From 9ac977f25a1f913cde4d7c8ed4dd77d9e18dd144 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 23 Feb 2026 03:18:16 +0000 Subject: [PATCH] Extend right-side UI elements using visibleBoundsProperty on wider screens When the browser window is wider than the 1024px layout bounds, the three right-edge elements now track visibleBoundsProperty so they use the extra space instead of remaining anchored to the fixed layout bounds: - resetAllButton: right/bottom pin to visibleBounds.maxX/maxY - dataTableNode: left shifts right by the extra visible width beyond layoutBounds - kinematicsGraph (grasp): right tracks visibleBounds.maxX with the same 45px overhang so the user can still pull it onto the screen All three elements are wired in a single visibleBoundsProperty.link, which fires synchronously on screen resize for fully reactive layout updates. The playbackControlsNode centerY is also re-aligned inside the same link to stay vertically centred with the repositioned reset button. https://claude.ai/code/session_018AiQS4Eo6Q9u1eKoNLbAk3 --- src/screen-name/view/SimScreenView.ts | 29 +++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/screen-name/view/SimScreenView.ts b/src/screen-name/view/SimScreenView.ts index 432f100..a02faf1 100644 --- a/src/screen-name/view/SimScreenView.ts +++ b/src/screen-name/view/SimScreenView.ts @@ -82,7 +82,6 @@ export class SimScreenView extends ScreenView { // ── Data table (top, a bit to the left) ────────────────────────────── const dataTableNode = new DataTableNode(model, model.videoLoadedProperty, model.calibUnitProperty); this.addChild(dataTableNode); - dataTableNode.left = this.videoPlayerNode.right + 20; dataTableNode.top = this.layoutBounds.top + 10; // ── Reset all (bottom right) ───────────────────────────────────────── @@ -90,8 +89,6 @@ export class SimScreenView extends ScreenView { listener: () => { model.reset(); // resets all model state including tool positions }, - right: this.layoutBounds.maxX - RESET_BUTTON_MARGIN, - bottom: this.layoutBounds.maxY - RESET_BUTTON_MARGIN, }); this.addChild(resetAllButton); @@ -99,7 +96,6 @@ export class SimScreenView extends ScreenView { const playbackControlsNode = this.videoPlayerNode.playbackControlsNode; this.addChild(playbackControlsNode); playbackControlsNode.centerX = this.videoPlayerNode.centerX; - playbackControlsNode.centerY = resetAllButton.centerY; playbackControlsNode.boundsProperty.lazyLink(() => { playbackControlsNode.centerX = this.videoPlayerNode.centerX; playbackControlsNode.centerY = resetAllButton.centerY; @@ -108,8 +104,29 @@ export class SimScreenView extends ScreenView { // ── Kinematics graph (bottom right, above reset all) ───────────────── const kinematicsGraph = new KinematicsGraphNode(model, this, trackLabPreferences); this.addChild(kinematicsGraph); - kinematicsGraph.right = this.layoutBounds.maxX + 45; - kinematicsGraph.bottom = resetAllButton.top - 150; + + // ── Reactive right-edge positioning ────────────────────────────────── + // When the browser window is wider than layoutBounds, visibleBoundsProperty + // extends beyond layoutBounds on both sides. The three elements below are + // anchored to the right edge of the screen and must follow it dynamically. + this.visibleBoundsProperty.link((visibleBounds) => { + const extraWidth = Math.max(0, visibleBounds.maxX - this.layoutBounds.maxX); + + // Data display: shift right in proportion to the extra visible width. + dataTableNode.left = this.videoPlayerNode.right + 20 + extraWidth; + + // Reset button: stays pinned to the visible bottom-right corner. + resetAllButton.right = visibleBounds.maxX - RESET_BUTTON_MARGIN; + resetAllButton.bottom = visibleBounds.maxY - RESET_BUTTON_MARGIN; + + // Playback controls align vertically with the reset button. + playbackControlsNode.centerY = resetAllButton.centerY; + + // Kinematics graph (grasp): tracks the visible right edge with the same + // fixed overhang that lets the user pull it onto the screen. + kinematicsGraph.right = visibleBounds.maxX + 45; + kinematicsGraph.bottom = resetAllButton.top - 150; + }); // ── Webcam panel (topmost when visible, above coord/calibration overlays) ─ const webcamPanel = this.videoPlayerNode.webcamPanel;