#include <TFT_eSPI.h>
#include <lvgl.h>
// Configurações do display
#define TFT_WIDTH 320
#define TFT_HEIGHT 240
static TFT_eSPI tft;
// LVGL buffers
static lv_draw_buf_t draw_buf;
static lv_color_t buf[TFT_WIDTH * 10];
static lv_display_t *disp;
// Widgets
static lv_obj_t *raindrops[20]; // 20 gotas
static int rain_count = 0;
// Cor do céu
static lv_color_t sky_blue = lv_color_hex(0x87CEEB);
// -------------------- Callback de animação --------------------
static void rain_animation_cb(void *var, int32_t value)
{
lv_obj_t *drop = (lv_obj_t *)var;
lv_obj_set_y(drop, value);
if (value >= TFT_HEIGHT) {
lv_obj_set_pos(drop, random(10, TFT_WIDTH-10), 0);
}
}
// -------------------- Cria uma gota --------------------
static void create_raindrop(int x, int delay_ms)
{
static lv_style_t style_drop;
lv_style_init(&style_drop);
lv_style_set_bg_color(&style_drop, lv_color_hex(0xADD8E6)); // azul claro
lv_style_set_bg_opa(&style_drop, LV_OPA_80);
lv_style_set_radius(&style_drop, 8);
lv_obj_t *drop = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(drop);
lv_obj_add_style(drop, &style_drop, 0);
lv_obj_set_size(drop, 4, 12);
lv_obj_set_pos(drop, x, random(0, 100));
// Animação
lv_anim_t anim;
lv_anim_init(&anim);
lv_anim_set_var(&anim, drop);
lv_anim_set_exec_cb(&anim, rain_animation_cb);
lv_anim_set_values(&anim, 0, TFT_HEIGHT);
lv_anim_set_time(&anim, 800 + random(0, 400));
lv_anim_set_delay(&anim, delay_ms);
lv_anim_set_repeat_count(&anim, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&anim);
raindrops[rain_count++] = drop;
}
// -------------------- Cria a nuvem --------------------
static void create_cloud()
{
lv_obj_t *cloud_container = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(cloud_container);
lv_obj_set_size(cloud_container, 150, 80);
lv_obj_set_pos(cloud_container, 80, 30);
lv_obj_set_style_bg_opa(cloud_container, LV_OPA_TRANSP, 0);
static lv_style_t style_cloud;
lv_style_init(&style_cloud);
lv_style_set_bg_color(&style_cloud, lv_color_hex(0xFFFFFF));
lv_style_set_bg_opa(&style_cloud, LV_OPA_COVER);
lv_style_set_radius(&style_cloud, LV_RADIUS_CIRCLE);
// Círculos da nuvem
lv_obj_t *c1 = lv_obj_create(cloud_container);
lv_obj_remove_style_all(c1);
lv_obj_add_style(c1, &style_cloud, 0);
lv_obj_set_size(c1, 50, 50);
lv_obj_set_pos(c1, 0, 20);
lv_obj_t *c2 = lv_obj_create(cloud_container);
lv_obj_remove_style_all(c2);
lv_obj_add_style(c2, &style_cloud, 0);
lv_obj_set_size(c2, 60, 60);
lv_obj_set_pos(c2, 35, 10);
lv_obj_t *c3 = lv_obj_create(cloud_container);
lv_obj_remove_style_all(c3);
lv_obj_add_style(c3, &style_cloud, 0);
lv_obj_set_size(c3, 50, 50);
lv_obj_set_pos(c3, 75, 20);
// Base da nuvem
lv_obj_t *base = lv_obj_create(cloud_container);
lv_obj_remove_style_all(base);
lv_obj_set_style_bg_color(base, lv_color_hex(0xFFFFFF), 0);
lv_obj_set_style_radius(base, 20, 0);
lv_obj_set_size(base, 120, 40);
lv_obj_set_pos(base, 15, 45);
}
// -------------------- Flush LVGL v9 --------------------
static void my_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *color_p)
{
uint32_t w = area->x2 - area->x1 + 1;
uint32_t h = area->y2 - area->y1 + 1;
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
uint16_t *buf16 = (uint16_t*) color_p;
tft.pushColors(buf16, w*h, true);
tft.endWrite();
lv_display_flush_ready(disp);
}
// -------------------- Inicializa display LVGL v9 --------------------
static void init_display()
{
tft.begin();
tft.setRotation(0);
lv_init();
lv_draw_buf_init(&draw_buf,
TFT_WIDTH, // largura
10, // altura do buffer
LV_COLOR_FORMAT_RGB565,
TFT_WIDTH, // stride
buf, sizeof(buf));
disp = lv_display_create(TFT_WIDTH, TFT_HEIGHT);
lv_display_set_draw_buffers(disp, &draw_buf, nullptr);
lv_display_set_flush_cb(disp, my_flush_cb);
}
// -------------------- Setup --------------------
void setup()
{
Serial.begin(115200);
randomSeed(analogRead(0));
init_display();
lv_obj_t *scr = lv_scr_act();
lv_obj_set_style_bg_color(scr, sky_blue, 0);
create_cloud();
for (int i = 0; i < 20; i++) {
create_raindrop(random(10, 310), i*100);
}
Serial.println("Animação iniciada!");
}
// -------------------- Loop --------------------
void loop()
{
lv_timer_handler();
delay(5);
}Loading
esp32-p4-function-ev
esp32-p4-function-ev