From e8468932c3999fefd7603c20773e695dcb7d7c34 Mon Sep 17 00:00:00 2001 From: Milan Bhandari Date: Wed, 4 Nov 2026 00:39:56 -0500 Subject: [PATCH] Fit animations to the board's reading width A three-column scene with link labels asked for about 778px while the board's column is about 755px at any window width, so its right column ran off the block. The stage now lays out at least 720px wide, the board's reading width, and a narrower block scrolls it sideways rather than squeezing it. Within that width a scene's label gap gives way before its cards would overflow. A link's label also avoids other arrows' lines: a parallel edge drawn back between the same cards sat under the outbound label. The authoring instructions ask agents to draw for a 720px stage. Agent-Session: cbacb871-2558-4fe4-9272-77524bb21683 Agent-Session: ffed49d6-ca86-4940-b93c-e8eb7e0de440 Agent-Session: d7e3a290-82a4-4f66-9b3c-7a52a51add18 --- .../app/src/animation/animation-block.tsx | 29 ++-- .../app/src/animation/stage-protocol.ts | 5 + .../review/app/src/animation/stage-runtime.ts | 87 ++++++++++-- .../review/app/src/blocks.browser.test.tsx | 126 ++++++++++++++++-- packages/review/instructions/animation.md | 4 +- 5 files changed, 214 insertions(+), 37 deletions(-) diff --git a/packages/review/app/src/animation/animation-block.tsx b/packages/review/app/src/animation/animation-block.tsx index e3fb0d692..94fdf2e72 100644 --- a/packages/review/app/src/animation/animation-block.tsx +++ b/packages/review/app/src/animation/animation-block.tsx @@ -68,6 +68,7 @@ import type { PlayerStop, StagePlayer } from "./stage-player"; import { type HostMessage, STAGE_BOOT, + STAGE_MIN_WIDTH, type SlotLayout, type StageColorScheme, type StageInit, @@ -301,9 +302,10 @@ function StageBlock({ const { diagramFullscreenOnClick } = useWhiteboardSettings(); const frameRef = useRef(null); const [contentHeight, setContentHeight] = useState(STAGE_MIN_HEIGHT); - // The widest the stage's content has reached past its edge, in any frame; - // the stage keeps that width and a narrower block scrolls it. - const [minWidth, setMinWidth] = useState(0); + // The board's reading width, or the widest the stage's content has + // reached past its edge in any frame: the stage keeps that width and a + // narrower block scrolls it. + const [minWidth, setMinWidth] = useState(STAGE_MIN_WIDTH); // The tallest frame of the scenario, from a hidden measuring copy, so the // stage does not change height as the reader steps through frames. const [measuredHeight, setMeasuredHeight] = useState(0); @@ -360,7 +362,7 @@ function StageBlock({ // of its height, and the width its stage was laid out at. const holdInline = () => { setHeld(figureRef.current?.offsetHeight ?? 0); - setInlineWidth(canvasRef.current?.clientWidth ?? 0); + setInlineWidth(Math.max(canvasRef.current?.clientWidth ?? 0, minWidth)); }; const openRef = useRef(null); @@ -1100,11 +1102,7 @@ function StageBlock({ >
0 && styles.canvasScrolls, - scaled && styles.canvasScaled, - )} + {...stylex.props(styles.canvas, scaled && styles.canvasScaled)} style={{ height: stageHeight, ...(scaled && { @@ -1113,10 +1111,7 @@ function StageBlock({ }), }} > -
+