diff --git a/apps/builder/app/builder/features/workspace/canvas-iframe.tsx b/apps/builder/app/builder/features/workspace/canvas-iframe.tsx index 3b0b770b937e..1b140b6ef24f 100644 --- a/apps/builder/app/builder/features/workspace/canvas-iframe.tsx +++ b/apps/builder/app/builder/features/workspace/canvas-iframe.tsx @@ -45,7 +45,15 @@ const CanvasRectUpdater = ({ } const rect = iframeRef.current.getBoundingClientRect(); - $canvasRect.set(rect); + + $canvasRect.set( + new DOMRect( + Math.round(rect.x), + Math.round(rect.y), + Math.round(rect.width), + Math.round(rect.height) + ) + ); }; setUpdateCallback(() => task); diff --git a/apps/builder/app/builder/features/workspace/canvas-tools/canvas-tools.tsx b/apps/builder/app/builder/features/workspace/canvas-tools/canvas-tools.tsx index 33762b22af9a..f855015c6141 100644 --- a/apps/builder/app/builder/features/workspace/canvas-tools/canvas-tools.tsx +++ b/apps/builder/app/builder/features/workspace/canvas-tools/canvas-tools.tsx @@ -17,7 +17,7 @@ import { Label } from "./outline/label"; import { Outline } from "./outline/outline"; import { useSubscribeDragAndDropState } from "./use-subscribe-drag-drop-state"; import { applyScale } from "./outline"; -import { $scale } from "~/builder/shared/nano-states"; +import { $clampingRect, $scale } from "~/builder/shared/nano-states"; import { BlockChildHoveredInstanceOutline } from "./outline/block-instance-outline"; const containerStyle = css({ @@ -41,11 +41,16 @@ export const CanvasTools = () => { const dragAndDropState = useStore($dragAndDropState); const instances = useStore($instances); const scale = useStore($scale); + const clampingRect = useStore($clampingRect); if (!canvasToolsVisible) { return; } + if (clampingRect === undefined) { + return; + } + if (dragAndDropState.isDragging) { if (dragAndDropState.placementIndicator === undefined) { return; @@ -59,7 +64,7 @@ export const CanvasTools = () => { return dropTargetInstance ? (
- + {placementIndicator !== undefined && ( diff --git a/apps/builder/app/builder/features/workspace/canvas-tools/outline/apply-scale.ts b/apps/builder/app/builder/features/workspace/canvas-tools/outline/apply-scale.ts index 6f11188a161f..10ddbcbf4743 100644 --- a/apps/builder/app/builder/features/workspace/canvas-tools/outline/apply-scale.ts +++ b/apps/builder/app/builder/features/workspace/canvas-tools/outline/apply-scale.ts @@ -4,9 +4,9 @@ export const applyScale = (rect: Rect, scale: number = 1) => { // Calculate in the "scale" that is applied to the canvas const scaleFactor = scale / 100; return { - top: rect.top * scaleFactor, - left: rect.left * scaleFactor, - width: rect.width * scaleFactor, - height: rect.height * scaleFactor, + top: Math.round(rect.top * scaleFactor), + left: Math.round(rect.left * scaleFactor), + width: Math.round(rect.width * scaleFactor), + height: Math.round(rect.height * scaleFactor), }; }; diff --git a/apps/builder/app/builder/features/workspace/canvas-tools/outline/block-instance-outline.tsx b/apps/builder/app/builder/features/workspace/canvas-tools/outline/block-instance-outline.tsx index 5164d5f65379..aca03db013c0 100644 --- a/apps/builder/app/builder/features/workspace/canvas-tools/outline/block-instance-outline.tsx +++ b/apps/builder/app/builder/features/workspace/canvas-tools/outline/block-instance-outline.tsx @@ -30,7 +30,7 @@ import { } from "@webstudio-is/design-system"; import { Outline } from "./outline"; import { applyScale } from "./apply-scale"; -import { $scale } from "~/builder/shared/nano-states"; +import { $clampingRect, $scale } from "~/builder/shared/nano-states"; import { PlusIcon, TrashIcon } from "@webstudio-is/icons"; import { BoxIcon } from "@webstudio-is/icons/svg"; import { useRef, useState } from "react"; @@ -342,6 +342,7 @@ export const BlockChildHoveredInstanceOutline = () => { const isContentMode = useStore($isContentMode); const modifierKeys = useStore($modifierKeys); const instances = useStore($instances); + const clampingRect = useStore($clampingRect); const timeoutRef = useRef>( undefined @@ -366,6 +367,10 @@ export const BlockChildHoveredInstanceOutline = () => { return; } + if (clampingRect === undefined) { + return; + } + const blockInstanceSelector = findBlockSelector(outline.selector, instances); if (blockInstanceSelector === undefined) { @@ -412,7 +417,7 @@ export const BlockChildHoveredInstanceOutline = () => { ); return ( - +
{ const scale = useStore($scale); const instanceRect = useStore($collaborativeInstanceRect); const ephemeralStyles = useStore($ephemeralStyles); + const clampingRect = useStore($clampingRect); - if (instanceRect === undefined || ephemeralStyles.length !== 0) { + if ( + instanceRect === undefined || + ephemeralStyles.length !== 0 || + clampingRect === undefined + ) { return; } const rect = applyScale(instanceRect, scale); - return ; + return ( + + ); }; diff --git a/apps/builder/app/builder/features/workspace/canvas-tools/outline/hovered-instance-outline.tsx b/apps/builder/app/builder/features/workspace/canvas-tools/outline/hovered-instance-outline.tsx index 804463a27a3c..34dece26756e 100644 --- a/apps/builder/app/builder/features/workspace/canvas-tools/outline/hovered-instance-outline.tsx +++ b/apps/builder/app/builder/features/workspace/canvas-tools/outline/hovered-instance-outline.tsx @@ -10,7 +10,7 @@ import { import { Outline } from "./outline"; import { Label } from "./label"; import { applyScale } from "./apply-scale"; -import { $scale } from "~/builder/shared/nano-states"; +import { $clampingRect, $scale } from "~/builder/shared/nano-states"; import { findClosestSlot } from "~/shared/instance-utils"; import { shallowEqual } from "shallow-equal"; import type { InstanceSelector } from "~/shared/tree-utils"; @@ -31,8 +31,13 @@ export const HoveredInstanceOutline = () => { const scale = useStore($scale); const textEditingInstanceSelector = useStore($textEditingInstanceSelector); const isContentMode = useStore($isContentMode); + const clampingRect = useStore($clampingRect); - if (outline === undefined || hoveredInstanceSelector === undefined) { + if ( + outline === undefined || + hoveredInstanceSelector === undefined || + clampingRect === undefined + ) { return; } @@ -58,7 +63,7 @@ export const HoveredInstanceOutline = () => { const rect = applyScale(outline.rect, scale); return ( - +