Rotate the random zoom spot over time, not just per-track

Random zoom position was previously picked once per track (stable via
subsonic_id) and held for that track's entire runtime. Changed it to
rotate on a ~10s cadence based on wall-clock time, still offset by a
per-track hash so different tracks don't all land on the same spot in
the same window. This lets a single long track show off different
sections of its own artwork over time, rather than being stuck on one
spot until the next track starts.
This commit is contained in:
poprhythm committed 2026-10-02 22:19:59 -04:00
1 parent d8add24c5e
commit f6893bdcdf
2 files changed
+43 -21

No files matched your search

+24 -12
View File
@@ -104,13 +104,22 @@ DEFAULT_ZOOM_LEVEL = "moderate"
# own 36x36 bounds. Kept modest (0.3-0.7, not full 0.0-1.0) and verified
# safe (no black border, even at the strongest 1.7x zoom) via the
# calibration tool -- more extreme corners weren't tested and may not be.
# Picked per-track (stable via subsonic_id, like the old corner-selection
# logic) rather than per-render, so a still-playing track doesn't jump
# between spots on every NOWPLAYING_TTL refresh. Only used when the
# "Zoom position" schema field is set to "random" -- "center" always zooms
# on the image's own center, exposed as a config choice since some covers
# (e.g. ones with a centered logo or face) read better with a predictable
# center zoom than a per-track random one.
# Only used when the "Zoom position" schema field is set to "random" --
# "center" always zooms on the image's own center, exposed as a config
# choice since some covers (e.g. ones with a centered logo or face) read
# better with a predictable center zoom than a random one.
#
# Rotates on a ~10s cadence (matching ART_ZOOM_DURATION below) based on
# wall-clock time, not just per-track: a time bucket picks the spot, offset
# by a per-track hash so different tracks don't all land on the same spot
# at the same moment. This means the spot can change on *every* refresh,
# including mid-playback of a single still-running track -- not just when
# the track itself changes -- so a long track gets to show off different
# sections of its art over time, which is the whole point of "random"
# rather than "center". One real limitation: a one-shot `pixlet render`
# CLI call reads the system clock same as the live server would, so this
# is still deterministic for a given moment -- it just varies *which*
# moment you rendered at, same as the live progress bar in _track_progress.
ZOOM_CENTER_SPOT = (0.5, 0.5)
ZOOM_RANDOM_SPOTS = [
(0.5, 0.5),
@@ -119,16 +128,19 @@ ZOOM_RANDOM_SPOTS = [
(0.3, 0.7),
(0.7, 0.3),
]
ZOOM_SPOT_ROTATE_SECONDS = 10
DEFAULT_ZOOM_POSITION = "center"
def _zoom_spot_for_track(zoom_position, subsonic_id):
def _zoom_spot(zoom_position, subsonic_id):
if zoom_position != "random":
return ZOOM_CENTER_SPOT
total = 0
track_offset = 0
for ch in subsonic_id.elems():
total += ord(ch)
return ZOOM_RANDOM_SPOTS[total % len(ZOOM_RANDOM_SPOTS)]
track_offset += ord(ch)
time_bucket = int(time.now().unix / ZOOM_SPOT_ROTATE_SECONDS)
return ZOOM_RANDOM_SPOTS[(time_bucket + track_offset) % len(ZOOM_RANDOM_SPOTS)]
def main(config):
station_url = config.get("station_url", DEFAULT_STATION_URL)
@@ -266,7 +278,7 @@ def _art_widget(art_bytes, zoom_scale, zoom_position, subsonic_id):
# toward the bottom-right -- the opposite of the bug it was meant to
# fix. Since `origin` already does directly and correctly what that
# Translate was clumsily approximating, this uses `origin` alone.
origin_x, origin_y = _zoom_spot_for_track(zoom_position, subsonic_id)
origin_x, origin_y = _zoom_spot(zoom_position, subsonic_id)
top_scale = max(zoom_scale, 1.0)
zoom = animation.Transformation(
child = art,
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.