LVGL高效顯示進度條

田帅康学习笔记發表於2024-12-10

此篇文章在2022年5月17日被記錄

在微控制器中顯示動畫是一件很浪費資源的事情,在那個小小的flash中存入一大坨資料是相當費力地,因此就進度條動畫而言,有一種相當簡單的實現方式,就是重複移動整個圖片然後遮住某個部分,例如這個樣子:

img

動圖中可以看到在被遮住後,達到了動畫的效果

實現該功能並且封裝成函式:

/*
*函式說明:這個函式用來在螢幕上顯示進度條動畫,旨在節省資源
*引數傳入:1、父物件;2、圖片內容3、原始圖片被分成幾部分了(備註詳談)4、佈局
*返回值:無
*備註:這個動畫的實現方式是對一張圖片進行迴圈動畫,並對其能看到運動的地方進行遮罩
*此函式對圖片的格式具有要求,詳情參考示例圖片,圖片被分成幾個part,運動路徑為一個part。
*/
void lv_progress_bar_animation(lv_obj_t * obj,const void *src_img,int part,lv_align_t align)
{
    float mask_w=(float)(part-1)/(float)part;//某些係數的計算
    float anim=(float)(((float)1/(float)part));

    lv_obj_t *parent=obj;//父佈局繼承
    lv_obj_t * cont = lv_cont_create(parent, NULL);//新建一個容器
    lv_img_header_t header; //新建一個圖片頭部物件
    lv_img_decoder_get_info(src_img, &header);
    lv_obj_set_size(cont, header.w*mask_w,header.h);//設定容器的寬度為圖片的寬度*係數,容器的高度為圖片的高度
    lv_obj_align(cont, NULL, align, 0, 0);//設定容器位於父佈局的位置

    lv_obj_set_style_local_border_width(cont,LV_CONT_PART_MAIN,LV_STATE_DEFAULT,0);//隱藏容器的邊框
    lv_obj_t * img1 = lv_img_create(cont, NULL);//建立一個圖片物件
    lv_img_set_src(img1, src_img);//設定圖片的內容


    lv_anim_t a;   //新建動畫
    lv_anim_init(&a);//初始化動畫
    lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x);//設定動畫回撥函式
    lv_anim_set_var(&a, img1);//給動畫繫結圖片物件
    lv_anim_set_time(&a, 1000);//設定動畫速度
    lv_anim_set_values(&a, -header.w*anim, 0);//設定動畫位置從哪裡到哪裡
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);//設定動畫永不停息
    lv_anim_start(&a);//動畫開始
}

在函式中呼叫:

LV_IMG_DECLARE(slider);
lv_progress_bar_animation(lv_scr_act(),&slider,4,LV_ALIGN_CENTER);

LV_IMG_DECLARE(bar);
lv_progress_bar_animation(lv_scr_act(),&bar,7,LV_ALIGN_IN_BOTTOM_MID);

實現效果如下:

img

重點講一下這裡的part引數:

img

part就是有幾個重複的部分,並且動畫播放時,運動的路徑為-一個part的畫素到0.然後將末端遮住就可以了。

相關文章