mirror of
https://github.com/drawdb-io/drawdb.git
synced 2026-02-12 02:00:40 +08:00
Separate zoom and pan from settings
This commit is contained in:
@@ -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() {
|
||||
)}
|
||||
<g
|
||||
style={{
|
||||
transform: `translate(${settings.pan?.x}px, ${settings.pan?.y}px) scale(${settings.zoom})`,
|
||||
transform: `translate(${transform.pan?.x}px, ${transform.pan?.y}px) scale(${transform.zoom})`,
|
||||
transformOrigin: "top left",
|
||||
}}
|
||||
id="diagram"
|
||||
@@ -437,7 +439,7 @@ export default function Canvas() {
|
||||
setResize={setAreaResize}
|
||||
initCoords={initCoords}
|
||||
setInitCoords={setInitCoords}
|
||||
zoom={settings.zoom}
|
||||
zoom={transform.zoom}
|
||||
></Area>
|
||||
))}
|
||||
{relationships.map((e, i) => (
|
||||
|
||||
@@ -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({
|
||||
<Dropdown.Item
|
||||
key={i}
|
||||
onClick={() => {
|
||||
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={<div className="p-1">%</div>}
|
||||
onChange={(v) =>
|
||||
setSettings((prev) => ({
|
||||
setTransform((prev) => ({
|
||||
...prev,
|
||||
zoom: parseFloat(v) * 0.01,
|
||||
}))
|
||||
@@ -2151,7 +2157,9 @@ export default function ControlPanel({
|
||||
trigger="click"
|
||||
>
|
||||
<div className="py-1 px-2 hover-2 rounded flex items-center justify-center">
|
||||
<div className="w-[40px]">{Math.floor(settings.zoom * 100)}%</div>
|
||||
<div className="w-[40px]">
|
||||
{Math.floor(transform.zoom * 100)}%
|
||||
</div>
|
||||
<div>
|
||||
<IconCaretdown />
|
||||
</div>
|
||||
@@ -2161,7 +2169,7 @@ export default function ControlPanel({
|
||||
<button
|
||||
className="py-1 px-2 hover-2 rounded text-lg"
|
||||
onClick={() =>
|
||||
setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.2 }))
|
||||
setTransform((prev) => ({ ...prev, zoom: prev.zoom * 1.2 }))
|
||||
}
|
||||
>
|
||||
<i className="fa-solid fa-magnifying-glass-plus"></i>
|
||||
@@ -2171,7 +2179,7 @@ export default function ControlPanel({
|
||||
<button
|
||||
className="py-1 px-2 hover-2 rounded text-lg"
|
||||
onClick={() =>
|
||||
setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.2 }))
|
||||
setTransform((prev) => ({ ...prev, zoom: prev.zoom / 1.2 }))
|
||||
}
|
||||
>
|
||||
<i className="fa-solid fa-magnifying-glass-minus"></i>
|
||||
|
||||
Reference in New Issue
Block a user