Animation (lv_anim)
Animations allow you to define the way something should move or change over time, and let LVGL do the heavy lifting of making it happen. What makes it so powerful is that the thing being changed ca...
Animations allow you to define the way something should move or change over time, and let LVGL do the heavy lifting of making it happen. What makes it so powerful is that the thing being changed can be virtually anything in your system. It is very convenient to apply this to LVGL Widgets in your user interface (UI), to change their appearance, size or location over time. But because it is --- at its core --- a generic change-over-time manager, complete with a variety of optional event callbacks, its application can be wider than just to UI components.
For each Animation you create, it accomplishes the above by providing a generic method of varying a signed integer from a start value to an end value over a specified time period. It allows you to specify what object it applies to (the "variable"), which is available in the callback functions that are called as the Animation is playing through.
This variation over time can be linear (default), it can be on a path (curve) that you specify, and there is even a variety of commonly-used non-linear effects that can be specified.
The main callback called during an Animation (when it is playing) is called an animator function, which has the following prototype:
void func(void *var , int32_t value);This prototype makes it easy to use most of the LVGL set functions directly or via a trivial wrapper. It includes:
- most of the widget properties
- functions that set local style properties directly on objects (needs a wrapper to set the selector)
- set properties on
lv_style_tobjects (e.g. shared styles) (lv_obj_report_style_changeneeds to be called to notify the widgets having the style) lv_style_set_<property_name>(&style, <value>)lv_obj_set_<property_name>(widget, <value>)
Using lv_style_set_<property_name>(&shared_style, <value>), an animation on a
single lv_style_t object shared
among several objects can simultaneously modify the appearance of all objects that
use it. See Styles for more details.
Examples of lv_obj_set_<property_name>(widget, <value>) are:
lv_obj_set_x(widget, value) or
lv_obj_set_width(widget, value).
This makes it very convenient to apply to the appearance (and other attributes) of UI components. You can also provide your own "set" functions, so the application of Animations is really limited only by your imagination.
The number of Animations that can be playing at the same time for a given object with a given animator callback is one (1). However, the number of Animations that can be playing at the same time is limited only by available RAM and CPU time for:
- a given object with different animator callbacks; and
- different objects.
Thus, you can have a Button's width being changed by one Animation while having its height being changed by another Animation.
Creating an Animation
To create an Animation, start by creating an Animation template in an
lv_anim_t variable. It has to be initialized and configured with
lv_anim_set_...() functions.
/* INITIALIZE AN ANIMATION
*-----------------------*/
static lv_anim_t anim_template;
static lv_anim_t * running_anim;
lv_anim_init(&anim_template);
/* MANDATORY SETTINGS
*------------------*/
/* Set the "animator" function */
lv_anim_set_exec_cb(&anim_template, (lv_anim_exec_xcb_t) lv_obj_set_x);
/* Set target of the Animation */
lv_anim_set_var(&anim_template, widget);
/* Length of the Animation [ms] */
lv_anim_set_duration(&anim_template, duration_in_ms);
/* Set start and end values. E.g. 0, 150 */
lv_anim_set_values(&anim_template, start, end);
/* OPTIONAL SETTINGS
*------------------*/
/* Time to wait before starting the Animation [ms] */
lv_anim_set_delay(&anim_template, delay);
/* Set path (curve). Default is linear */
lv_anim_set_path_cb(&anim_template, lv_anim_path_ease_in);
/* Set anim_template callback to indicate when the Animation is completed. */
lv_anim_set_completed_cb(&anim_template, completed_cb);
/* Set anim_template callback to indicate when the Animation is deleted (idle). */
lv_anim_set_deleted_cb(&anim_template, deleted_cb);
/* Set anim_template callback to indicate when the Animation is started (after delay). */
lv_anim_set_start_cb(&anim_template, start_cb);
/* When ready, play the Animation backward with this duration. Default is 0 (disabled) [ms] */
lv_anim_set_reverse_duration(&anim_template, time);
/* Delay before reverse play. Default is 0 (disabled) [ms] */
lv_anim_set_reverse_delay(&anim_template, delay);
/* Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINITE for infinite repetition */
lv_anim_set_repeat_count(&anim_template, cnt);
/* Delay before repeat. Default is 0 (disabled) [ms] */
lv_anim_set_repeat_delay(&anim_template, delay);
/* Apply the start value immediately (default true); false: apply start value after
* delay when the Animation actually starts. */
lv_anim_set_early_apply(&anim_template, true/false);
/* START THE ANIMATION
*------------------*/
running_anim = lv_anim_start(&anim_template); /* Start the Animation */Animation Path
You can control the Path (rate curve) of an Animation. The simplest case is linear, meaning the current value between start and end is changed at the same rate (i.e. with fixed steps) over the duration of the Animation. A Path is a function which calculates the next value to set based on the current state of the Animation. There are a number of built-in Paths that can be used:
lv_anim_path_linear: linear animation (default)lv_anim_path_step: change in one step at the endlv_anim_path_ease_in: slow at the beginninglv_anim_path_ease_out: slow at the endlv_anim_path_ease_in_out: slow at the beginning and endlv_anim_path_overshoot: overshoot the end valuelv_anim_path_bounce: bounce back a little from the end value (like hitting a wall)
Alternately, you can provide your own Path function.
lv_anim_init(&my_anim) sets the Path to lv_anim_path_linear
by default. If you want to use a different Path (including a custom Path function
you provide), set it using lv_anim_set_path_cb(&anim_template, path_cb).
If you provide your own custom Path function, its prototype is:
int32_t calculate_value(lv_anim_t * anim);Speed vs Time
Normally, you set the Animation duration directly using
lv_anim_set_duration(&anim_template, duration_in_ms). But in some cases
the rate is known but the duration is not known. Given an Animation's start
and end values, rate here means the number of units of change per second, i.e.
how quickly (units per second) the Animation's value needs to change between the
start and end value. For such cases there is a utility function
lv_anim_speed_to_time you can use to compute the Animation's duration, so
you can set it like this:
uint32_t change_per_sec = 20;
uint32_t duration_in_ms = lv_anim_speed_to_time(change_per_sec, 0, 100);
/* `duration_in_ms` will be 5000 */
lv_anim_set_duration(&anim_template, duration_in_ms);Animating in Both Directions
Sometimes an Animation needs to play forward, and then play backwards, effectively
reversing course, animating from the end value back to the start value again.
To do this, pass a non-zero value to this function to set the duration for the
reverse portion of the Animation:
lv_anim_set_reverse_duration(&anim_template, duration_in_ms).
Optionally, you can also introduce a delay between the forward and backward
directions using lv_anim_set_reverse_delay(&anim_template, delay_in_ms)
Starting an Animation
After you have set up your lv_anim_t object, it is important to realize
that what you have set up is a "template" for a live, running Animation that has
not been created yet. When you call lv_anim_start(&anim_template)
passing the template you have set up, it uses your template to dynamically allocate
an internal object that is a live, running Animation. This function returns a
pointer to that object.
static lv_anim_t anim_template;
static lv_anim_t * running_anim;
/* Set up template... */
lv_anim_init(&anim_template);
/* ...and other set-up functions above. */
/* Later... */
running_anim = lv_anim_start(&anim_template);template, so if you do not need it later, its contents do not need to be preserved after this call.
Once a live running Animation has been started, it runs until it has completed, or until it is deleted (see below), whichever comes first. An Animation has completed when:
- its "value" has reached the designated
endvalue; - if the Animation has a non-zero reverse duration value, then its value
has run from the
endvalue back to thestartvalue again; - if a non-zero repeat count has been set, it has repeated the Animation that number of times.
Once the live, running Animation reaches completion, it is automatically deleted from the list of running Animations. This does not impact your Animation template.
If lv_anim_set_repeat_count(&anim_template, cnt) has been called
passing LV_ANIM_REPEAT_INFINITE, the animation never reaches a state
of being "completed". In this case, it must be deleted to terminate the
Animation.
Deleting Animations
You should delete an Animation using lv_anim_delete(var, func) if one of
these two conditions exists:
- the object (variable) being animated is deleted (and it is not a Widget) or
- a running animation needs to be stopped before it is completed.
If the object (variable) being deleted is a type of Widget, the housekeeping code
involved in deleting it also deletes any running animations that are connected
with it. So lv_anim_delete(var, func) only needs to be called if the
object being deleted is not one of the Widgets.
If you kept a copy of the pointer returned by lv_anim_start as
running_anim, you can delete the running animation like this:
lv_anim_delete(running_anim->var, running_anim->exec_cb);In the event that the Animation completes after you have determined it needs to be
deleted, and before the call to lv_anim_delete is made, it does no harm
to call it a second time --- no damage will occur.
This function returns a Boolean value indicating whether any live, running Animations were deleted.
Pausing Animations
If you kept a copy of the pointer returned by lv_anim_start,
you can pause the running animation using lv_anim_pause(animation) and then resume it
using lv_anim_resume(animation).
lv_anim_pause_for(animation, milliseconds)
is also available if you wish for the animation to resume automatically after.
Timelines
You can create a series of related animations that are linked together using an Animation Timeline. A Timeline is a collection of multiple Animations which makes it easy to create complex composite Animations.

To create and use an Animation Timeline:
- Create an Animation template but do not call
lv_anim_starton it. - Create an Animation Timeline object by calling
lv_anim_timeline_create. - Add Animation templates to the Timeline by calling
lv_anim_timeline_add(timeline, start_time, &anim_template).start_timeis the start time of the Animation on the Timeline. Note thatstart_timewill override any value given tolv_anim_set_delay(&anim_template, delay). - Call
lv_anim_timeline_start(timeline)to start the Animation Timeline.
own copy of the contents of the Animation template, so if you do not need it later, its contents do not need to be preserved after this call.
It supports forward and reverse play of the entire Animation group, using
lv_anim_timeline_set_reverse(timeline, reverse). Note that if you want to
play in reverse from the end of the Timeline, you need to call
lv_anim_timeline_set_progress(timeline, LV_ANIM_TIMELINE_PROGRESS_MAX)
after adding all Animations and before telling it to start playing.
Call lv_anim_timeline_pause(timeline) to pause the Animation Timeline.
Note: this does not preserve its state. The only way to start it again is to call
lv_anim_timeline_start(timeline), which starts the Timeline from the
beginning or at the point set by
lv_anim_timeline_set_progress(timeline, progress).
Call lv_anim_timeline_set_progress(timeline, progress) function to set the
state of the Animation Timeline according to the progress value. progress is
a value between 0 and 65535 (LV_ANIM_TIMELINE_PROGRESS_MAX) to indicate the
proportion of the Timeline that has "played". Example: a progress value of
LV_ANIM_TIMELINE_PROGRESS_MAX / 2 would set the Timeline play to its
half-way point.
Call lv_anim_timeline_get_playtime(timeline) function to get the total
duration (in milliseconds) of the entire Animation Timeline.
Call lv_anim_timeline_get_reverse(timeline) function to get whether the
Animation Timeline is also played in reverse after its forward play completes.
Call lv_anim_timeline_delete(timeline) function to delete the Animation Timeline.
If you need to delete a Widget during Animation, be sure to delete the Animation Timeline before deleting the Widget. Otherwise, the program may crash or behave abnormally.
To prevent undefined behavior, the Animations subsystem does not allow more than one Animation to execute concurrently when they modify the same target object with the same animator callback.
If you have set up an Animation Timeline from 2 or more Animation Templates with these characteristics, be aware that when the Animation is started for any of them, the Animation subsystem looks for such cases and considers it a conflict when:
- more than one are running concurrently, or
- more than one have their "early apply" behavior turned on (which it is by default).
When this is detected, all such Animations are deleted except for the one most recently added.
To avoid this, if you want to use more than one Animation Template that updates the same object using the same animator callback:
- ensure that all but the first one to execute in the Timeline have their "early apply" default behavior turned off before starting the Timeline, and
- ensure that they do not execute concurrently.
Example:
/* These 4 Animation Templates execute in an Animation Timeline in the numbered
* sequence, and they modify the same object using the same callback. */
lv_anim_t anim_template_1;
lv_anim_t anim_template_2;
lv_anim_t anim_template_3;
lv_anim_t anim_template_4;
/* Initialization code for all 4 of them here. */
/* Ensure these steps are made before the Timeline is started. */
lv_anim_set_early_apply(&anim_template_2, false);
lv_anim_set_early_apply(&anim_template_3, false);
lv_anim_set_early_apply(&anim_template_4, false);
/* Start Timeline */
lv_anim_timeline_start(timeline);Examples
Start animation on an event
Playback animation
Cubic Bezier animation
Pause animation
Animation timeline
API
How is this guide?
Last updated on