-
Notifications
You must be signed in to change notification settings - Fork 1
/
addPanZoom.js
121 lines (93 loc) · 2.65 KB
/
addPanZoom.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { createListener } from "./utils.js";
export function addPanZoom(el, state) {
const listen = createListener(el);
let mousedown = false;
let scale = 1;
let pointX = 0;
let pointY = 0;
let start = { x: 0, y: 0 };
function setTransform(el) {
el.style.transformOrigin = `${0}px ${0}px`;
el.style.transform =
"translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
}
function updateTransformGroups() {
const transformGroups = document.querySelectorAll(".transform-group");
for (const group of transformGroups) {
setTransform(group);
}
}
function toWorkspaceCoords({ x, y }) {
let newX = (x - pointX) / scale;
let newY = (y - pointY) / scale;
return { x: newX, y: newY };
}
listen("pointerdown", "", (e) => {
if (e.shiftKey || e.button === 2) {
return;
}
mousedown = true;
start = { x: e.offsetX - pointX, y: e.offsetY - pointY };
if (e.detail === 2) {
}
});
listen("pointermove", "", (e) => {
if (!mousedown) return;
if (state.transforming) return;
pointX = e.offsetX - start.x;
pointY = e.offsetY - start.y;
updateTransformGroups();
});
listen("pointerup", "", (evt) => {
mousedown = false;
});
listen(
"wheel",
"",
(e) => {
let xs = (e.offsetX - pointX) / scale;
let ys = (e.offsetY - pointY) / scale;
if (Math.sign(e.deltaY) < 0) scale *= 1.03;
else scale /= 1.03;
pointX = e.offsetX - xs * scale;
pointY = e.offsetY - ys * scale;
Object.keys(state.toolchain.tools).forEach((toolID) => {
let toolTo = state.toolchain.tools[toolID];
if ("onZoom" in toolTo.lifecycle) toolTo.lifecycle.onZoom(scale);
});
updateTransformGroups();
e.preventDefault();
},
{ passive: false }
);
function setPanZoom(pz) {
scale = pz.scale;
pointX = pz.x;
pointY = pz.y;
updateTransformGroups();
}
function setScaleXY(limits) {
const bb = el.getBoundingClientRect();
const xr = limits.x[1] - limits.x[0];
const yr = limits.y[1] - limits.y[0];
const xScalingFactor = bb.width / xr;
const yScalingFactor = bb.height / yr;
const scalingFactor = Math.min(xScalingFactor, yScalingFactor) * 0.9;
scale = scalingFactor;
const center = {
x: ((limits.x[0] + limits.x[1]) / 2) * scalingFactor - bb.width / 2,
y: ((limits.y[0] + limits.y[1]) / 2) * scalingFactor - bb.height / 2,
};
pointX = -center.x;
pointY = -center.y;
updatePanZoom();
}
return {
scale: () => scale,
x: () => pointX,
y: () => pointY,
setScaleXY,
toWorkspaceCoords,
setPanZoom,
};
}