7、LVGL动画

LVGL动画

文章目录

  • LVGL动画
    • LVGL动画概述
    • 动画数据结构
    • 动画API
    • LVGL如何使用动画

LVGL动画概述

LVGL里面有好多对象都支持动画效果,比如进度条、滑块、按钮等,但是那些都是对象里面自带的API进行设定的,如果我们想让某个对象拥有动画效果,LVGL也是支持的,只是原子的教程里面没有.

先简单说一下动画的实现原理.

首先,动画由一个双向链表进行管理,该链表除去头尾指针外只记录了动画结构体的大小.
其次,动画的实现其实是LVGL的一个系统内置任务实现.
最后,动画的概念其实和软件定时器高度相似,但是添加了一些额外的属性,总体来说还是比较好理解的.

备注: 如果想加深理解,可以看一下lv_anim.c文件,内容很少,很容易理解.

动画数据结构

想要使用动画,还需要对动画的数据结构有一定了解.结构如下.

/** Describes an animation*/
typedef struct _lv_anim_t
{
    void * var;                  
    lv_anim_exec_xcb_t exec_cb;   
    lv_anim_path_cb_t path_cb;  
    lv_anim_ready_cb_t ready_cb;
    int32_t start;              
    int32_t end;                
    uint16_t time;              
    int16_t act_time;          
    uint16_t playback_pause;    
    uint16_t repeat_pause;      
#if LV_USE_USER_DATA
    lv_anim_user_data_t user_data;
#endif

    uint8_t playback : 1; 
    uint8_t repeat : 1;  
    /*Animation system use these - user shouldn't set*/
    uint8_t playback_now : 1; 
    uint32_t has_run : 1;    
} lv_anim_t;

下面只说一些对应用有直接影响的参数.

  • var

    设定的对象,给哪个对象设定动画效果

  • exec_cb

    控制对象属性的函数地址,一般使用lv_obj_set_x或者lv_obj_set_y,使用lv_obj_set_x的时候,动画左右移动,使用lv_obj_set_y的时候上下移动.
    除了坐标外,还可以设定对象的透明度,颜色等等.

  • path_cb

    路径算法,比较有意思的一个选项,有如下几个可以选择.

    • lv_anim_path_linear 动画效果均速移动
    • lv_anim_path_step 没有动画效果,直接跳转到结束位置
    • lv_anim_path_ease_in 开头很慢,速度逐渐加速
    • lv_anim_path_ease_out 开头很快,速度逐渐减小
    • lv_anim_path_ease_in_out 开始速度很慢,在动画中心处存在一个最大速度的时候开始逐渐减速.
    • lv_anim_path_overshoot 动画会超过设定值,效果类似于惯性
    • lv_anim_path_bounce 动画效果类似于弹性物体落地.

    如果有特殊的动画需求可以自行实现动画方法,之后将该函数注册到这个指针即可.

  • ready_cb

    动画效果结束后的回调函数,可以根据需求自行填写,lvgl内部其余组件一般是用这个回调做一些收尾工作,比如释放内存.

  • start

    动画开始的起点,根据exec_cb函数的不同代表不同属性的初始值.

  • end

    动画开始的终点,根据exec_cb函数的不同代表不同属性的结束值.

  • time

    设定的动画的执行时间,设定5S代表5S秒内从startend点的时间.

  • act_time

    动画已经执行的时间

  • playback_pause

    动画正放与回放之间的时间间隔

  • repeat_pause

    动画重复的时间间隔

  • playback

    是否执行动画回放

  • repeat

    是否重复播放动画

总结一下,想使用动画,先确定如下几点.

  1. 某个对象使用动画,使用var指向该对象.
  2. 动画方向,使用exec_cb确认.
  3. 动画范围,就是动画的起点到终点,使用startend进行确认.如果不选择,默认为0-100(方向根据exec_cb确认).
  4. 动画效果,使用path_cb进行选择,如果不选择,默认为lv_anim_path_linear
  5. 动画时长,使用time进行调整,如果不修改,默认为500.
  6. 可选择项,如果想让动画效果滞后一段时间播放,则可以设定act_time,需要注意的是,该延时时间仅会生效一次.

上面是一些最基本的属性,还有好多属性可提供选择,举一个简单的例子,让钟表以500ms的时间从Y轴的0掉落到Y轴的100,将该过程称为A,如果需要回放的话,则打开playback选项,钟表将会以500ms的时间从Y轴的100上升到Y轴0位置处,将该过程称之为B.以这个例子解释如下属性.

  1. 需要打开动画回放功能,打开playback即可.
  2. 动画AB之间的时间间隔以playback_pause设定.
  3. 动画重复播放,打开repeat即可.
  4. 动画重复播放的时间间隔,使用repeat_pause设定.
  5. 动画结束后触发ready_cb函数,有需求可以设置该指针去做.

备注:

  • playbackrepeat同时打开后,AB的时间间隔依旧是playback_pauseABAB的时间间隔才是repeat_pause.

  • 这个repeat更像是一个定时器的标志位,打开了就是周期定时器,关闭了就是一个单次定时器.ready_cbrepeat打开的时间不会执行.

  • act_timerepeat打开时仅会在第一次运行动画效果时执行一次.

动画API

上面介绍了一些重要的成员变量,下面简单说一些能用得到的API,还有相当一部分略过,略过的基本都是内联函数,都是对结构体内部成员变量进行赋值的操作.使用时直接赋值即刻.

  • lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)

    给出指定speed,给出动画的startend坐标,返回值是所用时间. speed单位是px/sec.
    比如a.time = lv_anim_speed_to_time(100,0,100);,结果是1000ms.

  • lv_anim_create(lv_anim_t * a)

    创建一个动画,使用的时候可以传入局部变量,因为在函数内部会自动申请一个内存块存放动画属性.

  • lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)

    删除一个动画

  • lv_anim_count_running()

    获取当前系统一共有多少个运行的动画

LVGL如何使用动画

一般场景中,都是触发条件后,执行一次动画,每次在执行动画时,调用如下函数即可.具体参数根据需求自行修改.

static void obj_add_anim()
{
    lv_anim_t a;
    memset(&a, 0, sizeof(lv_anim_t));

    a.var = bg_img;  //动画对象

    a.exec_cb = lv_obj_set_y; // y轴移动
    a.time =   lv_anim_speed_to_time(100,0,100); //1S的动画时间
    a.start = 10;  // 开始坐标
    a.end = 120;   // 结束坐标

    a.act_time = -500;  //第一次运行动画时,延时500ms开始

    a.path_cb = lv_anim_path_bounce; //模拟弹性物体下落动画
    a.ready_cb = ready_call_back;  // 自定义的打印函数

    a.playback = 0;     //不开启动画回放
    a.playback_pause = 2000;

    a.repeat = 1;       //开始重复动画
    a.repeat_pause = 200;//每次重复动画时间间隔200ms
    lv_anim_create(&a);  //必须调用的函数,否则无法使用
}

在LVGL内置的anim任务中,当动画执行完后,系统会自动释放掉动画管理结构体的内存.所以不用担心内存溢出的问题.

你可能感兴趣的:(LVGL)