feat(docs): proofread/edit batch 9 (#7324)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
@@ -4,27 +4,71 @@
|
||||
Animation (lv_anim)
|
||||
===================
|
||||
|
||||
You can automatically change the value of a variable between a start and
|
||||
an end value using animations. Animation will happen by periodically
|
||||
calling an "animator" function with the corresponding value parameter.
|
||||
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.
|
||||
|
||||
The *animator* functions have the following prototype:
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void func(void * var, lv_anim_var_t value);
|
||||
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 :ref:`local style properties <style_local>`) directly on objects (needs a wrapper to set set the *selector*)
|
||||
- set properties on :cpp:type:`lv_style_t` objects (e.g. :ref:`shared styles <style_initialize>`) (``lv_obj_report_style_change`` needs to be called to notify the widgets having the style)
|
||||
|
||||
- ``lv_style_set_<property_name>(&style, <value>)``
|
||||
- ``lv_obj_set_<property_name>(widget, <value>)``
|
||||
|
||||
Because of the former, an animation on a single :cpp:type:`lv_style_t` object shared
|
||||
among several objects can simultaneously modify the appearance of all objects that
|
||||
use it. See :ref:`styles` for more details.
|
||||
|
||||
Examples of the latter are: :cpp:expr:`lv_obj_set_x(widget, value)` or
|
||||
:cpp:expr:`lv_obj_set_width(widget, value)`.
|
||||
|
||||
This makes it very convenient to apply to the appearance (and other attributes) of UI
|
||||
componenets. But you can provide your own "set" functions, and 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.
|
||||
|
||||
|
||||
This prototype is compatible with the majority of the property *set*
|
||||
functions in LVGL. For example :cpp:expr:`lv_obj_set_x(widget, value)` or
|
||||
:cpp:expr:`lv_obj_set_width(widget, value)`
|
||||
|
||||
.. _animations_create:
|
||||
|
||||
Create an animation
|
||||
Create an Animation
|
||||
*******************
|
||||
|
||||
To create an animation an :cpp:type:`lv_anim_t` variable has to be initialized
|
||||
and configured with ``lv_anim_set_...()`` functions.
|
||||
To create an Animation, start by creating an Animation *template* in an
|
||||
:cpp:type:`lv_anim_t` variable. It has to be initialized and configured with
|
||||
``lv_anim_set_...()`` functions.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -32,79 +76,77 @@ and configured with ``lv_anim_set_...()`` functions.
|
||||
/* INITIALIZE AN ANIMATION
|
||||
*-----------------------*/
|
||||
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
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(&a, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
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(&a, widget);
|
||||
/* Set target of the Animation */
|
||||
lv_anim_set_var(&anim_template, widget);
|
||||
|
||||
/* Length of the animation [ms] */
|
||||
lv_anim_set_duration(&a, duration);
|
||||
/* 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(&a, start, end);
|
||||
lv_anim_set_values(&anim_template, start, end);
|
||||
|
||||
/* OPTIONAL SETTINGS
|
||||
*------------------*/
|
||||
|
||||
/* Time to wait before starting the animation [ms] */
|
||||
lv_anim_set_delay(&a, delay);
|
||||
/* 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(&a, lv_anim_path_ease_in);
|
||||
lv_anim_set_path_cb(&anim_template, lv_anim_path_ease_in);
|
||||
|
||||
/* Set a callback to indicate when the animation is completed. */
|
||||
lv_anim_set_completed_cb(&a, completed_cb);
|
||||
/* Set anim_template callback to indicate when the Animation is completed. */
|
||||
lv_anim_set_completed_cb(&anim_template, completed_cb);
|
||||
|
||||
/* Set a callback to indicate when the animation is deleted (idle). */
|
||||
lv_anim_set_deleted_cb(&a, deleted_cb);
|
||||
/* Set anim_template callback to indicate when the Animation is deleted (idle). */
|
||||
lv_anim_set_deleted_cb(&anim_template, deleted_cb);
|
||||
|
||||
/* Set a callback to indicate when the animation is started (after delay). */
|
||||
lv_anim_set_start_cb(&a, start_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_playback_duration(&a, time);
|
||||
/* When ready, play the Animation backward with this duration. Default is 0 (disabled) [ms] */
|
||||
lv_anim_set_playback_duration(&anim_template, time);
|
||||
|
||||
/* Delay before playback. Default is 0 (disabled) [ms] */
|
||||
lv_anim_set_playback_delay(&a, delay);
|
||||
lv_anim_set_playback_delay(&anim_template, delay);
|
||||
|
||||
/* Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINITE for infinite repetition */
|
||||
lv_anim_set_repeat_count(&a, cnt);
|
||||
lv_anim_set_repeat_count(&anim_template, cnt);
|
||||
|
||||
/* Delay before repeat. Default is 0 (disabled) [ms] */
|
||||
lv_anim_set_repeat_delay(&a, delay);
|
||||
lv_anim_set_repeat_delay(&anim_template, delay);
|
||||
|
||||
/* true (default): apply the start value immediately, false: apply start value after delay when the anim. really starts. */
|
||||
lv_anim_set_early_apply(&a, true/false);
|
||||
/* true (default): apply the start value immediately, false: apply start value after delay when the Anim. really starts. */
|
||||
lv_anim_set_early_apply(&anim_template, true/false);
|
||||
|
||||
/* START THE ANIMATION
|
||||
*------------------*/
|
||||
lv_anim_start(&a); /* Start the animation */
|
||||
running_anim = lv_anim_start(&anim_template); /* Start the Animation */
|
||||
|
||||
You can apply multiple different animations on the same variable at the
|
||||
same time. For example, animate the x and y coordinates with
|
||||
:cpp:func:`lv_obj_set_x` and :cpp:func:`lv_obj_set_y`. However, only one animation can
|
||||
exist with a given variable and function pair and :cpp:func:`lv_anim_start`
|
||||
will remove any existing animations for such a pair.
|
||||
|
||||
.. _animations_path:
|
||||
|
||||
Animation path
|
||||
.. _animation_path:
|
||||
|
||||
Animation Path
|
||||
**************
|
||||
|
||||
You can control the path of an animation. The most simple case is
|
||||
linear, meaning the current value between *start* and *end* is changed
|
||||
with fixed steps. A *path* is a function which calculates the next value
|
||||
to set based on the current state of the animation. Currently, there are
|
||||
the following built-in path functions:
|
||||
You can control the Path (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:
|
||||
|
||||
- :cpp:func:`lv_anim_path_linear`: linear animation
|
||||
- :cpp:func:`lv_anim_path_linear`: linear Animation (default)
|
||||
- :cpp:func:`lv_anim_path_step`: change in one step at the end
|
||||
- :cpp:func:`lv_anim_path_ease_in`: slow at the beginning
|
||||
- :cpp:func:`lv_anim_path_ease_out`: slow at the end
|
||||
@@ -113,70 +155,200 @@ the following built-in path functions:
|
||||
- :cpp:func:`lv_anim_path_bounce`: bounce back a little from the end value (like
|
||||
hitting a wall)
|
||||
|
||||
.. _animations_speed_vs_time:
|
||||
Alternately, you can provide your own Path function.
|
||||
|
||||
Speed vs time
|
||||
:cpp:expr:`lv_anim_init(&my_anim)` sets the Path to :cpp:func:`lv_anim_path_linear`
|
||||
by default. If you want to use a different Path (including a custom Path function
|
||||
you provide), you set it using :cpp:expr:`lv_anim_set_path_cb(&anim_template, path_cb)`.
|
||||
|
||||
If you provide your own custom Path function, its prototype is:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int32_t calculate_value(lv_anim_t * anim);
|
||||
|
||||
|
||||
|
||||
.. _animation_speed_vs_time:
|
||||
|
||||
Speed vs Time
|
||||
*************
|
||||
|
||||
By default, you set the animation time directly. But in some cases,
|
||||
setting the animation speed is more practical.
|
||||
Normally, you set the Animation duration directly using
|
||||
:cpp:expr:`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
|
||||
:cpp:func:`lv_anim_speed_to_time` you can use to compute the Animation's duration, so
|
||||
you can set it like this:
|
||||
|
||||
The :cpp:expr:`lv_anim_speed_to_time(speed, start, end)` function calculates the
|
||||
required time in milliseconds to reach the end value from a start value
|
||||
with the given speed. The speed is interpreted in *unit/sec* dimension.
|
||||
For example, :cpp:expr:`lv_anim_speed_to_time(20, 0, 100)` will yield 5000
|
||||
milliseconds. For example, in the case of :cpp:func:`lv_obj_set_x` *unit* is
|
||||
pixels so *20* means *20 px/sec* speed.
|
||||
.. code-block:: c
|
||||
|
||||
.. _animations_delete:
|
||||
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);
|
||||
|
||||
|
||||
|
||||
.. _animation_direction
|
||||
|
||||
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:
|
||||
:cpp:expr:`lv_anim_set_playback_duration(&anim_template, duration_in_ms)`.
|
||||
|
||||
Optionally, you can also introduce a delay between the forward and backward
|
||||
directions using :cpp:expr:`lv_anim_set_playback_delay(&anim_template, delay_in_ms)`
|
||||
|
||||
|
||||
|
||||
.. _animation_start:
|
||||
|
||||
Starting an Amination
|
||||
*********************
|
||||
|
||||
After you have set up your :cpp:type:`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 :cpp:expr:`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.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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);
|
||||
|
||||
.. note::
|
||||
|
||||
:cpp:expr:`lv_anim_start(&anim_template)` makes its own copy of the Animation
|
||||
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 desginated ``end`` value;
|
||||
- if the Animation has a non-zero *reverse* duration value, then its value
|
||||
has run from the ``end`` value back to the ``start`` value 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.
|
||||
|
||||
.. note::
|
||||
|
||||
If :cpp:expr:`lv_anim_set_repeat_count(&anim_template, cnt)` has been called
|
||||
passing :c:macro:`LV_ANIM_REPEAT_INFINITE`, the animation never reaches a state
|
||||
of being "completed". In this case, it must be deleted to terminate the
|
||||
Animation.
|
||||
|
||||
|
||||
|
||||
.. _animation_delete:
|
||||
|
||||
Deleting Animations
|
||||
*******************
|
||||
|
||||
You should delete an Animation using :cpp:expr:`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.
|
||||
|
||||
.. note::
|
||||
|
||||
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 :cpp:expr:`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 :cpp:func:`lv_anim_start` as
|
||||
``running_anim``, you can delete the running animation like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 :cpp:func:`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.
|
||||
|
||||
Delete animations
|
||||
*****************
|
||||
|
||||
You can delete an animation with :cpp:expr:`lv_anim_delete(var, func)` if you
|
||||
provide the animated variable and its animator function.
|
||||
|
||||
.. _animations_timeline:
|
||||
|
||||
Timeline
|
||||
********
|
||||
|
||||
A timeline is a collection of multiple animations which makes it easy to
|
||||
create complex composite animations.
|
||||
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:
|
||||
|
||||
Firstly, create an animation element but don't call :cpp:func:`lv_anim_start`.
|
||||
- Create an Animation template but do not call :cpp:func:`lv_anim_start` on it.
|
||||
|
||||
Secondly, create an animation timeline object by calling
|
||||
:cpp:func:`lv_anim_timeline_create`.
|
||||
- Create an Animation Timeline object by calling :cpp:func:`lv_anim_timeline_create`.
|
||||
|
||||
Thirdly, add animation elements to the animation timeline by calling
|
||||
:cpp:expr:`lv_anim_timeline_add(at, start_time, &a)`. ``start_time`` is the
|
||||
start time of the animation on the timeline. Note that ``start_time``
|
||||
will override the value of ``delay``.
|
||||
- Add Animation templates to the Timeline by calling
|
||||
:cpp:expr:`lv_anim_timeline_add(timeline, start_time, &anim_template)`.
|
||||
``start_time`` is the start time of the Animation on the Timeline. Note that
|
||||
``start_time`` will override any value given to
|
||||
:cpp:expr:`lv_anim_set_delay(&anim_template, delay)`.
|
||||
|
||||
Finally, call :cpp:expr:`lv_anim_timeline_start(at)` to start the animation
|
||||
timeline.
|
||||
- Call :cpp:expr:`lv_anim_timeline_start(timeline)` to start the Animation Timeline.
|
||||
|
||||
It supports forward and backward playback of the entire animation group,
|
||||
using :cpp:expr:`lv_anim_timeline_set_reverse(at, reverse)`.
|
||||
Note that if you want to play in reverse from the end of the timeline,
|
||||
you need to call :cpp:expr:`lv_anim_timeline_set_progress(at, LV_ANIM_TIMELINE_PROGRESS_MAX)`
|
||||
after adding all animations and before starting to play.
|
||||
.. note::
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_stop(at)` to stop the animation timeline.
|
||||
:cpp:expr:`lv_anim_timeline_add(timeline, start_time, &anim_template)` makes its
|
||||
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.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_set_progress(at, progress)` function to set the
|
||||
state of the Widget corresponding to the progress of the timeline.
|
||||
It supports forward and backward playback of the entire Animation group, using
|
||||
:cpp:expr:`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
|
||||
:cpp:expr:`lv_anim_timeline_set_progress(timeline, LV_ANIM_TIMELINE_PROGRESS_MAX)`
|
||||
after adding all Animations and before telling it to start playing.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_get_playtime(at)` function to get the total
|
||||
duration of the entire animation timeline.
|
||||
Call :cpp:expr:`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
|
||||
:cpp:expr:`lv_anim_timeline_start(timeline)`, which starts the Timeline from the
|
||||
beginning or at the point set by
|
||||
:cpp:expr:`lv_anim_timeline_set_progress(timeline, progress)`.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_get_reverse(at)` function to get whether to
|
||||
reverse the animation timeline.
|
||||
Call :cpp:expr:`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 ``32767`` (:c:macro:`LV_ANIM_TIMELINE_PROGRESS_MAX`) to indicate the
|
||||
proportion of the Timeline that has "played". Example: a ``progress`` value of
|
||||
:cpp:expr:`LV_ANIM_TIMELINE_PROGRESS_MAX / 2` would set the Timeline playback to its
|
||||
half-way point.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_delete(at)` function to delete the animation timeline.
|
||||
**Note**: If you need to delete a Widget during animation, be sure to delete the
|
||||
anim timeline before deleting the Widget. Otherwise, the program may crash or behave abnormally.
|
||||
Call :cpp:expr:`lv_anim_timeline_get_playtime(timeline)` function to get the total
|
||||
duration (in milliseconds) of the entire Animation Timeline.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_get_reverse(timeline)` function to get whether the
|
||||
Animation Timeline is also played in reverse after its forward play completes.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_delete(timeline)` function to delete the Animation Timeline.
|
||||
**Note**: 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.
|
||||
|
||||
.. image:: /misc/anim-timeline.png
|
||||
|
||||
|
||||
Reference in New Issue
Block a user