Skip to content

A component animation library implemented in plain C

License

Notifications You must be signed in to change notification settings

stephendpmurphy/animate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

animate

A component animation library implemented in plain C. Animate allows a developer to apply a "vector" based animation to coordinate based components. This could be UI elements like addressable LEDs or Displays. Using a display as an example, the developer typically creates UI elements with their favorite library (I will be using u8g2 in these examples) and places the elements at a fixed location on the screen. (x=15, y=15 in this example)

void display_name(void) {
    u8g2_FirstPage(&u8g2);
    do
    {
        u8g2_SetFont(&u8g2, u8g2_font_7x13B_tf);
        u8g2_DrawStr(&u8g2, 15, 15, "stephendpmurphy");
    } while (u8g2_NextPage(&u8g2));
}

The animate library can be used to apply an offset to the X,Y coordinates that increments/decrements at a configurable velocity from point A to point B. As an example you can implement a transition where the text enters the screen from the left by giving the transition a start point the following parameters

  • X_start = -128
  • X_end = 0
  • velocity = 20

Once the transition is started it will begin the X coordinate at the specified start position and increment by 20 until the specified end position is reached. It is vitally important that the transition is "ticked" or updated at a fixed rate which matches the update rate of your display. A commented example is seen below where the text is brought in from the left of the screen.

#include <stdlib.h>
#include "u8g2.h"
#include "animation.h"

u8g2_t u8g2;
animation_inst_t myAnimation = {0};
    
int maint(void) {

    int16_t X_OFFS_myAnimation;
    int16_t X_OFFS_myOtherAnimation;

    // Set our config to have a negative X offset
    // Pushing the UI element off the screen to the left.
    // As it ticks to zero the offset will decrease which brings
    // the UI element onto the screen, entering from the left.
    myAnimation.config.start.x = -128;
    myAnimation.config.end.x = 0;
    myAnimation.config.velocity.x = 20;

    // Begin the animation
    animation_start(&animation);

    while(1) {

        // Update myAnimation. This must "tick"
        // at a fixed update rate which matches
        // the display update rate
        animation_update(&myAnimation);

        // Get the current value of the animation X coordinate
        // and store it as an offset to be applied to our 
        // UI element
        X_OFFS_myAnimation = animation_getCurrentX(&myAnimation);

        // Update the display
        u8g2_FirstPage(&u8g2);
        do
        {
            u8g2_SetFont(&u8g2, u8g2_font_7x13B_tf);
            // Draw our UI element, and apply our X_OFFS from the 
            // animation
            u8g2_DrawStr(&u8g2, X_OFFS_myAnimation + 15, 15, "stephendpmurphy");
        } while (u8g2_NextPage(&u8g2));

        // Delay for 30ms giving us roughly a 33hz display update rate
        delay_ms(30);
    }
}

These animations can be chained via a "callback" that is executed when an animation reaches it's specified X,Y end coordinates. The callback takes no parameters and returns void. An example of beginning an animation at the completion of another is seen below. It is mostly the same as the example above, however, once the first UI element finishes and reaches the end X,Y coordinates the callback will fire which begins the next animation.

#include <stdlib.h>
#include "u8g2.h"
#include "animation.h"

u8g2_t u8g2;
animation_inst_t myAnimation = {0};
animation_inst_t myOtherAnimation = {0};

void CB_animationComplete(void) {
    // Begin the animation
    animation_start(&myOtherAnimation);
}

int maint(void) {

    int16_t X_OFFS_myAnimation;
    int16_t X_OFFS_myOtherAnimation;

    // Set our config to have a negative X offset
    // Pushing the UI element off the screen to the left.
    // As it ticks to zero the offset will decrease which brings
    // the UI element onto the screen, entering from the left.
    myAnimation.config.start.x = -128;
    myAnimation.config.end.x = 0;
    myAnimation.config.velocity.x = 20;

    // Configure the other animation the same as above
    myOtherAnimation.config.start.x = -128;
    myOtherAnimation.config.end.x = 0;
    myOtherAnimation.config.velocity.x = 20;

    // Add our callback which will fire when the animation completes
    // thus starting the next animation
    myAnimation.cb = CB_animationComplete;

    // Begin the animation
    animation_start(&myAnimation);

    while(1) {
        // Update myAnimation. This must "tick"
        // at a fixed update rate which matches
        // the display update rate
        animation_update(&myAnimation);

        // Update myOtherAnimation. This does nothing until
        // the animation_start API is called. Until the animation
        // is started, the returned X,Y values will be the configured
        // start X,Y coordinates
        animation_update(&X_OFFS_myOtherAnimation);

        // Get the current value of the animation X coordinate
        // and store it as an offset to be applied to our
        // UI element
        X_OFFS_myAnimation = animation_getCurrentX(&myAnimation);
        // This will return the configured start X value until the animation
        // is started
        X_OFFS_myOtherAnimation = animation_getCurrentX(&X_OFFS_myOtherAnimation);

        // Update the display
        u8g2_FirstPage(&u8g2);
        do
        {
            u8g2_SetFont(&u8g2, u8g2_font_7x13B_tf);
            // Draw our UI element, and apply our X_OFFS_myAnimation from the
            // animation
            u8g2_DrawStr(&u8g2, X_OFFS_myAnimation + 15, 15, "stephendpmurphy");
            // Draw our second UI element, and apply our X_OFFS_myOtherAnimation from the
            // animation
            u8g2_DrawStr(&u8g2, X_OFFS_myAnimation + 15, 29, "animations!");
        } while (u8g2_NextPage(&u8g2));

        // Delay for 30ms giving us roughly a 33hz display update rate
        delay_ms(30);
    }
}

About

A component animation library implemented in plain C

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published