From 460ed2bc44e3451faae126c2e0df96259c11d24e Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:35:43 +0200 Subject: [PATCH] Keep grid rearrange shadow inside container (#6273) **Problem:** When rearranging grid elements, the shadow can go anywhere the mouse goes, making it seem like an absolute move. **Fix:** Wrap the shadow coords so they are restricted to the grid container bounds. | Before | After | |----------|--------------| | ![Kapture 2024-08-29 at 13 11 21](https://github.com/user-attachments/assets/cf92cae2-014b-4b58-87d6-fd3833ffe741) | ![Kapture 2024-08-29 at 13 10 43](https://github.com/user-attachments/assets/06f38111-e38b-4d8d-834d-9e59d7e71cf2) | Fixes #6272 --- .../canvas/controls/grid-controls.tsx | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx index 082408906c36..cb620cde6d73 100644 --- a/editor/src/components/canvas/controls/grid-controls.tsx +++ b/editor/src/components/canvas/controls/grid-controls.tsx @@ -32,6 +32,7 @@ import { pointsEqual, scaleRect, windowPoint, + zeroRectangle, zeroRectIfNullOrInfinity, } from '../../../core/shared/math-utils' import { @@ -505,6 +506,7 @@ export const GridControls = controlForStrategyMemoized(({ tar const canvasOffsetRef = useRefEditorState((store) => store.editor.canvas.roundedCanvasOffset) const scaleRef = useRefEditorState((store) => store.editor.canvas.scale) + const metadataRef = useRefEditorState((store) => store.editor.jsxMetadata) const activelyDraggingOrResizingCell = useEditorState( Substores.canvas, @@ -618,6 +620,20 @@ export const GridControls = controlForStrategyMemoized(({ tar const gridPath = optionalMap(EP.parentPath, shadow?.elementPath) + const gridFrame = React.useMemo(() => { + if (gridPath == null) { + return zeroRectangle + } + const maybeGridFrame = MetadataUtils.findElementByElementPath( + metadataRef.current, + gridPath, + )?.globalFrame + if (maybeGridFrame == null || !isFiniteRectangle(maybeGridFrame)) { + return zeroRectangle + } + return maybeGridFrame + }, [gridPath, metadataRef]) + useSnapAnimation({ targetRootCell: targetRootCell, controls: controls, @@ -722,8 +738,34 @@ export const GridControls = controlForStrategyMemoized(({ tar } } - return { x: getCoord('x', 'width'), y: getCoord('y', 'height') } - }, [features, initialShadowFrame, interactionData, shadow, hoveringStart, mouseCanvasPosition]) + // make sure the shadow is displayed only inside the grid container bounds + function wrapCoord(c: number, min: number, max: number, shadowSize: number) { + return Math.min(Math.max(c, min), max - shadowSize) + } + + return { + x: wrapCoord( + getCoord('x', 'width') ?? 0, + gridFrame.x, + gridFrame.x + gridFrame.width, + shadow.globalFrame.width, + ), + y: wrapCoord( + getCoord('y', 'height') ?? 0, + gridFrame.y, + gridFrame.y + gridFrame.height, + shadow.globalFrame.height, + ), + } + }, [ + features, + initialShadowFrame, + interactionData, + shadow, + hoveringStart, + mouseCanvasPosition, + gridFrame, + ]) if (grids.length === 0) { return null