@lancercomet/zoom-pan 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs DELETED
@@ -1,812 +0,0 @@
1
- const t = async (t2, s2) => new Promise((i2, h2) => {
2
- const e2 = new Image();
3
- "string" == typeof t2 ? (void 0 !== s2 && (e2.crossOrigin = s2), e2.src = t2) : e2.src = URL.createObjectURL(t2), e2.onload = () => {
4
- i2(e2);
5
- }, e2.onerror = () => {
6
- h2(new Error("Image load failed"));
7
- };
8
- }), s = (t2, s2, i2) => Math.min(Math.max(t2, s2), i2);
9
- class i {
10
- canvas;
11
- context;
12
- contentCanvas;
13
- contentContext;
14
- topScreenCanvas;
15
- topScreenContext;
16
- t;
17
- i;
18
- h;
19
- o = [];
20
- l = /* @__PURE__ */ new Map();
21
- u = false;
22
- M = false;
23
- m;
24
- p = true;
25
- _ = 0;
26
- v = performance.now();
27
- L = 0;
28
- R = 0;
29
- S = 0;
30
- C = 0;
31
- A = Math.log(1);
32
- T = Math.log(1);
33
- LOG_MIN;
34
- LOG_MAX;
35
- P = /* @__PURE__ */ new Set();
36
- B = /* @__PURE__ */ new Set();
37
- I = /* @__PURE__ */ new Set();
38
- get zoom() {
39
- return Math.exp(this.A);
40
- }
41
- get minZoom() {
42
- return this.i.minZoom;
43
- }
44
- get maxZoom() {
45
- return this.i.maxZoom;
46
- }
47
- D = Math.max(1, window.devicePixelRatio || 1);
48
- get dpr() {
49
- return this.D;
50
- }
51
- use(t2) {
52
- return this.l.has(t2.name) || (this.l.set(t2.name, t2), t2.install(this)), t2;
53
- }
54
- unuse(t2) {
55
- const s2 = this.l.get(t2);
56
- s2 && (s2.destroy(), this.l.delete(t2));
57
- }
58
- getPlugin(t2) {
59
- return this.l.get(t2);
60
- }
61
- onUpdate(t2) {
62
- this.P.add(t2);
63
- }
64
- offUpdate(t2) {
65
- this.P.delete(t2);
66
- }
67
- onBeforeRender(t2) {
68
- this.B.add(t2);
69
- }
70
- offBeforeRender(t2) {
71
- this.B.delete(t2);
72
- }
73
- onAfterRender(t2) {
74
- this.I.add(t2);
75
- }
76
- offAfterRender(t2) {
77
- this.I.delete(t2);
78
- }
79
- requestRender() {
80
- this.p = true;
81
- }
82
- F(t2) {
83
- return s(t2, this.LOG_MIN, this.LOG_MAX);
84
- }
85
- k(t2, s2, i2) {
86
- Number.isFinite(i2) && (this.S = t2, this.C = s2, this.T = this.F(i2), this.p = true);
87
- }
88
- zoomToAtScreen(t2, s2, i2) {
89
- this.k(t2, s2, Math.log(i2));
90
- }
91
- zoomToAtScreenRaw(t2, i2, h2) {
92
- if (!Number.isFinite(h2)) return;
93
- const e2 = Math.max(1e-8, this.i.minZoom), n2 = this.i.maxZoom, r2 = s(h2, e2, n2), o2 = Math.exp(this.A), a2 = r2;
94
- if (!Number.isFinite(o2) || o2 <= 0) return;
95
- if (Math.abs(a2 - o2) < 1e-12) return;
96
- const c2 = Math.log(r2);
97
- this.A = c2, this.T = c2;
98
- const l2 = a2 / o2;
99
- this.L = t2 - (t2 - this.L) * l2, this.R = i2 - (i2 - this.R) * l2, this.p = true;
100
- }
101
- zoomToAtWorld(t2, s2, i2) {
102
- const { x: h2, y: e2 } = this.toScreen(t2, s2);
103
- this.zoomToAtScreen(h2, e2, i2);
104
- }
105
- zoomByFactorAtScreen(t2, s2, i2) {
106
- if (i2 <= 0 || !Number.isFinite(i2)) return;
107
- const h2 = Math.log(i2);
108
- this.k(t2, s2, this.T + h2);
109
- }
110
- zoomByLogAtScreen(t2, s2, i2) {
111
- this.k(t2, s2, this.T + i2);
112
- }
113
- zoomByFactorAtWorld(t2, s2, i2) {
114
- const { x: h2, y: e2 } = this.toScreen(t2, s2);
115
- this.zoomByFactorAtScreen(h2, e2, i2);
116
- }
117
- zoomInAtCenter() {
118
- const t2 = this.canvas.getBoundingClientRect(), s2 = t2.width / 2, i2 = t2.height / 2;
119
- this.zoomByFactorAtScreen(s2, i2, 1.2);
120
- }
121
- zoomOutAtCenter() {
122
- const t2 = this.canvas.getBoundingClientRect(), s2 = t2.width / 2, i2 = t2.height / 2;
123
- this.zoomByFactorAtScreen(s2, i2, 1 / 1.2);
124
- }
125
- panBy(t2, s2) {
126
- this.L += t2, this.R += s2, this.p = true;
127
- }
128
- setPan(t2, s2) {
129
- this.L = t2, this.R = s2, this.p = true;
130
- }
131
- setTransform(t2, i2, h2) {
132
- const e2 = s(t2, this.i.minZoom, this.i.maxZoom);
133
- this.A = Math.log(e2), this.T = this.A, this.L = i2, this.R = h2, this.p = true;
134
- }
135
- Z(t2, s2) {
136
- t2.width === s2.width && t2.height === s2.height || (t2.width = s2.width, t2.height = s2.height);
137
- }
138
- U() {
139
- if (this.M) return void (this._ = requestAnimationFrame(() => this.U()));
140
- const t2 = performance.now(), s2 = Math.max(1, t2 - this.v);
141
- this.v = t2;
142
- const { approachKZoom: i2 } = this.i, h2 = Math.exp(this.A), e2 = this.T - this.A, n2 = Math.abs(e2) > 1e-6;
143
- if (n2) {
144
- const t3 = 1 - Math.exp(-i2 * s2);
145
- this.A += e2 * t3;
146
- }
147
- const r2 = Math.exp(this.A);
148
- if (r2 !== h2) {
149
- const t3 = this.S, s3 = this.C, i3 = r2 / h2;
150
- this.L = t3 - (t3 - this.L) * i3, this.R = s3 - (s3 - this.R) * i3;
151
- }
152
- if (this.u) {
153
- const t3 = 1 - Math.exp(-this.i.approachKPan * s2);
154
- this.L += (0 - this.L) * t3, this.R += (0 - this.R) * t3;
155
- const i3 = Math.abs(this.A) < 1e-3 && Math.abs(this.T) < 1e-6, h3 = Math.abs(this.L) < 0.5 && Math.abs(this.R) < 0.5;
156
- i3 && h3 && (this.A = 0, this.T = 0, this.L = 0, this.R = 0, this.u = false);
157
- }
158
- for (const t3 of this.P) t3(s2);
159
- if (!(this.p || n2 || this.u)) return void (this._ = requestAnimationFrame(() => this.U()));
160
- this.p = false;
161
- const o2 = this.contentCanvas, a2 = this.contentContext, c2 = this.topScreenCanvas, l2 = this.topScreenContext, u2 = this.canvas, d2 = this.context;
162
- this.Z(o2, u2), this.Z(c2, u2), a2.setTransform(1, 0, 0, 1, 0, 0), l2.setTransform(1, 0, 0, 1, 0, 0), d2.setTransform(1, 0, 0, 1, 0, 0);
163
- const f2 = this.i.background;
164
- "string" == typeof f2 && "" !== f2.trim() && "transparent" !== f2.toLowerCase() ? (d2.fillStyle = f2, d2.fillRect(0, 0, u2.width, u2.height)) : d2.clearRect(0, 0, u2.width, u2.height), a2.clearRect(0, 0, o2.width, o2.height), l2.clearRect(0, 0, c2.width, c2.height), a2.setTransform(this.D * r2, 0, 0, this.D * r2, this.D * this.L, this.D * this.R);
165
- for (const t3 of this.B) t3(a2);
166
- this.t(this);
167
- for (const t3 of this.I) t3(a2);
168
- d2.drawImage(o2, 0, 0), d2.drawImage(c2, 0, 0), this._ = requestAnimationFrame(() => this.U());
169
- }
170
- applyWorldTransform(t2) {
171
- const s2 = Math.exp(this.A);
172
- t2.setTransform(this.D * s2, 0, 0, this.D * s2, this.D * this.L, this.D * this.R);
173
- }
174
- applyScreenTransform(t2) {
175
- t2.setTransform(this.D, 0, 0, this.D, 0, 0);
176
- }
177
- getPixelColorAtScreen(t2, s2) {
178
- const i2 = Math.floor(t2 * this.D), h2 = Math.floor(s2 * this.D);
179
- if (i2 < 0 || h2 < 0 || i2 >= this.canvas.width || h2 >= this.canvas.height) return { r: 0, g: 0, b: 0, a: 0, rgba: "rgba(0,0,0,0)", hex: "#000000" };
180
- const e2 = this.contentContext.getImageData(i2, h2, 1, 1).data, n2 = e2[0], r2 = e2[1], o2 = e2[2], a2 = e2[3] / 255, c2 = (t3) => t3.toString(16).padStart(2, "0"), l2 = `#${c2(n2)}${c2(r2)}${c2(o2)}`;
181
- return { r: n2, g: r2, b: o2, a: a2, rgba: `rgba(${n2},${r2},${o2},${a2.toFixed(3)})`, hex: l2 };
182
- }
183
- getPixelColorAtWorld(t2, s2) {
184
- const { x: i2, y: h2 } = this.toScreen(t2, s2);
185
- return this.getPixelColorAtScreen(i2, h2);
186
- }
187
- registerLayerManager(t2) {
188
- t2 && (this.o.includes(t2) || (this.o.push(t2), this.p = true));
189
- }
190
- unregisterLayerManager(t2) {
191
- const s2 = this.o.indexOf(t2);
192
- s2 >= 0 && (this.o.splice(s2, 1), this.p = true);
193
- }
194
- getLayerManagers() {
195
- return [...this.o];
196
- }
197
- resetSmooth() {
198
- this.u = true, this.T = 0, this.p = true;
199
- }
200
- resetInstant() {
201
- this.A = 0, this.T = 0, this.L = 0, this.R = 0, this.p = true;
202
- }
203
- toWorld(t2, s2) {
204
- const i2 = Math.exp(this.A);
205
- return { wx: (t2 - this.L) / i2, wy: (s2 - this.R) / i2 };
206
- }
207
- toScreen(t2, s2) {
208
- const i2 = Math.exp(this.A);
209
- return { x: t2 * i2 + this.L, y: s2 * i2 + this.R };
210
- }
211
- getTransform() {
212
- return { zoom: Math.exp(this.A), tx: this.L, ty: this.R };
213
- }
214
- getViewportBounds() {
215
- const t2 = Math.exp(this.A), s2 = this.canvas.width / this.D, i2 = this.canvas.height / this.D, h2 = -this.L / t2, e2 = -this.R / t2, n2 = (s2 - this.L) / t2, r2 = (i2 - this.R) / t2;
216
- return { left: h2, top: e2, right: n2, bottom: r2, width: n2 - h2, height: r2 - e2 };
217
- }
218
- setZoomRange(t2, s2) {
219
- this.i.minZoom = t2, this.i.maxZoom = s2, this.LOG_MIN = Math.log(t2), this.LOG_MAX = Math.log(s2), this.T = Math.min(this.LOG_MAX, Math.max(this.LOG_MIN, this.T));
220
- }
221
- resizeToParent() {
222
- this.M = true;
223
- const t2 = (this.canvas.parentElement || this.canvas).getBoundingClientRect();
224
- this.D = Math.max(1, window.devicePixelRatio || 1);
225
- const s2 = Math.max(1, Math.round(t2.width)), i2 = Math.max(1, Math.round(t2.height));
226
- this.canvas.width = Math.round(s2 * this.D), this.canvas.height = Math.round(i2 * this.D), this.canvas.style.width = `${s2}px`, this.canvas.style.height = `${i2}px`, this.Z(this.contentCanvas, this.canvas), this.Z(this.topScreenCanvas, this.canvas), clearTimeout(this.m), this.m = window.setTimeout(() => {
227
- this.M = false;
228
- }, 50);
229
- }
230
- destroy() {
231
- cancelAnimationFrame(this._);
232
- for (const t2 of this.l.values()) t2.destroy();
233
- this.l.clear(), this.h && this.h.disconnect(), this.o = [], this.P.clear(), this.B.clear(), this.I.clear();
234
- }
235
- constructor(t2, s2, i2) {
236
- const h2 = t2.getContext("2d", { willReadFrequently: true, alpha: true });
237
- if (!h2) throw new Error("2D context not available");
238
- this.canvas = t2, this.context = h2, this.t = s2, this.contentCanvas = document.createElement("canvas"), this.contentCanvas.width = t2.width, this.contentCanvas.height = t2.height, this.contentContext = this.contentCanvas.getContext("2d", { alpha: true, willReadFrequently: true }), this.topScreenCanvas = document.createElement("canvas"), this.topScreenCanvas.width = t2.width, this.topScreenCanvas.height = t2.height, this.topScreenContext = this.topScreenCanvas.getContext("2d", { alpha: true }), this.i = { minZoom: 0.5, maxZoom: 10, approachKZoom: 0.022, approachKPan: 0.022, autoResize: true, background: "#fff", ...i2 }, this.LOG_MIN = Math.log(this.i.minZoom), this.LOG_MAX = Math.log(this.i.maxZoom), this.i.autoResize && (this.h = new ResizeObserver(() => this.resizeToParent()), this.h.observe(this.canvas.parentElement || this.canvas)), this.resizeToParent(), this.v = performance.now(), this._ = requestAnimationFrame(() => this.U());
239
- }
240
- }
241
- let h = 0;
242
- class e {
243
- id;
244
- type;
245
- name;
246
- space = "world";
247
- visible = true;
248
- opacity = 1;
249
- blend = "source-over";
250
- constructor(t2, s2, i2 = "world") {
251
- this.name = t2, this.id = `layer_${s2}_${++h}`, this.type = s2, this.space = i2;
252
- }
253
- }
254
- class n extends e {
255
- W;
256
- canvas;
257
- context;
258
- x = 0;
259
- y = 0;
260
- scale = 1;
261
- rotation = 0;
262
- anchor = "topLeft";
263
- $ = false;
264
- q = 0;
265
- O = 0;
266
- beginStroke(t2, s2) {
267
- const { lx: i2, ly: h2 } = this.toLocalPoint(t2, s2);
268
- this.q = i2, this.O = h2, this.$ = true;
269
- }
270
- stroke(t2, s2, i2, h2, e2 = 1, n2 = "brush") {
271
- if (!this.$) return;
272
- const { lx: r2, ly: o2 } = this.toLocalPoint(t2, s2);
273
- this.context.beginPath(), this.context.moveTo(this.q, this.O), this.context.lineTo(r2, o2), "eraser" === n2 ? (this.context.globalCompositeOperation = "destination-out", this.context.strokeStyle = "rgba(0, 0, 0, 1)") : (this.context.globalCompositeOperation = "source-over", this.context.strokeStyle = i2), this.context.lineWidth = h2 * e2, this.context.lineCap = "round", this.context.lineJoin = "round", this.context.stroke(), this.context.closePath(), this.q = r2, this.O = o2;
274
- }
275
- endStroke() {
276
- this.$ = false;
277
- }
278
- isDrawing() {
279
- return this.$;
280
- }
281
- captureSnapshot(t2) {
282
- try {
283
- if (t2) {
284
- const { x: s2, y: i2, width: h2, height: e2 } = t2, n2 = Math.max(0, Math.floor(s2)), r2 = Math.max(0, Math.floor(i2)), o2 = Math.min(this.canvas.width - n2, Math.ceil(h2)), a2 = Math.min(this.canvas.height - r2, Math.ceil(e2));
285
- return o2 <= 0 || a2 <= 0 ? null : this.context.getImageData(n2, r2, o2, a2);
286
- }
287
- return this.context.getImageData(0, 0, this.canvas.width, this.canvas.height);
288
- } catch {
289
- return null;
290
- }
291
- }
292
- restoreSnapshot(t2, s2) {
293
- const i2 = s2?.x ?? 0, h2 = s2?.y ?? 0;
294
- this.context.putImageData(t2, i2, h2);
295
- }
296
- clearRegion(t2) {
297
- t2 ? this.context.clearRect(t2.x, t2.y, t2.width, t2.height) : this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
298
- }
299
- requestRedraw() {
300
- this.W?.(this.context, this.canvas);
301
- }
302
- drawImage(t2, s2, i2, h2, e2) {
303
- this.context.drawImage(t2, s2, i2, h2 ?? t2.width, e2 ?? t2.height);
304
- }
305
- hitTest(t2, s2) {
306
- const { lx: i2, ly: h2 } = this.toLocalPoint(t2, s2);
307
- return i2 >= 0 && i2 <= this.canvas.width && h2 >= 0 && h2 <= this.canvas.height;
308
- }
309
- toLocalPoint(t2, s2) {
310
- const i2 = t2 - this.x, h2 = s2 - this.y, e2 = Math.cos(-this.rotation), n2 = Math.sin(-this.rotation), r2 = i2 * n2 + h2 * e2, o2 = (i2 * e2 - h2 * n2) / this.scale, a2 = r2 / this.scale;
311
- return { lx: o2 + ("center" === this.anchor ? this.canvas.width / 2 : 0), ly: a2 + ("center" === this.anchor ? this.canvas.height / 2 : 0) };
312
- }
313
- render(t2, s2) {
314
- if (!this.visible) return;
315
- const i2 = this.canvas.width * this.scale, h2 = this.canvas.height * this.scale, e2 = "center" === this.anchor ? -i2 / 2 : 0, n2 = "center" === this.anchor ? -h2 / 2 : 0;
316
- t2.save(), t2.globalAlpha = this.opacity, t2.globalCompositeOperation = this.blend, t2.translate(this.x, this.y), t2.rotate(this.rotation), t2.drawImage(this.canvas, e2, n2, i2, h2), t2.restore();
317
- }
318
- cropTo(t2) {
319
- const s2 = Math.max(1, Math.floor(t2.width)), i2 = Math.max(1, Math.floor(t2.height));
320
- if (s2 === this.canvas.width && i2 === this.canvas.height) return;
321
- const h2 = this.N(), e2 = Math.min(h2.width, s2), n2 = Math.min(h2.height, i2);
322
- this.V(s2, i2), e2 > 0 && n2 > 0 && this.context.drawImage(h2, 0, 0, e2, n2, 0, 0, e2, n2);
323
- }
324
- resizeTo(t2) {
325
- const s2 = Math.max(1, Math.floor(t2.width)), i2 = Math.max(1, Math.floor(t2.height));
326
- if (s2 === this.canvas.width && i2 === this.canvas.height) return;
327
- const h2 = this.N();
328
- this.V(s2, i2), h2.width > 0 && h2.height > 0 && this.context.drawImage(h2, 0, 0, h2.width, h2.height, 0, 0, s2, i2);
329
- }
330
- N() {
331
- const t2 = document.createElement("canvas");
332
- if (t2.width = this.canvas.width, t2.height = this.canvas.height, 0 === t2.width || 0 === t2.height) return t2;
333
- const s2 = t2.getContext("2d");
334
- if (!s2) throw new Error("Offscreen 2D context unavailable");
335
- return s2.drawImage(this.canvas, 0, 0), t2;
336
- }
337
- V(t2, s2) {
338
- this.canvas.width = t2, this.canvas.height = s2, this.context.setTransform(1, 0, 0, 1, 0, 0), this.context.clearRect(0, 0, t2, s2);
339
- }
340
- destroy() {
341
- this.canvas.width = 0, this.canvas.height = 0;
342
- }
343
- constructor(t2) {
344
- super(t2.name || "", "canvas", t2.space ?? "world"), this.canvas = document.createElement("canvas"), this.canvas.width = t2.width, this.canvas.height = t2.height;
345
- const s2 = this.canvas.getContext("2d", { willReadFrequently: true });
346
- if (!s2) throw new Error("Offscreen 2D context unavailable");
347
- this.context = s2, this.x = t2.x || 0, this.y = t2.y || 0, this.scale = t2.scale ?? 1, this.rotation = t2.rotation || 0, t2.anchor && (this.anchor = t2.anchor), this.W = t2.redraw, this.W && this.W(this.context, this.canvas);
348
- }
349
- }
350
- class r extends n {
351
- #t = null;
352
- static async fromImage(s2) {
353
- const i2 = await t(s2.src, s2.crossOrigin), h2 = s2.width ?? i2.naturalWidth, e2 = s2.height ?? i2.naturalHeight, n2 = new r({ name: s2.name, space: s2.space ?? "world", x: s2.x ?? 0, y: s2.y ?? 0, scale: s2.scale ?? 1, rotation: s2.rotation ?? 0, anchor: s2.anchor ?? "topLeft", width: h2, height: e2 });
354
- return n2.context.clearRect(0, 0, n2.canvas.width, n2.canvas.height), n2.context.drawImage(i2, 0, 0, h2, e2), "string" != typeof s2.src && (n2.#t = i2.src.startsWith("blob:") ? i2.src : null), n2;
355
- }
356
- async setSource(s2, i2) {
357
- const h2 = await t(s2, i2);
358
- if (this.canvas.width = h2.naturalWidth, this.canvas.height = h2.naturalHeight, this.context.setTransform(1, 0, 0, 1, 0, 0), this.context.clearRect(0, 0, this.canvas.width, this.canvas.height), this.context.drawImage(h2, 0, 0), this.#t) {
359
- try {
360
- URL.revokeObjectURL(this.#t);
361
- } catch {
362
- }
363
- this.#t = null;
364
- }
365
- "string" != typeof s2 && (this.#t = h2.src.startsWith("blob:") ? h2.src : null);
366
- }
367
- paint(t2) {
368
- t2(this.context, this.canvas);
369
- }
370
- getImageData(t2 = 0, s2 = 0, i2 = this.canvas.width, h2 = this.canvas.height) {
371
- return this.context.getImageData(t2, s2, i2, h2);
372
- }
373
- putImageData(t2, s2 = 0, i2 = 0) {
374
- this.context.putImageData(t2, s2, i2);
375
- }
376
- toDataURL(t2 = "image/png", s2) {
377
- return this.canvas.toDataURL(t2, s2);
378
- }
379
- toImageBitmap(t2) {
380
- return createImageBitmap(this.canvas, t2 ?? {});
381
- }
382
- destroy() {
383
- if (super.destroy?.(), this.#t) {
384
- try {
385
- URL.revokeObjectURL(this.#t);
386
- } catch {
387
- }
388
- this.#t = null;
389
- }
390
- }
391
- constructor(t2) {
392
- super({ name: t2.name, space: t2.space ?? "world", x: t2.x, y: t2.y, scale: t2.scale, rotation: t2.rotation, anchor: t2.anchor ?? "topLeft", width: t2.width, height: t2.height }), this.type = "bitmap";
393
- }
394
- }
395
- class o {
396
- H = [];
397
- X = [];
398
- K(t2, s2) {
399
- s2.save(), t2.applyWorldTransform(s2);
400
- for (const i2 of this.H) !i2.visible || i2.opacity <= 0 || (s2.save(), i2.render(s2, t2), s2.restore());
401
- s2.restore(), s2.save(), t2.applyScreenTransform(s2);
402
- for (const i2 of this.X) !i2.visible || i2.opacity <= 0 || (s2.save(), i2.render(s2, t2), s2.restore());
403
- s2.restore();
404
- }
405
- addLayer(t2, s2) {
406
- const i2 = "world" === t2.space ? this.H : this.X;
407
- return "number" == typeof s2 && s2 >= 0 && s2 < i2.length ? (i2.splice(s2, 0, t2), t2.id) : (i2.push(t2), t2.id);
408
- }
409
- async createImageLayer(t2) {
410
- const s2 = await r.fromImage(t2);
411
- return this.addLayer(s2), s2;
412
- }
413
- createCanvasLayer(t2) {
414
- const s2 = new n(t2);
415
- return this.addLayer(s2), s2;
416
- }
417
- removeLayer(t2) {
418
- const s2 = this.H.findIndex((s3) => s3.id === t2);
419
- if (s2 >= 0) return this.H[s2].destroy?.(), void this.H.splice(s2, 1);
420
- const i2 = this.X.findIndex((s3) => s3.id === t2);
421
- i2 >= 0 && (this.X[i2].destroy?.(), this.X.splice(i2, 1));
422
- }
423
- moveLayer(t2, s2) {
424
- const i2 = this.H.findIndex((s3) => s3.id === t2);
425
- if (i2 >= 0) {
426
- const [t3] = this.H.splice(i2, 1), h3 = Math.max(0, Math.min(s2, this.H.length));
427
- return void this.H.splice(h3, 0, t3);
428
- }
429
- const h2 = this.X.findIndex((s3) => s3.id === t2);
430
- if (h2 >= 0) {
431
- const [t3] = this.X.splice(h2, 1), i3 = Math.max(0, Math.min(s2, this.X.length));
432
- this.X.splice(i3, 0, t3);
433
- }
434
- }
435
- getLayer(t2) {
436
- return this.H.find((s2) => s2.id === t2) || this.X.find((s2) => s2.id === t2);
437
- }
438
- getAllLayers(t2) {
439
- return t2 ? ("world" === t2 ? this.H : this.X).slice() : [...this.H, ...this.X];
440
- }
441
- hitTest(t2, s2, i2 = "world") {
442
- const h2 = this.getAllLayers(i2);
443
- for (let i3 = h2.length - 1; i3 >= 0; i3--) {
444
- const e2 = h2[i3];
445
- if (e2.hitTest && e2.hitTest(t2, s2)) return e2;
446
- }
447
- }
448
- destroy() {
449
- for (const t2 of [...this.H, ...this.X]) t2.destroy?.();
450
- this.H = [], this.X = [];
451
- }
452
- }
453
- class a extends o {
454
- Y = null;
455
- G = null;
456
- j = true;
457
- J = 0;
458
- tt = 0;
459
- st = 0;
460
- it = 0;
461
- markDirty() {
462
- this.j = true;
463
- }
464
- addLayer(t2, s2) {
465
- return this.j = true, super.addLayer(t2, s2);
466
- }
467
- removeLayer(t2) {
468
- this.j = true, super.removeLayer(t2);
469
- }
470
- moveLayer(t2, s2) {
471
- this.j = true, super.moveLayer(t2, s2);
472
- }
473
- renderAllLayersIn(t2) {
474
- const s2 = t2.contentContext, i2 = this.H;
475
- 0 !== i2.length && (this.j && this.ht(i2), this.Y && this.G && s2.drawImage(this.Y, this.st, this.it));
476
- }
477
- ht(t2) {
478
- let s2 = 0, i2 = 0, h2 = 0, e2 = 0, n2 = false;
479
- for (const r3 of t2) {
480
- const t3 = r3, o3 = t3.canvas.width * t3.scale, a3 = t3.canvas.height * t3.scale, c2 = "center" === t3.anchor ? -o3 / 2 : 0, l2 = "center" === t3.anchor ? -a3 / 2 : 0, u2 = Math.cos(t3.rotation), d2 = Math.sin(t3.rotation), f2 = [{ x: c2, y: l2 }, { x: c2 + o3, y: l2 }, { x: c2, y: l2 + a3 }, { x: c2 + o3, y: l2 + a3 }];
481
- let M2 = 1 / 0, m2 = 1 / 0, p2 = -1 / 0, g = -1 / 0;
482
- for (const s3 of f2) {
483
- const i3 = s3.x * u2 - s3.y * d2 + t3.x, h3 = s3.x * d2 + s3.y * u2 + t3.y;
484
- M2 = Math.min(M2, i3), m2 = Math.min(m2, h3), p2 = Math.max(p2, i3), g = Math.max(g, h3);
485
- }
486
- n2 ? (s2 = Math.min(s2, M2), i2 = Math.min(i2, m2), h2 = Math.max(h2, p2), e2 = Math.max(e2, g)) : (s2 = M2, i2 = m2, h2 = p2, e2 = g, n2 = true);
487
- }
488
- if (!n2) return void (this.j = false);
489
- const r2 = Math.ceil(h2 - s2), o2 = Math.ceil(e2 - i2);
490
- this.Y || (this.Y = document.createElement("canvas"), this.G = this.Y.getContext("2d", { alpha: true })), this.J === r2 && this.tt === o2 || (this.Y.width = r2, this.Y.height = o2, this.J = r2, this.tt = o2), this.st = s2, this.it = i2;
491
- const a2 = this.G;
492
- a2.clearRect(0, 0, r2, o2), a2.save(), a2.translate(-s2, -i2);
493
- for (const s3 of t2) !s3.visible || s3.opacity <= 0 || (a2.save(), s3.render(a2), a2.restore());
494
- a2.restore(), this.j = false;
495
- }
496
- destroy() {
497
- super.destroy(), this.Y = null, this.G = null;
498
- }
499
- }
500
- class c extends o {
501
- renderAllLayersIn(t2) {
502
- const s2 = t2.topScreenContext;
503
- this.K(t2, s2);
504
- }
505
- }
506
- class l {
507
- name = "interaction";
508
- et = null;
509
- i;
510
- nt;
511
- rt;
512
- ot = false;
513
- ct = 0;
514
- lt = 0;
515
- ut = 0;
516
- dt = null;
517
- ft = (t2) => this.Mt(t2);
518
- gt = (t2) => this._t(t2);
519
- yt = () => this.wt();
520
- xt = (t2) => this.bt(t2);
521
- constructor(t2) {
522
- this.i = { panEnabled: true, zoomEnabled: true, friction: 0.92, stopSpeed: 0.02, emaAlpha: 0.25, idleNoInertiaMs: 120, wheelSensitivity: 15e-4, ...t2 }, this.nt = this.i.panEnabled, this.rt = this.i.zoomEnabled;
523
- }
524
- install(t2) {
525
- this.et = t2;
526
- const s2 = t2.canvas;
527
- s2.addEventListener("wheel", this.xt, { passive: false }), s2.addEventListener("pointerdown", this.ft), window.addEventListener("pointermove", this.gt), window.addEventListener("pointerup", this.yt), t2.onUpdate(this.vt);
528
- }
529
- destroy() {
530
- if (!this.et) return;
531
- const t2 = this.et.canvas;
532
- t2.removeEventListener("wheel", this.xt), t2.removeEventListener("pointerdown", this.ft), window.removeEventListener("pointermove", this.gt), window.removeEventListener("pointerup", this.yt), this.et.offUpdate(this.vt), this.et = null;
533
- }
534
- isPanEnabled() {
535
- return this.nt;
536
- }
537
- isZoomEnabled() {
538
- return this.rt;
539
- }
540
- setPanEnabled(t2) {
541
- this.nt !== t2 && (this.nt = t2, t2 || (this.ot = false, this.ct = 0, this.lt = 0));
542
- }
543
- setZoomEnabled(t2) {
544
- this.rt = t2;
545
- }
546
- setWheelSensitivity(t2) {
547
- this.i.wheelSensitivity = t2;
548
- }
549
- isDragging() {
550
- return this.ot;
551
- }
552
- vt = (t2) => {
553
- if (!this.et) return;
554
- const { friction: s2, stopSpeed: i2 } = this.i, h2 = Math.hypot(this.ct, this.lt) >= i2;
555
- if (!this.ot && this.nt && h2) {
556
- const h3 = this.ct * t2, e2 = this.lt * t2;
557
- this.et.panBy(h3, e2), this.ct *= s2, this.lt *= s2, Math.hypot(this.ct, this.lt) < i2 && (this.ct = 0, this.lt = 0);
558
- } else this.nt || (this.ct = 0, this.lt = 0);
559
- };
560
- Mt(t2) {
561
- if (0 === t2.button && this.nt) {
562
- this.ot = true, this.ct = 0, this.lt = 0, this.ut = performance.now(), this.dt = t2.pointerId;
563
- try {
564
- this.et?.canvas.setPointerCapture(t2.pointerId);
565
- } catch {
566
- }
567
- }
568
- }
569
- _t(t2) {
570
- if (!this.ot || !this.nt || !this.et) return;
571
- const s2 = performance.now(), i2 = Math.max(1, s2 - (this.ut || s2 - 16));
572
- this.ut = s2;
573
- const h2 = t2.movementX, e2 = t2.movementY;
574
- this.et.panBy(h2, e2);
575
- const n2 = this.i.emaAlpha, r2 = h2 / i2, o2 = e2 / i2;
576
- this.ct = (1 - n2) * this.ct + n2 * r2, this.lt = (1 - n2) * this.lt + n2 * o2;
577
- }
578
- wt() {
579
- if (!this.ot) return;
580
- this.ot = false;
581
- const t2 = performance.now(), s2 = this.ut ? t2 - this.ut : 1 / 0;
582
- if (null != this.dt && this.et) {
583
- try {
584
- this.et.canvas.releasePointerCapture(this.dt);
585
- } catch {
586
- }
587
- this.dt = null;
588
- }
589
- if (s2 >= this.i.idleNoInertiaMs) this.ct = 0, this.lt = 0;
590
- else {
591
- const t3 = Math.pow(this.i.friction, s2 / 16);
592
- this.ct *= t3, this.lt *= t3;
593
- }
594
- Math.hypot(this.ct, this.lt) < this.i.stopSpeed && (this.ct = 0, this.lt = 0);
595
- }
596
- Lt() {
597
- if (!this.et) return 16;
598
- const t2 = getComputedStyle(this.et.canvas).lineHeight;
599
- if (!t2 || "normal" === t2) return 16;
600
- const s2 = parseFloat(t2);
601
- return Number.isFinite(s2) ? s2 : 16;
602
- }
603
- Rt(t2) {
604
- if (!this.et) return 0;
605
- let s2 = t2.deltaY;
606
- return 1 === t2.deltaMode ? s2 *= this.Lt() : 2 === t2.deltaMode && (s2 *= this.et.canvas.clientHeight || window.innerHeight || 800), s2;
607
- }
608
- bt(t2) {
609
- if (!this.rt || !this.et) return;
610
- t2.preventDefault(), t2.stopPropagation();
611
- const s2 = this.Rt(t2), i2 = this.et.canvas.getBoundingClientRect(), h2 = t2.clientX - i2.left, e2 = t2.clientY - i2.top;
612
- let n2 = -s2 * this.i.wheelSensitivity;
613
- t2.ctrlKey || t2.metaKey ? n2 *= 1.6 : t2.shiftKey && (n2 *= 0.6), this.et.zoomByLogAtScreen(h2, e2, n2);
614
- }
615
- }
616
- function u(t2) {
617
- return new l(t2);
618
- }
619
- class d {
620
- name = "document";
621
- et = null;
622
- i;
623
- St = false;
624
- zt = 0;
625
- Ct = 0;
626
- At = 0;
627
- Tt = 0;
628
- Pt = 0;
629
- Bt = 0;
630
- It = 0;
631
- Dt = 0;
632
- Et = "minVisible";
633
- constructor(t2) {
634
- this.i = { rect: { x: 0, y: 0, width: 0, height: 0 }, margins: {}, drawBorder: false, minVisiblePx: 30, panClampMode: "minVisible", ...t2 }, t2?.rect && (this.St = true, this.zt = t2.rect.x, this.Ct = t2.rect.y, this.At = t2.rect.width, this.Tt = t2.rect.height), t2?.margins && (this.Pt = t2.margins.left ?? 0, this.Bt = t2.margins.right ?? 0, this.It = t2.margins.top ?? 0, this.Dt = t2.margins.bottom ?? 0), this.Et = this.i.panClampMode;
635
- }
636
- install(t2) {
637
- this.et = t2, t2.onUpdate(this.vt), t2.onBeforeRender(this.Ft), t2.onAfterRender(this.kt);
638
- }
639
- destroy() {
640
- this.et && (this.et.offUpdate(this.vt), this.et.offBeforeRender(this.Ft), this.et.offAfterRender(this.kt), this.et = null);
641
- }
642
- isEnabled() {
643
- return this.St;
644
- }
645
- getRect() {
646
- return { x: this.zt, y: this.Ct, width: this.At, height: this.Tt };
647
- }
648
- setRect(t2, s2, i2, h2) {
649
- this.St = true, this.zt = t2, this.Ct = s2, this.At = i2, this.Tt = h2;
650
- }
651
- clearRect() {
652
- this.St = false;
653
- }
654
- setMargins(t2) {
655
- this.Pt = t2.left ?? this.Pt, this.Bt = t2.right ?? this.Bt, this.It = t2.top ?? this.It, this.Dt = t2.bottom ?? this.Dt;
656
- }
657
- getMargins() {
658
- return { left: this.Pt, right: this.Bt, top: this.It, bottom: this.Dt };
659
- }
660
- setPanClampMode(t2) {
661
- this.Et = t2;
662
- }
663
- getPanClampMode() {
664
- return this.Et;
665
- }
666
- cropTo(t2) {
667
- this.Zt("crop", t2);
668
- }
669
- resizeTo(t2) {
670
- this.Zt("resize", t2);
671
- }
672
- zoomToFit(t2 = "contain") {
673
- if (!this.St || !this.et) return;
674
- const s2 = this.et.dpr, i2 = this.et.canvas.width / s2, h2 = this.et.canvas.height / s2, e2 = Math.max(1, i2 - (this.Pt + this.Bt)), n2 = Math.max(1, h2 - (this.It + this.Dt));
675
- let r2;
676
- const o2 = e2 / this.At, a2 = n2 / this.Tt;
677
- r2 = "contain" === t2 ? Math.min(o2, a2) : "cover" === t2 ? Math.max(o2, a2) : "fitWidth" === t2 ? o2 : a2, r2 = Math.min(this.et.maxZoom, Math.max(this.et.minZoom, r2));
678
- const c2 = this.Pt + (e2 - r2 * this.At) / 2, l2 = this.It + (n2 - r2 * this.Tt) / 2, u2 = c2 - r2 * this.zt, d2 = l2 - r2 * this.Ct;
679
- this.et.setTransform(r2, u2, d2);
680
- }
681
- isPointInDocument(t2, s2) {
682
- return !this.St || t2 >= this.zt && t2 <= this.zt + this.At && s2 >= this.Ct && s2 <= this.Ct + this.Tt;
683
- }
684
- vt = () => {
685
- this.St && this.et && this.Ut();
686
- };
687
- Ft = (t2) => {
688
- this.St && this.et && (t2.save(), t2.beginPath(), t2.rect(this.zt, this.Ct, this.At, this.Tt), t2.clip());
689
- };
690
- kt = (t2) => {
691
- if (this.St && this.et && (t2.restore(), this.i.drawBorder)) {
692
- const s2 = this.et.zoom;
693
- t2.save(), t2.lineWidth = 1 / s2, t2.strokeStyle = "#cfcfcf", t2.strokeRect(this.zt, this.Ct, this.At, this.Tt), t2.restore();
694
- }
695
- };
696
- Ut() {
697
- if (!this.et) return;
698
- const { zoom: t2, tx: s2, ty: i2 } = this.et.getTransform(), h2 = t2, e2 = this.et.dpr, n2 = this.et.canvas.width / e2, r2 = this.et.canvas.height / e2, o2 = this.zt, a2 = this.Ct, c2 = this.zt + this.At, l2 = this.Ct + this.Tt;
699
- let u2 = s2, d2 = i2;
700
- if ("margin" === this.Et) {
701
- const t3 = this.Pt - h2 * o2, e3 = n2 - this.Bt - h2 * c2, f2 = this.It - h2 * a2, M2 = r2 - this.Dt - h2 * l2, m2 = Math.max(1, n2 - (this.Pt + this.Bt)), p2 = Math.max(1, r2 - (this.It + this.Dt));
702
- u2 = h2 * this.At <= m2 ? this.Pt + (m2 - h2 * this.At) / 2 - h2 * this.zt : Math.min(t3, Math.max(e3, s2)), d2 = h2 * this.Tt <= p2 ? this.It + (p2 - h2 * this.Tt) / 2 - h2 * this.Ct : Math.min(f2, Math.max(M2, i2));
703
- } else if ("minVisible" === this.Et) {
704
- const t3 = h2 * this.At, e3 = h2 * this.Tt, f2 = Math.min(this.i.minVisiblePx, t3), M2 = Math.min(this.i.minVisiblePx, e3), m2 = n2 - f2 - h2 * o2, p2 = f2 - h2 * c2, g = r2 - M2 - h2 * a2, _ = M2 - h2 * l2;
705
- u2 = p2 <= m2 ? Math.min(m2, Math.max(p2, s2)) : (p2 + m2) / 2, d2 = _ <= g ? Math.min(g, Math.max(_, i2)) : (_ + g) / 2;
706
- }
707
- u2 === s2 && d2 === i2 || this.et.setPan(u2, d2);
708
- }
709
- Zt(t2, s2) {
710
- if (!this.et) return;
711
- const i2 = Math.max(1, Math.floor(s2.width)), h2 = Math.max(1, Math.floor(s2.height)), e2 = { width: i2, height: h2 }, n2 = this.et.getLayerManagers();
712
- for (const s3 of n2) {
713
- const i3 = s3.getAllLayers("world");
714
- for (const s4 of i3) {
715
- const i4 = s4;
716
- "function" == typeof i4.cropTo && "function" == typeof i4.resizeTo && ("crop" === t2 ? i4.cropTo(e2) : i4.resizeTo(e2));
717
- }
718
- }
719
- this.At = i2, this.Tt = h2, this.St && this.Ut();
720
- }
721
- }
722
- function f(t2) {
723
- return new d(t2);
724
- }
725
- class M {
726
- type = "snapshot";
727
- Wt;
728
- $t;
729
- qt;
730
- Ot;
731
- Nt = true;
732
- constructor(t2, s2, i2, h2) {
733
- this.Wt = t2, this.$t = s2, this.qt = i2, this.Ot = h2?.region;
734
- }
735
- execute() {
736
- if (this.Nt) return;
737
- const t2 = this.Ot ? { x: this.Ot.x, y: this.Ot.y } : void 0;
738
- this.Wt.restoreSnapshot(this.qt, t2), this.Nt = true;
739
- }
740
- undo() {
741
- if (!this.Nt) return;
742
- const t2 = this.Ot ? { x: this.Ot.x, y: this.Ot.y } : void 0;
743
- this.Wt.restoreSnapshot(this.$t, t2), this.Nt = false;
744
- }
745
- canMerge() {
746
- return false;
747
- }
748
- merge() {
749
- return this;
750
- }
751
- }
752
- function m(t2, s2, i2, h2) {
753
- return s2 && i2 ? new M(t2, s2, i2, h2) : null;
754
- }
755
- class p {
756
- Vt;
757
- Ht = [];
758
- Xt = [];
759
- executeCommand(t2) {
760
- t2.execute(), this.addCommand(t2);
761
- }
762
- addCommand(t2) {
763
- this.Xt = [];
764
- const s2 = this.Ht[this.Ht.length - 1];
765
- if (s2 && s2.canMerge?.(t2) && s2.merge) {
766
- const i2 = s2.merge(t2) ?? s2;
767
- return void (i2 !== s2 && (this.Ht[this.Ht.length - 1] = i2));
768
- }
769
- this.Ht.push(t2), this.Ht.length > this.Vt && this.Ht.shift();
770
- }
771
- undo() {
772
- if (0 === this.Ht.length) return null;
773
- const t2 = this.Ht.pop();
774
- return t2.undo(), this.Xt.push(t2), t2;
775
- }
776
- redo() {
777
- if (0 === this.Xt.length) return null;
778
- const t2 = this.Xt.pop();
779
- return t2.execute(), this.Ht.push(t2), t2;
780
- }
781
- canUndo() {
782
- return this.Ht.length > 0;
783
- }
784
- canRedo() {
785
- return this.Xt.length > 0;
786
- }
787
- clear() {
788
- this.Ht = [], this.Xt = [];
789
- }
790
- setMaxHistorySize(t2) {
791
- this.Vt = Math.max(1, t2), this.Ht.length > this.Vt && (this.Ht = this.Ht.slice(-this.Vt));
792
- }
793
- constructor(t2) {
794
- this.Vt = t2?.maxHistorySize ?? 50, this.Ht = t2?.undoStack ?? [], this.Xt = t2?.redoStack ?? [];
795
- }
796
- }
797
- export {
798
- r as BitmapLayer,
799
- n as CanvasLayer,
800
- a as ContentLayerManager,
801
- d as DocumentPlugin,
802
- p as HistoryManager,
803
- l as InteractionPlugin,
804
- e as LayerBase,
805
- o as LayerManagerBase,
806
- M as SnapshotCommand,
807
- c as TopScreenLayerManager,
808
- i as ViewManager,
809
- f as createDocumentPlugin,
810
- u as createInteractionPlugin,
811
- m as createSnapshotCommand
812
- };