Shorten album art zoom to a 10s round-trip so it actually completes

At the old 60s round-trip, a fresh render (triggered by the server well
before a minute passes) kept restarting the animation from tick 0, so only
the outbound zoom-out was ever visible on-device -- it never appeared to
zoom back in. Shortening the loop to 10s total makes it far more likely a
full out-and-back cycle plays before the next refresh.
This commit is contained in:
poprhythm committed 2026-09-29 15:48:47 -04:00
1 parent cda256d1c2
commit dc0c5019ca
1 file changed
+19 -21
+19 -21
View File
@@ -87,17 +87,22 @@ def main(config):
return render.Root(child = content)
# Album art gets a slow "Ken Burns" breathing effect: eases from the full
# frame in to a zoomed-in crop of the top-left corner, then back out, on a
# continuous loop -- not a one-shot reveal. A one-shot version (start
# zoomed in, end on the full frame, then hold) looked jumpy: since the app
# re-renders on NOWPLAYING_TTL and each fresh render restarts its own
# animation from tick 0, whatever the *previous* pushed image happened to
# be showing at that moment gets abruptly replaced by a fresh zoomed-in
# frame. The back-and-forth loop doesn't eliminate that (a server-side
# re-render always restarts at tick 0 regardless), but ending exactly where
# it started means the animation also loops seamlessly on-device between
# refreshes, which in practice reads as far less jarring than a one-way
# reveal that snaps back.
# frame in to a zoomed-in crop, then back out, on a continuous loop -- not
# a one-shot reveal. A one-shot version (start zoomed in, end on the full
# frame, then hold) looked jumpy: since the app re-renders on NOWPLAYING_TTL
# and each fresh render restarts its own animation from tick 0, whatever the
# *previous* pushed image happened to be showing at that moment gets
# abruptly replaced by a fresh zoomed-in frame. The back-and-forth loop
# doesn't eliminate that (a server-side re-render always restarts at tick 0
# regardless), but ending exactly where it started means the animation also
# loops seamlessly on-device between refreshes.
#
# Duration is intentionally short (a handful of seconds each way), not the
# ~60s round-trip originally tried: on the real device/server, a fresh
# render replaces the still-playing animation well before a minute-long
# cycle can complete, so only the outbound half (zoom out) was ever visible
# and it never appeared to "zoom back in". A short loop guarantees at least
# one full out-and-back cycle plays before that happens.
#
# Art is rendered oversized (45x45, vs. the 32x32 display slot) since
# animation.Scale has no visible effect on a widget whose declared size
@@ -110,18 +115,11 @@ def main(config):
# animation.Scale(1.0, 1.0) -- so scaling *down* from there shrinks the
# already-fitted image further, exposing background outside its bounds
# (the black border). Scaling *up* only ever crops further into the image,
# which is always safe. animation.Scale's pivot defaults to the top-left
# corner (confirmed empirically; an explicit `origin` param had no effect
# at all, so isn't used here) -- there's no reliable way to zoom into any
# other corner, so this always zooms into the top-left. Duration 1200
# ticks x the default 50ms/tick = 60s round-trip (30s in, 30s out);
# verified empirically that a slower zoom compresses *smaller*, not
# larger, since more adjacent ticks become pixel-identical at this
# resolution -- well under the 460KB device limit.
# which is always safe.
ART_SIZE = 45
ART_SLOT = 32
ART_ZOOM_SCALE = 1.4 # how far in to zoom on the top-left corner
ART_ZOOM_DURATION = 1200 # 60s at the default 50ms/tick
ART_ZOOM_SCALE = 1.4 # how far in to zoom
ART_ZOOM_DURATION = 200 # 10s round-trip (5s in, 5s out) at the default 50ms/tick
def _art_widget(art_bytes):
art = render.Image(src = art_bytes, width = ART_SIZE, height = ART_SIZE)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.