From f3eb6d7c04ebe60f79430da0ce14f2fd59388ee6 Mon Sep 17 00:00:00 2001 From: 1ilit Date: Sat, 9 Mar 2024 20:35:04 +0200 Subject: [PATCH] Separate zoom and pan from settings --- src/components/Canvas.jsx | 52 +++--- src/components/ControlPanel.jsx | 34 ++-- src/context/LayoutContext.jsx | 2 +- src/pages/Editor.jsx | 287 ++++++++++++++++---------------- 4 files changed, 197 insertions(+), 178 deletions(-) diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx index 38108ab..c598c52 100644 --- a/src/components/Canvas.jsx +++ b/src/components/Canvas.jsx @@ -10,6 +10,7 @@ import { TableContext, UndoRedoContext, SelectContext, + TransformContext, } from "../pages/Editor"; import Note from "./Note"; import { Toast } from "@douyinfe/semi-ui"; @@ -19,8 +20,9 @@ export default function Canvas() { useContext(TableContext); const { areas, updateArea } = useContext(AreaContext); const { notes, updateNote } = useContext(NoteContext); - const { settings, setSettings } = useContext(SettingsContext); + const { settings } = useContext(SettingsContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { transform, setTransform } = useContext(TransformContext); const { selectedElement, setSelectedElement } = useContext(SelectContext); const [dragging, setDragging] = useState({ element: ObjectType.NONE, @@ -69,8 +71,8 @@ export default function Canvas() { if (type === ObjectType.TABLE) { const table = tables.find((t) => t.id === id); setOffset({ - x: clientX / settings.zoom - table.x, - y: clientY / settings.zoom - table.y, + x: clientX / transform.zoom - table.x, + y: clientY / transform.zoom - table.y, }); setDragging({ element: ObjectType.TABLE, @@ -81,8 +83,8 @@ export default function Canvas() { } else if (type === ObjectType.AREA) { const area = areas.find((t) => t.id === id); setOffset({ - x: clientX / settings.zoom - area.x, - y: clientY / settings.zoom - area.y, + x: clientX / transform.zoom - area.x, + y: clientY / transform.zoom - area.y, }); setDragging({ element: ObjectType.AREA, @@ -93,8 +95,8 @@ export default function Canvas() { } else if (type === ObjectType.NOTE) { const note = notes.find((t) => t.id === id); setOffset({ - x: clientX / settings.zoom - note.x, - y: clientY / settings.zoom - note.y, + x: clientX / transform.zoom - note.x, + y: clientY / transform.zoom - note.y, }); setDragging({ element: ObjectType.NOTE, @@ -119,8 +121,8 @@ export default function Canvas() { setLine({ ...line, - endX: (e.clientX - offsetX - settings.pan?.x) / settings.zoom, - endY: (e.clientY - offsetY - settings.pan?.y) / settings.zoom, + endX: (e.clientX - offsetX - transform.pan?.x) / transform.zoom, + endY: (e.clientY - offsetY - transform.pan?.y) / transform.zoom, }); } else if ( panning.state && @@ -132,26 +134,26 @@ export default function Canvas() { } const dx = e.clientX - panOffset.x; const dy = e.clientY - panOffset.y; - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, pan: { x: prev.pan?.x + dx, y: prev.pan?.y + dy }, })); setPanOffset({ x: e.clientX, y: e.clientY }); } else if (dragging.element === ObjectType.TABLE && dragging.id >= 0) { - const dx = e.clientX / settings.zoom - offset.x; - const dy = e.clientY / settings.zoom - offset.y; + const dx = e.clientX / transform.zoom - offset.x; + const dy = e.clientY / transform.zoom - offset.y; updateTable(dragging.id, { x: dx, y: dy }, true); } else if ( dragging.element === ObjectType.AREA && dragging.id >= 0 && areaResize.id === -1 ) { - const dx = e.clientX / settings.zoom - offset.x; - const dy = e.clientY / settings.zoom - offset.y; + const dx = e.clientX / transform.zoom - offset.x; + const dy = e.clientY / transform.zoom - offset.y; updateArea(dragging.id, { x: dx, y: dy }); } else if (dragging.element === ObjectType.NOTE && dragging.id >= 0) { - const dx = e.clientX / settings.zoom - offset.x; - const dy = e.clientY / settings.zoom - offset.y; + const dx = e.clientX / transform.zoom - offset.x; + const dy = e.clientY / transform.zoom - offset.y; updateNote(dragging.id, { x: dx, y: dy }); } else if (areaResize.id !== -1) { if (areaResize.dir === "none") return; @@ -160,8 +162,8 @@ export default function Canvas() { let newY = initCoords.y; let newWidth = initCoords.width; let newHeight = initCoords.height; - const mouseX = e.clientX / settings.zoom; - const mouseY = e.clientY / settings.zoom; + const mouseX = e.clientX / transform.zoom; + const mouseY = e.clientY / transform.zoom; setPanning({ state: false, x: 0, y: 0 }); if (areaResize.dir === "br") { newWidth = initCoords.width + (mouseX - initCoords.mouseX); @@ -191,7 +193,7 @@ export default function Canvas() { }; const handleMouseDown = (e) => { - setPanning({ state: true, ...settings.pan }); + setPanning({ state: true, ...transform.pan }); setPanOffset({ x: e.clientX, y: e.clientY }); setCursor("grabbing"); }; @@ -228,7 +230,7 @@ export default function Canvas() { }; const didPan = () => - !(settings.pan?.x === panning.x && settings.pan?.y === panning.y); + !(transform.pan?.x === panning.x && transform.pan?.y === panning.y); const getMoveInfo = () => { switch (dragging.element) { @@ -280,8 +282,8 @@ export default function Canvas() { { action: Action.PAN, undo: { x: panning.x, y: panning.y }, - redo: settings.pan, - message: `Move diagram to (${settings.pan?.x}, ${settings.pan?.y})`, + redo: transform.pan, + message: `Move diagram to (${transform.pan?.x}, ${transform.pan?.y})`, }, ]); setRedoStack([]); @@ -359,7 +361,7 @@ export default function Canvas() { const handleMouseWheel = (e) => { e.preventDefault(); - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, zoom: e.deltaY <= 0 ? prev.zoom * 1.05 : prev.zoom / 1.05, })); @@ -422,7 +424,7 @@ export default function Canvas() { )} ))} {relationships.map((e, i) => ( diff --git a/src/components/ControlPanel.jsx b/src/components/ControlPanel.jsx index 5db1939..37f0a16 100644 --- a/src/components/ControlPanel.jsx +++ b/src/components/ControlPanel.jsx @@ -51,6 +51,7 @@ import { import { AreaContext, NoteContext, + TransformContext, SelectContext, SettingsContext, StateContext, @@ -122,7 +123,7 @@ export default function ControlPanel({ }); const [data, setData] = useState(null); const { state, setState } = useContext(StateContext); - const {layout, setLayout} = useLayout(); + const { layout, setLayout } = useLayout(); const { settings, setSettings } = useContext(SettingsContext); const { relationships, @@ -146,6 +147,7 @@ export default function ControlPanel({ useContext(UndoRedoContext); const { selectedElement, setSelectedElement } = useContext(SelectContext); const { tab, setTab } = useContext(TabContext); + const { transform, setTransform } = useContext(TransformContext); const invertLayout = (component) => setLayout((prev) => ({ ...prev, [component]: !prev[component] })); @@ -334,7 +336,7 @@ export default function ControlPanel({ } setRedoStack((prev) => [...prev, a]); } else if (a.action === Action.PAN) { - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, pan: a.undo, })); @@ -515,7 +517,7 @@ export default function ControlPanel({ } setUndoStack((prev) => [...prev, a]); } else if (a.action === Action.PAN) { - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, pan: a.redo, })); @@ -527,9 +529,9 @@ export default function ControlPanel({ const viewGrid = () => setSettings((prev) => ({ ...prev, showGrid: !prev.showGrid })); const zoomIn = () => - setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.2 })); + setTransform((prev) => ({ ...prev, zoom: prev.zoom * 1.2 })); const zoomOut = () => - setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.2 })); + setTransform((prev) => ({ ...prev, zoom: prev.zoom / 1.2 })); const viewStrictMode = () => { setSettings((prev) => ({ ...prev, strictMode: !prev.strictMode })); Toast.success(`Stict mode is ${settings.strictMode ? "on" : "off"}.`); @@ -557,7 +559,7 @@ export default function ControlPanel({ }); }; const resetView = () => - setSettings((prev) => ({ ...prev, zoom: 1, pan: { x: 0, y: 0 } })); + setTransform((prev) => ({ ...prev, zoom: 1, pan: { x: 0, y: 0 } })); const fitWindow = () => { const diagram = document.getElementById("diagram").getBoundingClientRect(); const canvas = document.getElementById("canvas").getBoundingClientRect(); @@ -572,7 +574,7 @@ export default function ControlPanel({ const translateX = canvas.left; const translateY = canvas.top; - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, zoom: scale - 0.01, pan: { x: translateX, y: translateY }, @@ -756,6 +758,10 @@ export default function ControlPanel({ setRelationships(diagram.references); setAreas(diagram.areas); setNotes(diagram.notes); + setTransform({ + pan: diagram.pan, + zoom: diagram.zoom, + }); setUndoStack([]); setRedoStack([]); window.name = `d ${diagram.id}`; @@ -1609,7 +1615,7 @@ export default function ControlPanel({ } case MODAL.IMPORT: if (error.type !== STATUS.ERROR) { - setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } })); + setTransform((prev) => ({ ...prev, pan: { x: 0, y: 0 } })); overwriteDiagram(); setData(null); setVisible(MODAL.NONE); @@ -2125,7 +2131,7 @@ export default function ControlPanel({ { - setSettings((prev) => ({ ...prev, zoom: e })); + setTransform((prev) => ({ ...prev, zoom: e })); }} > {Math.floor(e * 100)}% @@ -2139,7 +2145,7 @@ export default function ControlPanel({ placeholder="Zoom" suffix={
%
} onChange={(v) => - setSettings((prev) => ({ + setTransform((prev) => ({ ...prev, zoom: parseFloat(v) * 0.01, })) @@ -2151,7 +2157,9 @@ export default function ControlPanel({ trigger="click" >
-
{Math.floor(settings.zoom * 100)}%
+
+ {Math.floor(transform.zoom * 100)}% +
@@ -2161,7 +2169,7 @@ export default function ControlPanel({ - -
- {parseInt(settings.zoom * 100)}% -
- - -
- - - - + +
+ +
setResize(false)} + onMouseMove={dragHandler} + > + {layout.sidebar && ( + )} +
+ + {!( + layout.sidebar || + layout.toolbar || + layout.header + ) && ( +
+
+ + +
+ {parseInt(transform.zoom * 100)}% +
+ + +
+ + + +
+ )} +
- -
- - - - - - - - + + + + + + + + + + ); }