【LVGL】ANIM(动画)学习

2023-11-09

animate:通用动画

过渡动画与通用动画的区别:

  • 过渡动画只有在状态发生改变时发生,通用动画可以在任意时刻进行
  • 过渡动画支是样式(style)的一部分,通用动画和样式是相互独立的

实际上,过渡的底层也使用的是动画。

创建动画

为了创建动画,需要像样式一样声明一个动画类型并初始化:

lv_anim_t anim;
lv_anim_init(&anim);

由于动画是立即执行的,因此可以使用自动变量存储。然后,需要明确该动画将作用于哪一个控件:

/*
	参数1:通用动画初始化的结构体
	参数2:用作动画控件的结构体指针
*/
lv_anim_set_var(&anim, obj);

接下来,可以设置动画的各种轨迹,包括:

  • 动画需要改变什么的属性
  • 这些属性改变的范围
  • 动画效果
  • 延时
  • 持续时间
  • 动画执行次数
  • 完成动画后处理

1. 动画需要改变什么的属性

	static void set_cont_main_value(void* cont, int32_t v)
	{
	    lv_obj_set_height(cont, v);
	}
	lv_anim_set_exec_cb(&b, set_cont_main_value);
    lv_anim_set_values(&b, 0, 60);
  • lv_anim_set_exec_cb :参数1:动画结构体指针,参数2:回调函数
    回调函数说明:
    set_cont_main_value回调函数有两个形参,参数1:是用作动画控件的结构体指针,参数2:是lv_anim_set_values函数中参数2和参数3的范围值。

  • 可以在回调函数种设置控件的尺寸、样式、位置等操作,实现各种动画效果

2. 这些属性改变的范围

 lv_anim_set_values(&b, 0, 60);
  • 参数1:通用动画的结构体指针
  • 参数2:开始范围值
  • 参数3:结束范围值
  • 参数2和参数3的开始和结束范围值最终会在lv_anim_set_exec_cb函数参数的set_cont_main_value回调函数的参数2:int32_t v 依次写入v变量

3. 动画效果

/*
	函数说明:加载函数动画路径(也就是动画执行效果)
	参数1:通用动画的结构体指针
	参数2:动画路径执行效果,具体说明看3.1
*/
    lv_anim_set_path_cb(&b, lv_anim_path_ease_out);
3. 1动画效果
/**
 *将初始值与终止值之间按照频次平均分割,每次赋值均匀增加,斜率k=1
 */
lv_anim_value_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *在开始阶段每次赋值逐渐增加,直到到达除开始阶段外的平均速度,开始阶段斜率k=0->1,其他阶段k=1
 */
lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *在结束阶段每次赋值逐渐减小,直到减为0速,结束阶段斜率k=1->0,其他阶段k=1
 */
lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *开始阶段逐渐加速,结束阶段逐渐减速,中间阶段匀速。可理解为汽车从静止加速到刹车减速
 */
lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *在结束阶段会小幅超越终止值,类似于惯性缓冲
 */
lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *整个阶段为减速阶段,正向减小为0时进行反向小部分增加,反复三次。可理解为小球落地反弹运动
 */
lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t * a);
 
/**
 *规定在整个阶段共分为几段,每次都取段端点值赋值
 */
lv_anim_value_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t * a);

4.延时

/*
	函数说明:延迟多久执行动画
	参数1:通用动画的结构体指针
	参数2:延迟多久执行动画
*/
lv_anim_set_delay(&b, 1000);

5.持续时间

/*
	函数说明:动画持续多长时间
	参数1:通用动画的结构体指针
	参数2:动画持续时间
*/
lv_anim_set_time(&b, 1000);

6.动画执行次数

/*
	函数说明:动画执行次数
	参数1:通用动画的结构体指针
	参数2:LV_ANIM_REPEAT_INFINITE :无限制重复,0:不重复
*/
    lv_anim_set_repeat_count(&b, 0);

7.完成动画后处理

static void anim_ready_cb(lv_anim_t *var)
{
    lv_obj_t* label = lv_label_create(cont);
    lv_obj_remove_style_all(label);
    lv_obj_align(label, LV_ALIGN_CENTER, 0, -24);

    lv_obj_set_style_text_font(label, &myFontOrbitron_18, LV_PART_MAIN);
    lv_obj_add_style(label, &style_label, LV_PART_MAIN);

    lv_label_set_text(label, "Start Up");
    //lv_obj_fade_in(label, 1000, 100);

    lv_anim_t label_anim;
    lv_anim_init(&label_anim);
    lv_anim_set_var(&label_anim, label);
    lv_anim_set_values(&label_anim, lv_obj_get_y(label), -24);
    lv_anim_set_time(&label_anim, 500);
    lv_anim_set_exec_cb(&label_anim, anim_x_cb);
    //lv_anim_set_path_cb(&label_anim, lv_anim_path_ease_in_out);
    lv_anim_set_repeat_count(&label_anim, 0);
    lv_anim_set_ready_cb(&label_anim, label_ready_cb);
    lv_anim_start(&label_anim);
}
/*
	函数说明:动画准备好回调处理
	参
	数1:通用动画的结构体指针
	参数2:回调函数,动画在执行完成后做的回调处理
*/
lv_anim_set_ready_cb(&b, anim_ready_cb);

注意事项

  1. 如果需要渲染控件(配置样式给控件),要在控件渲染完成后执行动画,否则动画执行的是控件的默认值

示例:

#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/win32drv/win32drv.h"

#include "test.h"

static lv_style_t style_label;
static lv_obj_t* cont;
static lv_obj_t* cont_main;


LV_FONT_DECLARE(myFontOrbitron_18);

static void anim_x_cb(void* var, int32_t v)
{
    lv_obj_set_y(var, v);
}

static void label_ready_cb(lv_anim_t* var)
{
    lv_obj_fade_out(cont, 500, 100);
    //lv_obj_fade_in(cont_main, 500, 100);
}

static void anim_ready_cb(lv_anim_t *var)
{
    lv_obj_t* label = lv_label_create(cont);
    lv_obj_remove_style_all(label);
    lv_obj_align(label, LV_ALIGN_CENTER, 0, -24);

    lv_obj_set_style_text_font(label, &myFontOrbitron_18, LV_PART_MAIN);
    lv_obj_add_style(label, &style_label, LV_PART_MAIN);

    lv_label_set_text(label, "Start Up");
    //lv_obj_fade_in(label, 1000, 100);

    lv_anim_t label_anim;
    lv_anim_init(&label_anim);
    lv_anim_set_var(&label_anim, label);
    lv_anim_set_values(&label_anim, lv_obj_get_y(label), -24);
    lv_anim_set_time(&label_anim, 500);
    lv_anim_set_exec_cb(&label_anim, anim_x_cb);
    //lv_anim_set_path_cb(&label_anim, lv_anim_path_ease_in_out);
    lv_anim_set_repeat_count(&label_anim, 0);
    lv_anim_set_ready_cb(&label_anim, label_ready_cb);
    lv_anim_start(&label_anim);
}

static void set_value(void* bar, int32_t v)
{
    lv_bar_set_start_value(bar, 50 - (v - 50), LV_ANIM_OFF);
    lv_bar_set_value(bar, v, LV_ANIM_OFF);
    if (v == 100)
    {
        printf("v==100");
    }

}


static void set_cont_main_value(void* cont, int32_t v)
{

    lv_obj_set_height(cont, v);

}


void bar_demo(void)
{
    //进度条只有两个样式选择,一个是主要样式(不变化背景色),一个是指示器(变化的前景色)
    //http://t.csdn.cn/D1kgJ
    static lv_style_t style_main;           // 
    static lv_style_t style_indicator;      //


    cont = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(cont, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_color(cont, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_size(cont, 240, 240);
    lv_obj_center(cont);

    lv_style_init(&style_main);
    lv_style_set_border_width(&style_main, 2);
    lv_style_set_border_color(&style_main, lv_palette_main(LV_PALETTE_BLUE));
    lv_style_set_border_opa(&style_main, LV_OPA_TRANSP);
    //lv_style_set_bg_color(&style_main, lv_palette_main(LV_PALETTE_RED));
    //lv_style_set_bg_opa(&style_main, LV_OPA_COVER);
    lv_style_set_pad_all(&style_main, 6); /*To make the indicator smaller*/
    lv_style_set_radius(&style_main, 6);

    lv_style_init(&style_indicator);
    lv_style_set_bg_opa(&style_indicator, LV_OPA_COVER);
    lv_style_set_bg_color(&style_indicator, lv_palette_main(LV_PALETTE_ORANGE));
    lv_style_set_radius(&style_indicator, 3);

    lv_obj_t* bar = lv_bar_create(cont);
    //样式到这先添加,否则可能出现别的问题
    lv_obj_remove_style_all(bar);
    lv_obj_add_style(bar, &style_main,      LV_PART_MAIN);
    lv_obj_add_style(bar, &style_indicator, LV_PART_INDICATOR);

    lv_obj_set_size(bar, 160, 16);
    lv_obj_center(bar);
    lv_bar_set_range(bar, 0, 100);
    lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);
    lv_bar_set_value(bar, 50, LV_ANIM_OFF);
    lv_bar_set_start_value(bar, 50, LV_ANIM_OFF);

    lv_style_init(&style_label);
    lv_style_set_text_font(&style_label, &lv_font_montserrat_16);
    lv_style_set_text_color(&style_label, lv_color_hex(0xff931e));

    static lv_style_transition_dsc_t trans_main;
    static lv_style_t                style_cont_main;
    static const lv_style_prop_t trans_props[] = {LV_STYLE_WIDTH, LV_STYLE_HEIGHT, LV_STYLE_BG_COLOR, 0,};

    cont_main = lv_obj_create(lv_scr_act());
    lv_obj_set_size(cont_main, 240, 60);

    lv_obj_set_style_bg_color(cont_main, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_color(cont_main, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_radius(cont_main, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_align(cont_main, LV_ALIGN_TOP_MID);


    lv_style_init(&style_cont_main);
    lv_style_set_bg_color(&style_cont_main, lv_palette_main(LV_PALETTE_RED));
    lv_style_set_width(&style_cont_main, 240);
    lv_style_set_height(&style_cont_main, 120);
    lv_style_set_radius(&style_cont_main, 50);

    lv_style_transition_dsc_init(&trans_main, trans_props, lv_anim_path_ease_in_out, 100, 0, NULL);
    lv_style_set_transition(&style_cont_main, &trans_main);
    lv_obj_add_style(cont_main, &style_cont_main, LV_STATE_PRESSED);



    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, bar);
    lv_anim_set_values(&a, 50, 100);
    lv_anim_set_exec_cb(&a, set_value);
    lv_anim_set_time(&a, 500);
    //lv_anim_set_playback_time(&a, 2000);
    lv_anim_set_repeat_count(&a, 0);
    lv_anim_set_ready_cb(&a, anim_ready_cb);
    //lv_anim_start(&a);

    lv_anim_t b;
    lv_anim_init(&b);
    lv_anim_set_var(&b, cont_main);
    lv_anim_set_values(&b, 0, 60);
    lv_anim_set_exec_cb(&b, set_cont_main_value);
 //   lv_anim_set_delay(&b, 1000);
    lv_anim_set_time(&b, 1000);
    //lv_anim_set_playback_time(&a, 2000);
    lv_anim_set_path_cb(&b, lv_anim_path_ease_out);
    lv_anim_set_repeat_count(&b, 0);
    lv_anim_set_ready_cb(&b, anim_ready_cb);
    //lv_anim_start(&b);


    lv_anim_timeline_t* anim_timeline = lv_anim_timeline_create();
    lv_anim_timeline_add(anim_timeline, 0, &a);
    lv_anim_timeline_add(anim_timeline, 1000, &b);
    lv_anim_timeline_start(anim_timeline);
}

```![请添加图片描述](https://img-blog.csdnimg.cn/e0af6bf1dcb5402e90612f251f778d8f.gif)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【LVGL】ANIM(动画)学习 的相关文章

  • KVM下虚拟机网卡桥接配置

    基本概念 KVM基本概念 KVM 全称是 Kernel based Virtual Machine 是 Linux 下 x86 硬件平台上的全功能虚拟化解决方案 包含一个可加载的内核模块 kvm ko 提供和虚拟化核心架构和处理器规范模块

随机推荐

  • 在安卓手机搭建kali环境,手机变成便携式渗透神器

    kali是著名的黑客专用系统 一般都是直接装在物理机或者虚拟机上 我们可以尝试把kali安装在手机上 把手机打造成一个便携式渗透神器 我们需要下载以下3款软件 1 Termux 终端模拟器 2 AnLinux 里边有各种安装liunx的命令
  • 离散数学期末复习—学习笔记

    主要是看ppt和做课后练习 数理逻辑 1 命题逻辑的基本概念 1 1 命题与连接词 1 2 命题公式及其赋值 1 3 习题 2 命题逻辑等值演算 2 1等值式 基本等值式 16组 24个公式 2 2 析取范式和合取范式 主要是主析取范式和主
  • kettle入门教程

    目录 1 kettle叙述 1 1什么是kettle 1 2kettle工程存储方式 1 3kettle两种设计 1 4kettle的组成 1 5kettle的下载安装 2 kettle教程 2 1转换 2 1 1普通转换 2 1 2执行s
  • html中div hover的用法,CSS: hover选择器的使用详解

    有些时候需要用到mouseover和mouseout这两个鼠标事件 但是写js又比较麻烦 还要添加监听事件 所以能用css解决的东西尽量yongcss解决 这样可以提高性能 下面说一下我对 hover 的了解 之前在学计算机应用的时候 老师
  • Windows端pytorch镜像快速安装【清华源】

    目录 0 说在前面 1 安装Anacoda 1 1 说在前面 1 2 下载 1 3 安装 1 4 记住3条命令 2 安装CUDA 2 1 更新NVIDIA驱动 2 2 下载CUDA 3 安装cudnn 3 1 下载安装 4 安装pytorc
  • MySQL必知必会 学习笔记 第七章 数据过滤

    可用AND操作符给WHERE子句附加条件 SELECT columnName FROM tableName WHERE columnName1 1 AND columnName2 2 OR操作符指示MySQL匹配符合操作符任一端条件的行 S
  • 监听器

    监听器在JavaWeb开发中用得比较多 下面说一下监听器 Listener 在开发中的常见应用 一 统计当前在线人数 在JavaWeb应用开发中 有时候我们需要统计当前在线的用户数 此时就可以使用监听器技术来实现这个功能了 1 packag
  • vue3 在原型上挂载方法

    在vue3 中没有 this 不在是实例化查出来的vue对象 那怎么往原型挂在公用的方法呢 const app createApp App const test gt console log 我是测试函数触发的 return 测试成功 ap
  • nginx第三方模块---nginx-sticky-module的平滑升级

    nginx第三方模块 nginx sticky module的平滑升级 第一步 下载 下载地址 链接 https bitbucket org nginx goodies nginx sticky module ng downloads ta
  • 5个方面详解:AI产品运营必知的软硬件技术

    比算法更难得是算法的思想 比编程工具更难的是编程的思维 比做产品更难的是产品的梦想 本文主要从5个方面 详细阐述AI产品运营必知的软硬件技术 一 AI产品运营对基础关系的安排 1 智能软硬件与软件和硬件 在AI产品里没有纯粹单独的软件和硬件
  • 【SpringBoot应用篇】SpringBoot集成MinIO对象存储服务

    SpringBoot应用篇 SpringBoot集成MinIO对象存储服务 对象存储服务MinIO MinIO简介 MinIO特点 开箱使用 docker安装启动 管理控制台 快速入门 Java 上传文件到minio 配置访问权限 封装Mi
  • 计算机基础知识深入研究系列:定点数与浮点数

    插眼 总结 暂无 自己还没深入研究 留链接供以后参考 深入浅出浮点数 https blog csdn net cppptr article details 573372 硬件中的定点数与浮点数运算与相互转换 https blog csdn
  • Qt 官方资源下载地址

    1 所有Qt版本下载地址 http download qt io archive qt 2 所有Qt Creator下载地址 http download qt io archive qtcreator 3 所有Qt VS开发插件下载地址 h
  • CubeMX——F1和G0系列外部中断回调函数差异

    以前写代码 一些固定的代码总喜欢复制粘贴 然后在G0系列使用外部中断的时候 发现死活触发不了 一路检查了CubeMX的配置以及硬件连接 均发现没问题 然后发现G0系列的外部中断回调函数和F1系列的不一样 以下列举的是配置下降沿触发模式 主要
  • 怎么给input插入一个图片

    html部分
  • 强化学习笔记:连续控制 & 确定策略梯度DPG

    1 离散控制与连续控制 之前的无论是DQN Q learning A2C REINFORCEMENT SARSA什么的 都是针对离散动作空间 不能直接解决连续控制问题 考虑这样一个问题 我们需要控制一只机械手臂 完成某些任务 获取奖励 机械
  • C++生成随机字符串的程序

    include
  • set-cookie失效之坑

    最近做的一个微信公众号项目 打开网页登录的时候就会出现每次请求sessionid不一致的问题 先贴图 session是后台生成的 由于验证码信息是放了在session里面 每次的session不一致 导致没有办法从session里面拿到响应
  • springmvc整合freemarker以及前端的一些坑

    一 SpringMVC整合freemarker配置 1 引入相关jar包 html view plain copy
  • 【LVGL】ANIM(动画)学习

    animate 通用动画 过渡动画与通用动画的区别 过渡动画只有在状态发生改变时发生 通用动画可以在任意时刻进行 过渡动画支是样式 style 的一部分 通用动画和样式是相互独立的 实际上 过渡的底层也使用的是动画 创建动画 为了创建动画