ux(canvas): zoom controls float on the canvas' bottom-right corner
The canvas header runs out of room when the AI chat panel docks on the right — the board selector clipped and the zoom cluster was squeezed out entirely. The −/%/+ cluster now floats on the circuit canvas' bottom-right corner (always free), with stopPropagation so a click never starts a pan.
This commit is contained in:
parent
cd83813a9b
commit
f9a9657b5e
|
|
@ -264,6 +264,18 @@
|
|||
height: 28px;
|
||||
}
|
||||
|
||||
/* Floating variant: pinned to the canvas' bottom-right corner (the header
|
||||
got too tight once the AI chat panel docks on the right). Sits above the
|
||||
canvas layers; dialogs/modals portal to <body> so they stay on top. */
|
||||
.zoom-controls--floating {
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
bottom: 14px;
|
||||
z-index: 60;
|
||||
height: 32px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.zoom-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -2860,65 +2860,9 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
|||
</div>
|
||||
|
||||
<div className="canvas-header-right">
|
||||
{/* Zoom controls */}
|
||||
<div className="zoom-controls">
|
||||
<button
|
||||
className="zoom-btn"
|
||||
onClick={() =>
|
||||
handleWheel({
|
||||
deltaY: 100,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
preventDefault: () => {},
|
||||
} as any)
|
||||
}
|
||||
title={t('editor.canvas.zoomOut')}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
className="zoom-level"
|
||||
onClick={handleResetView}
|
||||
title={t('editor.canvas.resetView')}
|
||||
>
|
||||
{Math.round(zoom * 100)}%
|
||||
</button>
|
||||
<button
|
||||
className="zoom-btn"
|
||||
onClick={() =>
|
||||
handleWheel({
|
||||
deltaY: -100,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
preventDefault: () => {},
|
||||
} as any)
|
||||
}
|
||||
title={t('editor.canvas.zoomIn')}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{/* Zoom moved to a floating cluster on the canvas'
|
||||
bottom-right corner — the header gets too tight when the
|
||||
AI chat panel is docked. */}
|
||||
|
||||
{/* Component count */}
|
||||
<span
|
||||
|
|
@ -3224,6 +3168,73 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
|||
}
|
||||
return null;
|
||||
})()}
|
||||
|
||||
{/* Floating zoom controls — pinned to the canvas' bottom-right
|
||||
corner (they lived in the canvas header, which gets too tight
|
||||
when the AI chat panel is docked; the corner is always free).
|
||||
stopPropagation so a click never starts a canvas pan/selection. */}
|
||||
<div
|
||||
className="zoom-controls zoom-controls--floating"
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<button
|
||||
className="zoom-btn"
|
||||
onClick={() =>
|
||||
handleWheel({
|
||||
deltaY: 100,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
preventDefault: () => {},
|
||||
} as any)
|
||||
}
|
||||
title={t('editor.canvas.zoomOut')}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
className="zoom-level"
|
||||
onClick={handleResetView}
|
||||
title={t('editor.canvas.resetView')}
|
||||
>
|
||||
{Math.round(zoom * 100)}%
|
||||
</button>
|
||||
<button
|
||||
className="zoom-btn"
|
||||
onClick={() =>
|
||||
handleWheel({
|
||||
deltaY: -100,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
preventDefault: () => {},
|
||||
} as any)
|
||||
}
|
||||
title={t('editor.canvas.zoomIn')}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue