背景
需要封装一个LVGL播放帧动画的组件,在下献丑了,封装了一个帧动画播放器。先看效果(没法录屏,只能手机录像):
代码如下
- 头文件
/*
* @Author:
* @Date: 2024-03-28 13:35:11
* @LastEditors:
* @LastEditTime: 2024-03-28 14:55:55
* @FilePath:/components/framePlayer.h
* @Description: 帧动画播放器
*/
#ifndef FRAME_PLAYER_H
#define FRAME_PLAYER_H
#include"lvgl.h"
#include"iostream"
#include "string"
class FramePlayer {
public:
FramePlayer(lv_obj_t *root);
// 设置前缀
void setPrefix(std::string prefix);
// 设置后缀
void setSuffix(std::string suffix);
// 设置起始文件名编号
void setStartIndex(int index);
// 设置结束图片文件名编号
void setEndIndex(int index);
// 设计师提供的图画有的经过了抽帧,文件名编号不连续,可以通过设置间隔和起始编号实现播放偶数帧,奇数帧等
void setIndexGap(int gap);
// 设置大小
void setSize(lv_coord_t w, lv_coord_t h);
// 设置位置
void setPos(lv_coord_t x, lv_coord_t y);
// 设置时间,即多久播放下一帧
void setPeriod(int period);
// 开始播放
void play();
// 定时器回调,固定刷新图片
static void onTimer(lv_timer_t* timer);
~FramePlayer();
lv_obj_t *root;
lv_obj_t *img;
std::string prefix;
std::string suffix;
int startIndex;
int currIndex;
int endIndex;
int indexGap;
int period;
lv_coord_t w;
lv_coord_t h;
lv_coord_t x;
lv_coord_t y;
lv_timer_t *timer;
};
#endif
- cpp文件
/*
* @Author:
* @Date: 2024-03-28 10:34:14
* @LastEditors:
* @LastEditTime: 2024-03-29 11:28:04
* @FilePath: /components/framePlayer.cpp
* @Description: 帧动画播放器
*/
#include "framePlayer.h"
FramePlayer::FramePlayer(lv_obj_t * root)
{
this->root = root;
}
void FramePlayer::setPrefix(std::string prefix){
this->prefix = prefix;
}
void FramePlayer::setSuffix(std::string suffix){
this->suffix = suffix;
}
void FramePlayer::setStartIndex(int index){
this->startIndex = index;
this->currIndex=index;
}
void FramePlayer::setEndIndex(int index){
this->endIndex = index;
}
void FramePlayer::setSize(lv_coord_t w, lv_coord_t h){
this->w = w;
this->h = h;
}
void FramePlayer::setPos(lv_coord_t x, lv_coord_t y){
this->x = x;
this->y = y;
}
void FramePlayer::setIndexGap(int gap){
this->indexGap = gap;
}
void FramePlayer::setPeriod(int period){
this->period = period;
}
void FramePlayer::play(){
this->img = lv_img_create(root);
lv_obj_set_size(img, w, h);
lv_obj_set_pos(img, x, y);
this->timer = lv_timer_create(onTimer, 100, this);
lv_obj_set_style_bg_opa(img, LV_OPA_TRANSP,0);
lv_timer_set_repeat_count(timer, -1);
lv_timer_set_period(timer, this->period);
lv_timer_enable(timer);
}
void FramePlayer::onTimer(lv_timer_t* timer){
FramePlayer * framePlayer = (FramePlayer*)timer->user_data;
std::string imgDir = HAIER_IMG_DIR;
if(framePlayer->currIndex <= framePlayer->endIndex){
std::string index = std::to_string(framePlayer->currIndex);
// index ,我的帧序列文件编号,需要补0,补充到5位,可以根据自己的需求修改
int len = index.length();
for(int i = 0; i < 5 - len; i++){
index = "0" + index;
}
std::string path = imgDir+framePlayer->prefix + index + framePlayer->suffix;
// printf("path:%s %d %d %d \n",path.c_str(),framePlayer->currIndex,framePlayer->indexGap);
lv_img_set_src(framePlayer->img, path.c_str());
lv_obj_invalidate(framePlayer->img);
framePlayer->currIndex+=framePlayer->indexGap;
}else{
framePlayer->currIndex = framePlayer->startIndex;
}
}
FramePlayer::~FramePlayer()
{
lv_timer_del(timer);
}
使用
下面给出具体的使用方法:
FramePlayer * framePlayer;
framePlayer = new FramePlayer(root);
framePlayer->setPrefix("demo/ai_ball_178/");
framePlayer->setSuffix(".png");
framePlayer->setStartIndex(0);
framePlayer->setEndIndex(102);
framePlayer->setIndexGap(2);
framePlayer->setSize(178, 178);
framePlayer->setPos(190, 95);
framePlayer->setPeriod(60);
framePlayer->play();