Wish lv_draw_mask_param_t has lv_draw_mask_text_param_t too,
for colorizing gradian text, rainbow text, etc…
It was my dream too the make possible to create things like that. However, it’d be very expensive to calculate this kind of mask real-time. Instead you can draw a text to a LV_IMG_CF_ALPHA_8BIT
canvas and use lv_draw_mask_map
.
Oh, I see, I will try by lv_draw_mask_map(..)
I’ve created an example:
/*Create a mask map with a canvas*/
static uint8_t buf[LV_IMG_BUF_SIZE_ALPHA_8BIT(200, 30)];
lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas, buf, 200, 30, LV_IMG_CF_ALPHA_8BIT);
memset(buf, 0x00, sizeof(buf));
lv_canvas_draw_text(canvas, 0, 0, 200, &style, "Hello world", LV_LABEL_ALIGN_LEFT);
lv_obj_del(canvas); /*Not required anymore, only `buf` will be used*/
/*Create a masker object. Everything is drawn on this object will be masked*/
lv_obj_t * mask = lv_objmask_create(lv_scr_act(), NULL);
/*Add a the mask map to the masking object.*/
lv_draw_mask_param_t mp;
lv_area_t area;
area.x1 = 0;
area.x1 = 0;
area.x2 = 199;
area.y2 = 29;
lv_draw_mask_map_init(&mp, &area, buf);
lv_objmask_add_mask(mask, &mp, 1);
lv_obj_set_size(mask, 200, 30);
/* Create a simple object with a gradient style.
* (Image can be used too)*/
lv_obj_t * obj = lv_obj_create(mask, NULL);
lv_obj_set_size(obj, 200, 30);
lv_obj_set_style(obj, &style);
I’ll add some updates soon:
- the mask coordinates are always absolute but it should be translated to relative by
lv_objmask
- now the whole
lv_draw_mask_param_t
is saved by the masking system. Later only it’s pointer will be saved.
@kisvegabor
Thank you.
I’ve just tried by the following code. But the result is so strange. What is wrong? How to fix the code?
uint8_t buf[ 200* 50];
void create_text_gradian() {
static lv_style_t style;
lv_style_copy(&style, &lv_style_plain);
style.body.main_color = LV_COLOR_RED;
style.body.grad_color = LV_COLOR_BLUE;
const char* str = "Hello Lvgl-007";
/*Create a mask map with a canvas*/
lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas, buf, 200,50, LV_IMG_CF_ALPHA_8BIT);
memset(buf, 0x00, sizeof(buf));
lv_canvas_draw_text(canvas, 0, 0, 200, &style, str, LV_LABEL_ALIGN_LEFT);
lv_obj_del(canvas); /*Not required anymore, only `buf` will be used*/
/*Create a masker object. Everything is drawn on this object will be masked*/
lv_obj_t * mask = lv_objmask_create(lv_scr_act(), NULL);
/*Add a the mask map to the masking object.*/
lv_draw_mask_param_t mp;
lv_area_t area;
area.x1 = 0;
area.y1 = 0;
area.x2 = 199;
area.y2 = 49;
lv_draw_mask_map_init(&mp, &area, buf);
lv_objmask_add_mask(mask, &mp, 1);
lv_obj_set_size(mask, 200, 50);
/* Create a simple object with a gradient style.
(Image can be used too)*/
lv_obj_t * obj = lv_obj_create(mask, NULL);
lv_obj_set_size(obj, 200, 50);
lv_obj_set_style(obj, &style);
}
Sorry, I forget to add the code of style
initialization.
You should set style.text.color=LV_COLOR_WHITE
. Higher brightness makes more visible pixels in the mask.
You should also set lv_objmask_set_style(mask, LV_OBJMASK_STYLE_BG, &lv_style_transp);
.
It’s already the default in the latest dev-7.0
Already tft can display right now.
And I’ve tried to set align for the object and/or the mask.
But tft can’t display align correctly.
How to set align for the mask + obj ?
Or lv_objmask should change the area from absolute position to relative position ?
Now all the mask coordinates are absolute.
I’m planning to translate the coordinates relative in lv_objmask
as I’ve mentioned here (I’ll add it probably next week)
Oh, sorry for I didn’t got you mention in the second comment.
Waiting for the coordinates relative objmask.
I’ve just updated lv_objmask
to translate to mask coordinates to relative. There were minor API changes as well.
Here are two example:
void text_mask(void)
{
static lv_style_t style;
lv_style_copy(&style, &lv_style_plain);
style.text.color = LV_COLOR_WHITE;
style.text.font = &lv_font_roboto_28;
style.body.main_color = LV_COLOR_RED;
style.body.grad_color = LV_COLOR_LIME;
/*Create a mask map with a canvas*/
static uint8_t buf[LV_IMG_BUF_SIZE_ALPHA_8BIT(200, 30)];
lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL);
lv_canvas_set_buffer(canvas, buf, 200, 30, LV_IMG_CF_ALPHA_8BIT);
memset(buf, 0x00, sizeof(buf));
lv_canvas_draw_text(canvas, 0, 0, 200, &style, "Hello world", LV_LABEL_ALIGN_LEFT);
lv_obj_del(canvas); /*Not required anymore, only `buf` will be used*/
/*Create a masker object. Everything is drawn on this object will be masked*/
lv_obj_t * mask = lv_objmask_create(lv_scr_act(), NULL);
/*Add a the mask map to the masking object.*/
lv_draw_mask_map_param_t mp;
lv_area_t area;
area.x1 = 0;
area.y1 = 0;
area.x2 = 199;
area.y2 = 29;
lv_draw_mask_map_init(&mp, &area, buf);
lv_objmask_add_mask(mask, &mp);
lv_obj_set_size(mask, 200, 30);
lv_obj_set_drag(mask, true);
/* Create a simple object with a gradient style.
* (Image can be used too)*/
lv_obj_t * obj = lv_obj_create(mask, NULL);
lv_obj_set_size(obj, 200, 30);
lv_obj_set_style(obj, &style);
lv_obj_set_click(obj, false);
}
lv_objmask_mask_t * m1;
void angle_mask_anim(lv_obj_t * objmask, lv_anim_value_t v)
{
lv_draw_mask_angle_param_t mp;
lv_draw_mask_angle_init(&mp, 100, 100, 0, v);
lv_objmask_upadte_mask(objmask, m1, &mp);
}
void angle_mask(void)
{
static lv_style_t style;
lv_style_copy(&style, &lv_style_plain);
style.body.main_color = LV_COLOR_RED;
style.body.grad_color = LV_COLOR_LIME;
/*Create a masker object. Everything is drawn on this object will be masked*/
lv_obj_t * mask = lv_objmask_create(lv_scr_act(), NULL);
/*Add a the mask map to the masking object.*/
lv_draw_mask_angle_param_t mp;
lv_draw_mask_angle_init(&mp, 100, 100, 0, 30);
m1 = lv_objmask_add_mask(mask, &mp);
lv_obj_set_size(mask, 200, 200);
lv_obj_set_drag(mask, true);
/* Create a simple object with a gradient style.
* (Image can be used too)*/
lv_obj_t * obj = lv_obj_create(mask, NULL);
lv_obj_set_size(obj, 200, 200);
lv_obj_set_style(obj, &style);
lv_obj_set_click(obj, false);
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, mask, (lv_anim_exec_xcb_t)angle_mask_anim);
lv_anim_set_values(&a, 10, 330);
lv_anim_set_time(&a, 2000, 0);
lv_anim_set_playback(&a, 200);
lv_anim_set_repeat(&a, 200);
lv_anim_create(&a);
}
...
text_mask();
angle_mask();
Wow! Must try!
BTW, mis-typo
lv_objmask_upadte_mask(..)
This is really going to open up the doors to a lot of cool effects! I’m excited to see what can be done with this!
If I wish to clear all masks in lv_objmask’s linked-list mask,
how to clear all ?
I’ve updated lv_objmask_remove_mask
to remove all masks if the mask
parameter is NULL
.
Also fixed the typo of lv_objmask_update_mask
, thanks.