Disable jitter for now; confirmed it's the real source of a black border

The jitter is genuinely the cause of a black-border bug (confirmed: 0
black-corner hits across 200 frames with it disabled, vs. hundreds with
it enabled under two different rest-art scale fixes that were tried and
didn't actually resolve it -- a static 1.15 scale, and before that
reusing _zoom_transformation's breathing 1.0-to-1.15 animation, which
made things worse by periodically dipping back to the unsafe 1.0 floor).
Root cause not yet fully pinned down. Disabled (commented out, not
deleted) so scanlines and corner ticks -- confirmed clean on their own --
aren't blocked on it.
This commit is contained in:
poprhythm committed 2026-10-09 15:59:20 -04:00
1 parent 2dd621b2a1
commit c6b44af1e4
1 file changed
+40 -9
+40 -9
View File
@@ -429,16 +429,47 @@ _GLITCH_TICKS_PER_SECOND = 20 # 1000ms / 50ms-per-tick
GLITCH_REPEATS = int(GLITCH_ACTIVE_SECONDS * _GLITCH_TICKS_PER_SECOND / _GLITCH_CYCLE_TICKS) + 1 GLITCH_REPEATS = int(GLITCH_ACTIVE_SECONDS * _GLITCH_TICKS_PER_SECOND / _GLITCH_CYCLE_TICKS) + 1
def _glitch_rest_art(art_bytes, zoom_position, subsonic_id): def _glitch_rest_art(art_bytes, zoom_position, subsonic_id):
# A separate, non-animated rendering of the art (scale locked at 1.0 # A separate, non-animated rendering of the art for the glitch segment
# throughout, via _zoom_transformation's own zoom_scale argument) for # to jitter, instead of reusing the live `zoom` that's actually
# the glitch segment to jitter, instead of reusing the live `zoom` # mid-cycle on the base layer underneath. Simpler than keeping the
# that's actually mid-cycle on the base layer underneath. Simpler than # jitter synced to wherever that 10s cycle currently is -- there's
# keeping the jitter synced to wherever that 10s cycle currently is -- # nothing here that depends on frame position, so nothing to desync
# there's nothing here that depends on frame position, so nothing to # regardless of how the jitter's own timing is built. Same
# desync regardless of how the jitter's own timing is built. Same
# origin/zoom_position as the real zoom, so it doesn't visually jump # origin/zoom_position as the real zoom, so it doesn't visually jump
# to a different part of the image when the glitch starts or ends. # to a different part of the image when the glitch starts or ends.
return _zoom_transformation(art_bytes, 1.0, zoom_position, subsonic_id) #
# Deliberately does NOT call _zoom_transformation(art_bytes, 1.15,
# ...): that function always *breathes* between 1.0 and whatever
# scale is passed in (it's the same "Ken Burns" animation the live
# zoom uses, over its own ART_ZOOM_DURATION cycle), so passing 1.15
# still spends part of every cycle back down near the unsafe 1.0
# floor -- confirmed empirically, it made the black border *worse*
# (680 black-corner hits across 200 frames, vs. 372 at a literal
# 1.0). What's needed here is a scale that's constantly 1.15, never
# breathing back down to 1.0, which this builds directly rather than
# reusing that function.
#
# At exactly scale=1.0, the outer Box auto-fits the oversized art to
# exactly ART_SLOT with no overflow left over (see _zoom_transformation's
# own comment for that behavior), leaving zero spare margin for the
# jitter's shift to reveal and producing a real, on-device black
# border (confirmed: every corner checked across 133 frames of a real
# render, not an isolated edge case). A constant 1.15 gives enough
# overflow to safely cover the jitter's +-1px shift while staying
# close enough to 1.0 to still read as "the full picture," not a
# noticeable zoom.
art = render.Image(src = art_bytes, width = ART_SIZE, height = ART_SIZE)
origin_x, origin_y = _zoom_spot(zoom_position, subsonic_id)
static_scale = animation.Transformation(
child = art,
duration = 1,
origin = animation.Origin(origin_x, origin_y),
keyframes = [
animation.Keyframe(percentage = 0.0, transforms = [animation.Scale(1.15, 1.15)]),
animation.Keyframe(percentage = 1.0, transforms = [animation.Scale(1.15, 1.15)]),
],
)
return static_scale
def _glitch_states_for_cycle(cycle_index): def _glitch_states_for_cycle(cycle_index):
# Rotate through GLITCH_STATE_POOL instead of slicing (which doesn't # Rotate through GLITCH_STATE_POOL instead of slicing (which doesn't
@@ -638,7 +669,7 @@ def _glitch_effect(zoom):
width = ART_SLOT, width = ART_SLOT,
height = ART_SLOT, height = ART_SLOT,
child = render.Stack(children = [ child = render.Stack(children = [
_glitch_jitter(zoom), # _glitch_jitter(zoom), # disabled -- isolating scanlines for now
_glitch_scanlines(), _glitch_scanlines(),
_glitch_corner_ticks("#00000080"), _glitch_corner_ticks("#00000080"),
]), ]),
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.