Description
I have a need to create a custom animation. I want to create the effect of a glass being filled with a liquid in an animation. So I need to simply change the color of pixels inside the glass in an animation.
What MCU/Processor/Board and compiler are you using?
i.MXRT1050EVK – IAR v8.50
What LVGL version are you using?
v7.0.1
What do you want to achieve?
Fill animation
What have you tried so far?
-
I tried creating lines at each Y point (bounded by the X coordinates I gave it) using the lv_line_create. That just resulted in a singled line that moved around the screen.
-
I tried using the lv_draw_line to draw lines between the X bounds at different Y levels. That didn’t work either.
-
I have tried changing the colors in the display buffers. This has been my most successful attempt as I can create a filled area of whatever shape I want. However, it still only seems to leave a single line at the end of the animation. The code that I have used for this is shown below. This one is the most perplexing to me.
Code to reproduce
#define LV_COLOR_BROWN LV_COLOR_MAKE(0x86, 0x64, 0x42)
static void cafeBrewStart_cb(lv_obj_t * btn, lv_event_t event)
{
uint32_t llY, ulY, lrY, urY, tmp32;
uint32_t startY, endY;
if(event == LV_EVENT_CLICKED) {
/*Create an array for the points of the line*/
// // Call brewing animation here
#if LV_USE_ANIMATION == 1
// Get Y values of start and end points of the lines
llY = demo_ui.CafeBrewScr_cupLeftSide->coords.y1;
ulY = demo_ui.CafeBrewScr_cupLeftSide->coords.y2;
if(llY < ulY) {
tmp32 = ulY;
ulY = llY;
llY = tmp32;
}
lrY = demo_ui.CafeBrewScr_cupRightSide->coords.y1;
urY = demo_ui.CafeBrewScr_cupRightSide->coords.y2;
if(lrY < urY) {
tmp32 = urY;
urY = lrY;
lrY = tmp32;
}
// Set start and end Y coords.
if(llY > lrY) {
startY = llY;
} else {
startY = lrY;
}
if(ulY > urY) {
endY = ulY;
} else {
endY = urY;
}
// Setup the animation
lv_anim_init(&brew_a);
// Since I'm executing a custom function, I don't think it really
// matters what I animate.
lv_anim_set_var(&brew_a, demo_ui.CafeHmScr);
lv_anim_set_custom_exec_cb(&brew_a, (lv_anim_custom_exec_cb_t) animateCoffeeCupFill);
lv_anim_set_time(&brew_a, 6000);
lv_anim_set_values(&brew_a, startY, endY);
lv_anim_set_start_cb(&brew_a, brew_animation_start_cb);
lv_anim_set_ready_cb(&brew_a, brew_animation_end_cb);
lv_anim_start(&brew_a);
#endif
}
void animateCoffeeCupFill(lv_obj_t * obj, lv_coord_t Ynew)
{
uint32_t tmpX1, tmpX2;
lv_point_t leftpoint, rightpoint;
lv_disp_t * lDisp;
lv_coord_t xRes, yRes;
lv_disp_buf_t * dispBuf;
lv_color_t * mem1;
lv_color_t * mem2;
lv_color_t * mem3;
lDisp = _lv_refr_get_disp_refreshing();
dispBuf = lv_disp_get_buf(lDisp);
mem1 = (lv_color_t *)dispBuf->buf_act;
mem2 = (lv_color_t *)dispBuf->buf1;
mem3 = (lv_color_t *)dispBuf->buf2;
// Animate coffee cup
// Get point one of the line (Left line)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tmpX1 = demo_ui.CafeBrewScr_cupLeftSide->coords.x1;
if(tmpX1 < demo_ui.CafeBrewScr_cupLeftSide->coords.x2) {
tmpX1 = demo_ui.CafeBrewScr_cupLeftSide->coords.x2;
}
leftpoint.x = tmpX1;
leftpoint.y = Ynew;
// Get point two of the line (Right line)
tmpX2 = demo_ui.CafeBrewScr_cupRightSide->coords.x1;
if(tmpX2 > demo_ui.CafeBrewScr_cupRightSide->coords.x2) {
tmpX2 = demo_ui.CafeBrewScr_cupRightSide->coords.x2;
}
rightpoint.x = tmpX2;
rightpoint.y = Ynew;
for(tmpX1 = leftpoint.x; tmpX1 < rightpoint.x; tmpX1++) {
mem1[(Ynew * DEMO_PANEL_WIDTH + tmpX1)] = LV_COLOR_BROWN;
mem2[(Ynew * DEMO_PANEL_WIDTH + tmpX1)] = LV_COLOR_BROWN;
mem3[(Ynew * DEMO_PANEL_WIDTH + tmpX1)] = LV_COLOR_BROWN;
}
}
Screenshot and/or video
N/A at this time.