From 9d806f0ec44f2537bd1f36de477213bf36287c47 Mon Sep 17 00:00:00 2001 From: Erik Brinkman Date: Wed, 21 Oct 2026 22:02:45 -0400 Subject: [PATCH] fix: update logo animation --- .../src/main/kotlin/cc/hafa/reader/ui/Logo.kt | 17 ++++++++++---- web/src/lib/components/logo.svelte | 22 +++++++++++-------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/android/app/src/main/kotlin/cc/hafa/reader/ui/Logo.kt b/android/app/src/main/kotlin/cc/hafa/reader/ui/Logo.kt index b8b6c4e..9923d6a 100644 --- a/android/app/src/main/kotlin/cc/hafa/reader/ui/Logo.kt +++ b/android/app/src/main/kotlin/cc/hafa/reader/ui/Logo.kt @@ -36,6 +36,10 @@ private const val DOT_RADIUS = 6f private const val SPACING = 13.2f private const val FIRST_RADIUS = 16.8f private const val STROKE = 8.1f +private const val LAST_RADIUS = FIRST_RADIUS + SPACING + +// outer edge of the still logo's last arc, which no wave crosses +private const val EDGE = LAST_RADIUS + STROKE / 2 private const val STEP_SECONDS = 0.7 private const val NANOS_PER_SECOND = 1e9 private val SLOTS = listOf(-1, 0, 1, 2) @@ -57,10 +61,15 @@ private fun wavesAt(phase: Double): List { val whole = floor(phase).toInt() val fraction = (phase - whole).toFloat() return SLOTS.map { slot -> - val radius = FIRST_RADIUS + SPACING * (slot + fraction) - val grow = smooth((radius - (FIRST_RADIUS - SPACING)) / SPACING) - val shrink = smooth(1 - (radius - (FIRST_RADIUS + SPACING)) / SPACING) - Wave(radius, STROKE * minOf(grow, shrink), if ((slot - whole) % 2 == 0) WHITE else BLUE) + val travel = FIRST_RADIUS + SPACING * (slot + fraction) + val color = if ((slot - whole) % 2 == 0) WHITE else BLUE + if (travel <= LAST_RADIUS) { + Wave(travel, STROKE * smooth((travel - (FIRST_RADIUS - SPACING)) / SPACING), color) + } else { + // past the last arc it holds its outer edge and thins inward + val width = STROKE * (1 - smooth((travel - LAST_RADIUS) / SPACING)) + Wave(EDGE - width / 2, width, color) + } } } diff --git a/web/src/lib/components/logo.svelte b/web/src/lib/components/logo.svelte index b5b08fa..dbce4c9 100644 --- a/web/src/lib/components/logo.svelte +++ b/web/src/lib/components/logo.svelte @@ -16,6 +16,9 @@ const SPACING = 13.2; const FIRST_RADIUS = 16.8; const STROKE = 8.1; + const LAST_RADIUS = FIRST_RADIUS + SPACING; + // outer edge of the still logo's last arc, which no wave crosses + const EDGE = LAST_RADIUS + STROKE / 2; const STEP_SECONDS = 0.7; const SLOTS = [-1, 0, 1, 2]; const WHITE = "#fff"; @@ -33,15 +36,16 @@ const whole = Math.floor(phase); const fraction = phase - whole; return SLOTS.map((slot) => { - const radius = FIRST_RADIUS + SPACING * (slot + fraction); - const grow = smooth((radius - (FIRST_RADIUS - SPACING)) / SPACING); - const shrink = smooth(1 - (radius - (FIRST_RADIUS + SPACING)) / SPACING); - return { - slot, - radius, - width: STROKE * Math.min(grow, shrink), - color: (slot - whole) % 2 === 0 ? WHITE : BLUE, - }; + const travel = FIRST_RADIUS + SPACING * (slot + fraction); + const color = (slot - whole) % 2 === 0 ? WHITE : BLUE; + if (travel <= LAST_RADIUS) { + const grow = smooth((travel - (FIRST_RADIUS - SPACING)) / SPACING); + return { slot, radius: travel, width: STROKE * grow, color }; + } else { + // past the last arc it holds its outer edge and thins inward + const width = STROKE * (1 - smooth((travel - LAST_RADIUS) / SPACING)); + return { slot, radius: EDGE - width / 2, width, color }; + } }); });