From 0d950ff1886de930c1e7fccb14e7f800553df2e4 Mon Sep 17 00:00:00 2001 From: KGFCH2 Date: Thu, 25 Jun 2026 17:31:47 +0530 Subject: [PATCH] feat: add Fit to Screen zoom control utility --- src/components/CenterCanvas.tsx | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/components/CenterCanvas.tsx b/src/components/CenterCanvas.tsx index b975324..dace8b6 100644 --- a/src/components/CenterCanvas.tsx +++ b/src/components/CenterCanvas.tsx @@ -99,6 +99,45 @@ export default function CenterCanvas({ setIsPanning(false); }; + const handleFitToScreen = () => { + if (nodes.length === 0 || !containerRef.current) return; + + let minX = Infinity; + let maxX = -Infinity; + let minY = Infinity; + let maxY = -Infinity; + + nodes.forEach((node) => { + minX = Math.min(minX, node.x); + maxX = Math.max(maxX, node.x + NODE_WIDTH); + minY = Math.min(minY, node.y); + maxY = Math.max(maxY, node.y + NODE_HEIGHT); + }); + + const contentWidth = maxX - minX; + const contentHeight = maxY - minY; + + const containerWidth = containerRef.current.clientWidth; + const containerHeight = containerRef.current.clientHeight; + + const padding = 80; + const scaleX = (containerWidth - padding) / contentWidth; + const scaleY = (containerHeight - padding) / contentHeight; + let newScale = Math.min(scaleX, scaleY); + newScale = Math.min(Math.max(0.4, newScale), 2); + newScale = parseFloat(newScale.toFixed(2)); + + const contentCx = minX + contentWidth / 2; + const contentCy = minY + contentHeight / 2; + + const newPanX = containerWidth / 2 - contentCx * newScale; + const newPanY = containerHeight / 2 - contentCy * newScale; + + setScale(newScale); + setPan({ x: Math.round(newPanX), y: Math.round(newPanY) }); + showToast?.('Fit flowchart to screen', 'info'); + }; + // Wheel zoom listener with passive ref to prevent page scroll React.useEffect(() => { const container = containerRef.current; @@ -748,6 +787,13 @@ export default function CenterCanvas({ > Reset + )}