multanim控件

一、使用场景

  场景切换过程中,同一种动画可能反复用到,比如APP切换、TLV切换、表盘切换等。为提到代码重复利用率,方便使用, 本控件将常用的动画进行了封装,应用程序只需调用统一的接口,即可实现相应的动画。封装的动画主要有缩放动画、3D翻转动画、轴向压缩动画,mask渐隐动画等

二、功能介绍

1. 动画类型

enum
{
    LV_MULTANIM_NONE,		//无效动画
    LV_MULTANIM_ZOOM,		//缩放动画
    LV_MULTANIM_3D,			//3D翻转动画
    LV_MULTANIM_SWITCH,		//反向翻转并带一定缩放
    LV_MULTANIM_TURN,		//半页翻转动画
    LV_MULTANIM_SCALE,		//轴向压缩动画
    LV_MULTANIM_FADE,		//mask渐隐动画
    LV_MULTANIM_OPEN,		//中间向两侧打开的mask动画
    LV_MULTANIM_MAX,		//无效
};
typedef uint16_t lv_multanim_type;
//目前已封装的动画类型包含以上几种,
//通过lv_multanim_set_type指定相应动画类型
lv_multanim_type lv_multanim_set_type(lv_obj_t *multanim, lv_multanim_type type);

2. 设置图片

//设置主图,动画的进度值按主图的位置计算偏移
void lv_multanim_set_major_img(lv_obj_t *multanim, lv_obj_t *major_img);
//设置次图,有的页面没有次图可以不设置
void lv_multanim_set_minor_img(lv_obj_t *multanim, lv_obj_t *minor_img);

3. 播放动画

//动画播放主要是设置以个连续的进度值,可以起一个动画,在回调中设置进度,以达到连续播放的动画
void lv_multanim_set_process(lv_obj_t *multanim, int32_t process);

三、案例详解

1.使用流程

  动画使用步骤基本流程:

//1.创建multanim实例
lv_obj_t *multanim = lv_multanim_create(parent);
//2.设置动画类型
lv_multanim_set_type(multanim, anim_type);
//3.设置主、次图片
lv_multanim_set_major_img(multanim, major_img);
lv_multanim_set_minor_img(multanim, minor_img);
//4.设置进度值
lv_multanim_set_process(multanim, proc);

2.切换动画

  3D切换动画的实现使用了该控件,流程如下

static void lv_turn3d_anim_progress(lv_baseanim_t *baseanim, lv_obj_t *anim_obj, int32_t progress)
{
    if (LV_BASEANIM_EXIT_TYPE == lv_baseanim_get_type(baseanim))
    {
        if (NULL == switch_multanim)
        {
        	//1.创建multanim实例
            switch_multanim = lv_multanim_create(anim_obj);
            //2.设置动画类型
            lv_multanim_set_type(switch_multanim, LV_MULTANIM_3D);
            //3.设置主图片
            lv_multanim_set_major_img(switch_multanim, anim_obj);
            lv_multanim_set_zoom(switch_multanim, APP_TRANS_ANIM_ZOOM_NONE + 4, APP_TRANS_ANIM_ZOOM_NONE * 0.8f);
            lv_obj_add_event_cb(switch_multanim, lv_switch_multanim_delete, LV_EVENT_DELETE, NULL);
        }
        lv_baseanim_para_t *para = lv_baseanim_get_para(baseanim);
        if (para->flag)
            lv_multanim_set_process(switch_multanim, progress);//4.设置进度值
        else
            lv_multanim_set_process(switch_multanim, -progress);//4.设置进度值
    }
    else if (switch_multanim)
    {
    	//3.设置次图片
        lv_multanim_set_minor_img(switch_multanim, anim_obj);
    }
}

BUILTIN_ANIMATION(turn3Danim, LV_SWITCHANIM_TURN_3D, lv_turn3d_anim_progress);

3.平铺动画

//1.根据设置等动画类型,转化为multanim类型
uint8_t anim_type = TLV_ANIM_TYPE_FIRST;
uint32_t target_anim = LV_MULTANIM_ZOOM;
switch (g_tlv->anim_cfg.trans_type)
{
    case TLV_ANIM_TRANS_ZOOM:
        target_anim = LV_MULTANIM_ZOOM;
        break;
    case TLV_ANIM_TRANS_FADE:
        //target_anim = LV_MULTANIM_FADE;
        target_anim = LV_MULTANIM_BOOK;
        anim_type = TLV_ANIM_TYPE_SECOND;
        break;
    case TLV_ANIM_TRANS_TURN_3D_HOR:
        target_anim = LV_MULTANIM_3D;
        break;
    case TLV_ANIM_TRANS_TURN_Y:
        target_anim = LV_MULTANIM_SCALE;
        break;
    case TLV_ANIM_TRANS_DRAG:
        target_anim = LV_MULTANIM_TURN;
        break;
    default:
        break;
}

if (NULL == g_tlv->multanim)
    g_tlv->multanim = lv_multanim_create(g_tlv->multlist);//2.创建multanim实例
if (target_anim != lv_multanim_set_type(g_tlv->multanim, target_anim))//3.设置动画类型
{
    //4.如果当前动画类型首次设置,需配置相关参数
    #if defined(SOLUTION_RES_USING_NAND) || defined(EX_RES_USING_FILE_MODE)
    if (LV_MULTANIM_FADE == target_anim || LV_MULTANIM_OPEN == target_anim)
    {
        //4.1于mask动画,需设置具体的mask图片源
        if (NULL == g_tlv->mask_l)
            g_tlv->mask_l = lv_multanim_create_mask(APP_GET_IMG(img_mask_left));
        if (NULL == g_tlv->mask_r)
            g_tlv->mask_r = lv_multanim_create_mask(APP_GET_IMG(img_mask_right));
        lv_multanim_set_mask(g_tlv->multanim, g_tlv->mask_l, g_tlv->mask_r); //5.设置主图片
    }
    else
    {
        if (g_tlv->mask_l)
            lv_multanim_free_mask(g_tlv->mask_l);
        if (g_tlv->mask_r)
            lv_multanim_free_mask(g_tlv->mask_r);
        g_tlv->mask_l = NULL;
        g_tlv->mask_r = NULL;
    }
    #else
    lv_multanim_set_mask(g_tlv->multanim, APP_GET_IMG(img_mask_left), APP_GET_IMG(img_mask_right));
    #endif
    //4.1配置动画图片的缩放系数
    if (LV_MULTANIM_ZOOM == target_anim)
        lv_multanim_set_zoom(g_tlv->multanim, APP_TRANS_ANIM_ZOOM_NONE, APP_TRANS_ANIM_ZOOM_NONE >> 1);
    else if (LV_MULTANIM_3D == target_anim)
        lv_multanim_set_zoom(g_tlv->multanim, APP_TRANS_ANIM_ZOOM_NONE + 2, APP_TRANS_ANIM_ZOOM_NONE * 0.7f);
    else if (LV_MULTANIM_SCALE == target_anim)
        lv_multanim_set_zoom(g_tlv->multanim, APP_TRANS_ANIM_ZOOM_NONE + 2, APP_TRANS_ANIM_ZOOM_NONE + 2);
    else
        lv_multanim_set_zoom(g_tlv->multanim, APP_TRANS_ANIM_ZOOM_NONE, APP_TRANS_ANIM_ZOOM_NONE);
}
if (LV_MULTANIM_ZOOM != target_anim)
    lv_obj_center(item->snapshot);
int32_t proc = (offset << 10) / LV_HOR_RES_MAX;
if (anim_type == TLV_ANIM_TYPE_FIRST)
{
    //动画类型:为两张图片配合动画
    if (offset_abs <= (LV_HOR_RES_MAX >> 1))
    {
        if (offset_abs <= (LV_HOR_RES_MAX >> 2))
        {
            if (LV_MULTANIM_ZOOM != target_anim)
                lv_img_set_zoom(item->snapshot, APP_TRANS_ANIM_ZOOM_NONE);
            lv_multanim_set_major_img(g_tlv->multanim, item->snapshot);
        }
        if (item->snapshot == lv_multanim_get_minor_img(g_tlv->multanim))
            proc = proc > 0 ? (proc - 1024) : (proc + 1024);
        lv_multanim_set_process(g_tlv->multanim, proc);//6.设置动画进度
    }
    else
    {
        lv_obj_move_background(item->snapshot);
        lv_multanim_set_minor_img(g_tlv->multanim, item->snapshot); //7.设置次图
    }
}
else
{
    //动画类型:只有上面图片有动画,下面图片保持不动
    if (offset_abs <= (LV_HOR_RES_MAX >> 1))
    {
        lv_obj_center(item->snapshot);
        lv_obj_t *major_img = lv_multanim_get_major_img(g_tlv->multanim);
        if(NULL == major_img)
            lv_multanim_set_major_img(g_tlv->multanim, item->snapshot);
        else if(major_img != item->snapshot)
            proc = proc > 0 ? (proc - 1024) : (proc + 1024);
        lv_multanim_set_process(g_tlv->multanim, proc);//6.设置动画进度
    }
    else
    {
        lv_obj_move_background(item->snapshot);
        if (NULL == lv_multanim_get_minor_img(g_tlv->multanim))
            lv_multanim_set_minor_img(g_tlv->multanim, item->snapshot);//7.设置次图
    }
}

四、注意事项

  1、由于本控件只是对动画本身按进度进行了功能封装,在使用时需根据实际场景进行适配。比如APP切换动画,在注册的切换回调中使用该控件的接口进行控件的初始化已经进度控制。