From b9beaba858e64ca1270a7eff39b0ef4ab288fed8 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Tue, 10 Mar 2026 23:51:41 -0400 Subject: [PATCH] Initial swap animation --- package.json | 2 +- src/c/main.c | 66 +++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index cdd2890..5eaea05 100644 --- a/package.json +++ b/package.json @@ -539,7 +539,7 @@ "type": "bitmap" }, { - "file": "fonts/RetroComputer.ttf", + "file": "fonts/RetroComputerTime.ttf", "name": "FONT_RETRO_COMPUTER_32", "targetPlatforms": [ "emery", diff --git a/src/c/main.c b/src/c/main.c index b3f5797..8df7533 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -16,6 +16,10 @@ static GBitmap *s_head_current; static GBitmap *s_butt_current; static GBitmap *s_head_next; static GBitmap *s_butt_next; +static GRect s_guy_head_grect_on = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(0, -16), 260, 115); +static GRect s_guy_head_grect_off = GRect(PBL_IF_ROUND_ELSE(-260, -230), PBL_IF_ROUND_ELSE(0, -16), 260, 115); +static GRect s_guy_butt_grect_on = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(145, 129), 260, 115); +static GRect s_guy_butt_grect_off = GRect(PBL_IF_ROUND_ELSE(260, 170), PBL_IF_ROUND_ELSE(145, 129), 260, 115); // declare lookup tables static const uint8_t s_head_count = 22; @@ -71,38 +75,78 @@ static void update_minute_1() { text_layer_set_text(s_date_layer, s_date_buffer); } -static void update_minute_30() { - update_minute_1(); - // update butt on half-hour boundaries +static void update_minute_30_out_handler(Animation *animation, bool finished, void *context) { + // destroy and reassign current gbitmap_destroy(s_butt_current); s_butt_current = s_butt_next; + + // swap colors replace_gbitmap_color(GColorGreen, s_random_color_next, s_butt_current, NULL); replace_gbitmap_color(s_random_color_current, s_random_color_next, s_head_current, NULL); - // update current color so it can be referenced for later replacement - s_random_color_current = s_random_color_next; + s_random_color_current = s_random_color_next; // must be referenced for later replacement + + // force update bitmap layers bitmap_layer_set_bitmap(s_guy_butt_layer, s_butt_current); bitmap_layer_set_bitmap(s_guy_head_layer, s_head_current); + + // animate return + Animation *butt_in_anim = property_animation_get_animation(property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_off, &s_guy_butt_grect_on)); + animation_set_curve(butt_in_anim, AnimationCurveEaseOut); + animation_set_duration(butt_in_anim, 350); + animation_schedule(butt_in_anim); + // calc next values s_butt_next = gbitmap_create_with_resource(s_random_butts[rand() % s_butt_count]); s_random_color_next = s_dark_bg_colors[rand() % s_color_count]; // next color } -static void update_minute_60() { +static void update_minute_30() { update_minute_1(); - // update head on hour boundaries + + // swap the silly butt on half-hour intervals + Animation *butt_out_anim = property_animation_get_animation(property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on, &s_guy_butt_grect_off)); + animation_set_curve(butt_out_anim, AnimationCurveEaseOut); + animation_set_duration(butt_out_anim, 350); + animation_set_handlers(butt_out_anim, (AnimationHandlers){.stopped = update_minute_30_out_handler}, NULL); + animation_schedule(butt_out_anim); +} + +static void update_minute_60_out_handler(Animation *animation, bool finished, void *context) { + // destroy and reassign current gbitmap_destroy(s_head_current); s_head_current = s_head_next; + + // swap colors replace_gbitmap_color(GColorGreen, s_random_color_next, s_head_current, NULL); replace_gbitmap_color(s_random_color_current, s_random_color_next, s_butt_current, NULL); - // update current color so it can be referenced for later replacement s_random_color_current = s_random_color_next; + + // force update bitmap layers bitmap_layer_set_bitmap(s_guy_head_layer, s_head_current); bitmap_layer_set_bitmap(s_guy_butt_layer, s_butt_current); + + // animate return + Animation *head_in_anim = property_animation_get_animation(property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_off, &s_guy_head_grect_on)); + animation_set_curve(head_in_anim, AnimationCurveEaseOut); + animation_set_duration(head_in_anim, 350); + animation_schedule(head_in_anim); + // calc next values s_head_next = gbitmap_create_with_resource(s_random_heads[rand() % s_head_count]); s_random_color_next = s_dark_bg_colors[rand() % s_color_count]; // next color } +static void update_minute_60() { + update_minute_1(); + + // swap the silly head on hour intervals + Animation *head_out_anim = property_animation_get_animation(property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on, &s_guy_head_grect_off)); + animation_set_curve(head_out_anim, AnimationCurveEaseOut); + animation_set_duration(head_out_anim, 350); + animation_set_handlers(head_out_anim, (AnimationHandlers){.stopped = update_minute_60_out_handler}, NULL); + animation_schedule(head_out_anim); +} + static void minute_handler(struct tm *tick_time, TimeUnits units_changed) { if (tick_time->tm_min % 60 == 0) { update_minute_60(); @@ -118,8 +162,8 @@ static void main_window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); // format silly guy layers - s_guy_head_layer = bitmap_layer_create(GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(0, -16), 260, 115)); - s_guy_butt_layer = bitmap_layer_create(GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(145, 129), 260, 115)); + s_guy_head_layer = bitmap_layer_create(s_guy_head_grect_on); + s_guy_butt_layer = bitmap_layer_create(s_guy_butt_grect_on); bitmap_layer_set_background_color(s_guy_head_layer, GColorBlack); bitmap_layer_set_bitmap(s_guy_head_layer, s_head_current); bitmap_layer_set_background_color(s_guy_butt_layer, GColorBlack); @@ -132,7 +176,7 @@ static void main_window_load(Window *window) { text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter); // format date layer - s_date_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(22, 8), PBL_IF_ROUND_ELSE(120, 104), PBL_IF_ROUND_ELSE(260, 200), 14)); + s_date_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(20, 6), PBL_IF_ROUND_ELSE(120, 104), PBL_IF_ROUND_ELSE(260, 200), 14)); text_layer_set_background_color(s_date_layer, GColorClear); text_layer_set_font(s_date_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14)); text_layer_set_text_alignment(s_date_layer, GTextAlignmentLeft);