diff --git a/components/canvas/nodes/ImageNode.tsx b/components/canvas/nodes/ImageNode.tsx index f79927028..45300dd1a 100644 --- a/components/canvas/nodes/ImageNode.tsx +++ b/components/canvas/nodes/ImageNode.tsx @@ -121,6 +121,7 @@ interface BoxCutoutPoint { const BOX_CUTOUT_DEFAULT_PADDING_RATIO = 0.08; const BOX_CUTOUT_MIN_EDGE_PX = 24; +const FLOATING_TOOLBAR_SCALE = 0.8; const clampNumber = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value)); @@ -972,8 +973,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { let rafId: number | null = null; const measure = () => { - const rect = toolbarEl.getBoundingClientRect(); - const next = { width: rect.width, height: rect.height }; + const next = { + width: toolbarEl.offsetWidth, + height: toolbarEl.offsetHeight, + }; setToolbarSize((prev) => Math.abs(prev.width - next.width) < 0.5 && Math.abs(prev.height - next.height) < 0.5 @@ -1028,8 +1031,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { let rafId: number | null = null; const measure = () => { - const rect = toolbarEl.getBoundingClientRect(); - const next = { width: rect.width, height: rect.height }; + const next = { + width: toolbarEl.offsetWidth, + height: toolbarEl.offsetHeight, + }; setBoxCutoutToolbarSize((prev) => Math.abs(prev.width - next.width) < 0.5 && Math.abs(prev.height - next.height) < 0.5 @@ -1729,14 +1734,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { const getToolbarPosition = () => { if (containerRef.current && typeof window !== "undefined") { const rect = containerRef.current.getBoundingClientRect(); - const toolbarScale = 0.8; const toolbarWidth = Math.max( 280, - toolbarSize.width * toolbarScale || 980 + (toolbarSize.width || 980) * FLOATING_TOOLBAR_SCALE ); const toolbarHeight = Math.max( 42, - toolbarSize.height * toolbarScale || 48 + (toolbarSize.height || 60) * FLOATING_TOOLBAR_SCALE ); const titleSafeHeight = 34; const gap = 12; @@ -1751,15 +1755,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { const maxToolbarWidth = Math.max(180, safeRight - safeLeft); const effectiveToolbarWidth = Math.min(toolbarWidth, maxToolbarWidth); - const halfToolbar = effectiveToolbarWidth / 2; - - let left = rect.left + rect.width / 2; + let left = rect.left + rect.width / 2 - effectiveToolbarWidth / 2; if (effectiveToolbarWidth >= maxToolbarWidth - 1) { - left = (safeLeft + safeRight) / 2; + left = safeLeft; } else { left = Math.min( - Math.max(left, safeLeft + halfToolbar), - safeRight - halfToolbar + Math.max(left, safeLeft), + safeRight - effectiveToolbarWidth ); } @@ -1775,14 +1777,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { const getBoxCutoutToolbarPosition = () => { if (containerRef.current && typeof window !== "undefined") { const rect = containerRef.current.getBoundingClientRect(); - const toolbarScale = 0.8; const toolbarWidth = Math.max( 240, - boxCutoutToolbarSize.width * toolbarScale || 460 + (boxCutoutToolbarSize.width || 460) * FLOATING_TOOLBAR_SCALE ); const toolbarHeight = Math.max( 42, - boxCutoutToolbarSize.height * toolbarScale || 48 + (boxCutoutToolbarSize.height || 60) * FLOATING_TOOLBAR_SCALE ); const gap = 14; const { viewportPadding, safeBottom, safeLeft, safeRight, maxTop } = @@ -1796,15 +1797,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { const maxToolbarWidth = Math.max(180, safeRight - safeLeft); const effectiveToolbarWidth = Math.min(toolbarWidth, maxToolbarWidth); - const halfToolbar = effectiveToolbarWidth / 2; - - let left = rect.left + rect.width / 2; + let left = rect.left + rect.width / 2 - effectiveToolbarWidth / 2; if (effectiveToolbarWidth >= maxToolbarWidth - 1) { - left = (safeLeft + safeRight) / 2; + left = safeLeft; } else { left = Math.min( - Math.max(left, safeLeft + halfToolbar), - safeRight - halfToolbar + Math.max(left, safeLeft), + safeRight - effectiveToolbarWidth ); } @@ -3425,10 +3424,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { style={{ top: toolbarPosition.top, left: toolbarPosition.left, - transform: "translateX(-50%) scale(0.8)", - transformOrigin: "top center", + transform: `scale(${FLOATING_TOOLBAR_SCALE})`, + transformOrigin: "top left", pointerEvents: "auto", - maxWidth: `${Math.max(180, Math.floor(toolbarPosition.maxWidth))}px`, + maxWidth: `${Math.max( + 180, + Math.floor(toolbarPosition.maxWidth / FLOATING_TOOLBAR_SCALE) + )}px`, overflowX: "auto", scrollbarWidth: "none", }} @@ -3593,10 +3595,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { style={{ top: boxCutoutToolbarPosition.top, left: boxCutoutToolbarPosition.left, - transform: "translateX(-50%) scale(0.8)", - transformOrigin: "top center", + transform: `scale(${FLOATING_TOOLBAR_SCALE})`, + transformOrigin: "top left", pointerEvents: "auto", - maxWidth: `${Math.max(180, Math.floor(boxCutoutToolbarPosition.maxWidth))}px`, + maxWidth: `${Math.max( + 180, + Math.floor(boxCutoutToolbarPosition.maxWidth / FLOATING_TOOLBAR_SCALE) + )}px`, overflowX: "auto", scrollbarWidth: "none", }}