diff --git a/subwave_nowplaying.star b/subwave_nowplaying.star index ea9f3ec..d69387f 100644 --- a/subwave_nowplaying.star +++ b/subwave_nowplaying.star @@ -370,7 +370,14 @@ def _glitch_band(zoomed_art, top, height, shift_x, hue_change): pad = (0, top, 0, max(0, ART_SLOT - top - height)), child = render.Box(width = ART_SLOT, height = height, child = tinted), ) - return render.Padding(pad = (max(0, shift_x), 0, max(0, -shift_x), 0), child = band) + shifted = render.Padding(pad = (max(0, shift_x), 0, max(0, -shift_x), 0), child = band) + + # render.Padding *grows* its child's declared size by the pad amount + # rather than nudging content within a fixed frame -- without this + # outer Box to clip it back down to exactly ART_SLOT, the horizontal + # shift above made this (and everything stacked with it) wider than + # the 32px art slot, bleeding into the text column next to it. + return render.Box(width = ART_SLOT, height = ART_SLOT, child = shifted) def _glitch_jitter(zoomed_art): states = [] @@ -387,6 +394,8 @@ def _glitch_jitter(zoomed_art): states.append(animation.Transformation( child = state, duration = GLITCH_HOLD_TICKS, + width = ART_SLOT, + height = ART_SLOT, keyframes = [ animation.Keyframe(percentage = 0.0, transforms = []), animation.Keyframe(percentage = 1.0, transforms = []), @@ -410,27 +419,58 @@ def _glitch_scanlines(): return render.Column(children = lines) def _glitch_corner_ticks(color): - def tick(): - return render.Stack(children = [ - render.Box(width = 5, height = 1, color = color), - render.Box(width = 1, height = 5, color = color), - ]) + tick_size = 5 - return render.Column( - main_align = "space_between", - expanded = True, - children = [ - render.Row(main_align = "space_between", expanded = True, children = [tick(), tick()]), - render.Row(main_align = "space_between", expanded = True, children = [tick(), tick()]), - ], + # A single tick shape (two short perpendicular lines) always draws + # the same way regardless of which corner it's placed in -- it has no + # idea it's "the top-right one". To make the bracket actually open + # toward the image's center at every corner (not just top-left), each + # line has to be explicitly pushed to the correct edge of its own + # tick_size x tick_size box via Padding: the horizontal line to the + # top or bottom, the vertical line to the left or right. Wrapped in an + # outer Box for the same reason as _glitch_band -- Padding grows its + # child's declared size, so without this the tick would be wider/ + # taller than tick_size. + def tick(top_aligned, left_aligned): + h_line = render.Padding( + pad = (0, 0 if top_aligned else tick_size - 1, 0, tick_size - 1 if top_aligned else 0), + child = render.Box(width = tick_size, height = 1, color = color), + ) + v_line = render.Padding( + pad = (0 if left_aligned else tick_size - 1, 0, tick_size - 1 if left_aligned else 0, 0), + child = render.Box(width = 1, height = tick_size, color = color), + ) + return render.Box(width = tick_size, height = tick_size, child = render.Stack(children = [h_line, v_line])) + + return render.Box( + width = ART_SLOT, + height = ART_SLOT, + child = render.Column( + main_align = "space_between", + expanded = True, + children = [ + render.Row(main_align = "space_between", expanded = True, children = [ + tick(top_aligned = True, left_aligned = True), + tick(top_aligned = True, left_aligned = False), + ]), + render.Row(main_align = "space_between", expanded = True, children = [ + tick(top_aligned = False, left_aligned = True), + tick(top_aligned = False, left_aligned = False), + ]), + ], + ), ) def _glitch_effect(zoomed_art): - return render.Stack(children = [ - _glitch_jitter(zoomed_art), - _glitch_scanlines(), - _glitch_corner_ticks("#33ff99"), - ]) + return render.Box( + width = ART_SLOT, + height = ART_SLOT, + child = render.Stack(children = [ + _glitch_jitter(zoomed_art), + _glitch_scanlines(), + _glitch_corner_ticks("#33ff99"), + ]), + ) def _message_screen(lines, colors): return render.Column(