Zoom buttons

This commit is contained in:
1ilit 2023-09-19 15:49:36 +03:00
parent 5661984992
commit 94df100726
3 changed files with 70 additions and 49 deletions

View File

@ -3,7 +3,12 @@ import Table from "./table";
import { Cardinality, Constraint, ObjectType } from "../data/data";
import Area from "./area";
import Relationship from "./relationship";
import { AreaContext, NoteContext, TableContext } from "../pages/editor";
import {
AreaContext,
NoteContext,
SettingsContext,
TableContext,
} from "../pages/editor";
import Note from "./note";
export default function Canvas(props) {
@ -11,6 +16,7 @@ export default function Canvas(props) {
useContext(TableContext);
const { areas, setAreas } = useContext(AreaContext);
const { notes, setNotes } = useContext(NoteContext);
const { settings, setSettings } = useContext(SettingsContext);
const [dragging, setDragging] = useState([ObjectType.NONE, -1]);
const [linking, setLinking] = useState(false);
const [line, setLine] = useState({
@ -45,7 +51,6 @@ export default function Canvas(props) {
mouseY: 0,
});
const [cursor, setCursor] = useState("default");
const [zoom, setZoom] = useState(1);
const canvas = useRef(null);
@ -54,22 +59,22 @@ export default function Canvas(props) {
if (type === ObjectType.TABLE) {
const table = tables.find((t) => t.id === id);
setOffset({
x: clientX / zoom - table.x,
y: clientY / zoom - table.y,
x: clientX / settings.zoom - table.x,
y: clientY / settings.zoom - table.y,
});
setDragging([ObjectType.TABLE, id]);
} else if (type === ObjectType.AREA) {
const area = areas.find((t) => t.id === id);
setOffset({
x: clientX / zoom - area.x,
y: clientY / zoom - area.y,
x: clientX / settings.zoom - area.x,
y: clientY / settings.zoom - area.y,
});
setDragging([ObjectType.AREA, id]);
} else if (type === ObjectType.NOTE) {
const note = notes.find((t) => t.id === id);
setOffset({
x: clientX / zoom - note.x,
y: clientY / zoom - note.y,
x: clientX / settings.zoom - note.x,
y: clientY / settings.zoom - note.y,
});
setDragging([ObjectType.NOTE, id]);
}
@ -83,16 +88,16 @@ export default function Canvas(props) {
setLine({
...line,
endX: (e.clientX - offsetX) / zoom,
endY: (e.clientY - offsetY) / zoom,
endX: (e.clientX - offsetX) / settings.zoom,
endY: (e.clientY - offsetY) / settings.zoom,
});
} else if (
panning &&
dragging[0] === ObjectType.NONE &&
areaResize.id === -1
) {
const dx = (e.clientX - panOffset.x) / zoom;
const dy = (e.clientY - panOffset.y) / zoom;
const dx = (e.clientX - panOffset.x) / settings.zoom;
const dy = (e.clientY - panOffset.y) / settings.zoom;
setPanOffset({ x: e.clientX, y: e.clientY });
setTables((prev) =>
@ -121,8 +126,8 @@ export default function Canvas(props) {
if (t.id === dragging[1]) {
return {
...t,
x: e.clientX / zoom - offset.x,
y: e.clientY / zoom - offset.y,
x: e.clientX / settings.zoom - offset.x,
y: e.clientY / settings.zoom - offset.y,
};
}
return t;
@ -156,8 +161,8 @@ export default function Canvas(props) {
if (t.id === dragging[1]) {
const updatedArea = {
...t,
x: e.clientX / zoom - offset.x,
y: e.clientY / zoom - offset.y,
x: e.clientX / settings.zoom - offset.x,
y: e.clientY / settings.zoom - offset.y,
};
return updatedArea;
}
@ -170,8 +175,8 @@ export default function Canvas(props) {
if (t.id === dragging[1]) {
return {
...t,
x: e.clientX / zoom - offset.x,
y: e.clientY / zoom - offset.y,
x: e.clientX / settings.zoom - offset.x,
y: e.clientY / settings.zoom - offset.y,
};
}
return t;
@ -184,8 +189,8 @@ export default function Canvas(props) {
let newY = initCoords.y;
let newWidth = initCoords.width;
let newHeight = initCoords.height;
const mouseX = e.clientX / zoom;
const mouseY = e.clientY / zoom;
const mouseX = e.clientX / settings.zoom;
const mouseY = e.clientY / settings.zoom;
setPanning(false);
if (areaResize.dir === "br") {
newWidth = initCoords.width + (mouseX - initCoords.mouseX);
@ -278,9 +283,9 @@ export default function Canvas(props) {
const handleMouseWheel = (e) => {
e.preventDefault();
if (e.deltaY <= 0) {
setZoom((prev) => prev * 1.05);
setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.05 }));
} else {
setZoom((prev) => prev / 1.05);
setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.05 }));
}
};
@ -292,7 +297,7 @@ export default function Canvas(props) {
return () => {
canvasElement.removeEventListener("wheel", handleMouseWheel);
};
}, []);
});
return (
<div className="flex-grow h-full" id="canvas">
@ -332,7 +337,12 @@ export default function Canvas(props) {
height="100%"
fill="url(#pattern-circles)"
></rect>
<g style={{ transform: `scale(${zoom})`, transformOrigin: "0 0" }}>
<g
style={{
transform: `scale(${settings.zoom})`,
transformOrigin: "0 0",
}}
>
{areas.map((a) => (
<Area
key={a.id}
@ -343,7 +353,7 @@ export default function Canvas(props) {
setResize={setAreaResize}
initCoords={initCoords}
setInitCoords={setInitCoords}
zoom={zoom}
zoom={settings.zoom}
></Area>
))}
{tables.map((table) => (

View File

@ -18,7 +18,7 @@ import {
Button,
Divider,
Dropdown,
Form,
InputNumber,
Image,
Modal,
Spin,
@ -72,7 +72,7 @@ export default function ControlPanel(props) {
});
const [data, setData] = useState(null);
const { layout, setLayout } = useContext(LayoutContext);
const { setSettings } = useContext(SettingsContext);
const { settings, setSettings } = useContext(SettingsContext);
const { relationships, tables, setTables, setRelationships } =
useContext(TableContext);
const { notes, setNotes } = useContext(NoteContext);
@ -316,11 +316,13 @@ export default function ControlPanel(props) {
},
"Zoom in": {
children: [],
function: () => {},
function: () =>
setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.2 })),
},
"Zoom out": {
children: [],
function: () => {},
function: () =>
setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.2 })),
},
Fullscreen: {
children: [],
@ -395,35 +397,37 @@ export default function ControlPanel(props) {
<Dropdown.Menu>
<Dropdown.Item>Fit window</Dropdown.Item>
<Dropdown.Divider />
{[
"25%",
"50%",
"75%",
"100%",
"125%",
"150%",
"200%",
"300%",
].map((e, i) => (
<Dropdown.Item key={i}>{e}</Dropdown.Item>
{[0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0].map((e, i) => (
<Dropdown.Item
key={i}
onClick={() => {
setSettings((prev) => ({ ...prev, zoom: e }));
}}
>
{Math.floor(e * 100)}%
</Dropdown.Item>
))}
<Dropdown.Divider />
<Dropdown.Item>
<Form>
<Form.InputNumber
field="zoom"
label="Custom zoom"
placeholder="Zoom"
suffix={<div className="p-1">%</div>}
/>
</Form>
<InputNumber
field="zoom"
label="Custom zoom"
placeholder="Zoom"
suffix={<div className="p-1">%</div>}
onChange={(v) =>
setSettings((prev) => ({
...prev,
zoom: parseFloat(v) * 0.01,
}))
}
/>
</Dropdown.Item>
</Dropdown.Menu>
}
trigger="click"
>
<div className="py-1 px-2 hover:bg-slate-200 rounded flex items-center justify-center">
<div>zoom</div>
<div className="w-[40px]">{Math.floor(settings.zoom * 100)}%</div>
<div>
<IconCaretdown />
</div>
@ -432,12 +436,18 @@ export default function ControlPanel(props) {
<button
className="py-1 px-2 hover:bg-slate-200 rounded text-lg"
title="Zoom in"
onClick={() =>
setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.2 }))
}
>
<i className="fa-solid fa-magnifying-glass-plus"></i>
</button>
<button
className="py-1 px-2 hover:bg-slate-200 rounded text-lg"
title="Zoom out"
onClick={() =>
setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.2 }))
}
>
<i className="fa-solid fa-magnifying-glass-minus"></i>
</button>

View File

@ -39,6 +39,7 @@ export default function Editor(props) {
const [settings, setSettings] = useState({
strictMode: false,
showFieldSummary: true,
zoom: 1,
});
const dragHandler = (e) => {