@ezuikit/control-zoom 0.0.1-alpha.1

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/.babelrc ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env"
4
+ ],
5
+ "plugins": []
6
+ }
package/dist/index.js ADDED
@@ -0,0 +1,682 @@
1
+ /*
2
+ * @ezuikit/control-zoom v0.0.1-alpha.1
3
+ * Copyright (c) 2025-10-08 Ezviz-OpenBiz
4
+ * Released under the MIT License.
5
+ */
6
+ 'use strict';
7
+
8
+ Object.defineProperty(exports, '__esModule', { value: true });
9
+
10
+ /**
11
+ * Zoom position
12
+ *
13
+ */ const ZOOM_DEFAULT_POSITION = [
14
+ 0,
15
+ 0
16
+ ];
17
+ /**
18
+ * 默认值
19
+ */ const DefaultOptions = {
20
+ initialZoom: 1,
21
+ defaultCursor: 'pointer',
22
+ scrollVelocity: 0.1,
23
+ animDuration: 0.25,
24
+ allowZoom: true,
25
+ allowPan: true,
26
+ onChange: ()=>{},
27
+ onTranslateChange: ()=>{},
28
+ onTap: ()=>{},
29
+ max: 8,
30
+ min: 1,
31
+ zoomStep: 0.1,
32
+ allowTouchEvents: false,
33
+ allowWheel: true,
34
+ ignoredMouseButtons: [],
35
+ doubleTouchMaxDelay: 300,
36
+ decelerationDuration: 750
37
+ };
38
+ /**
39
+ * dom 节点放大和拖动
40
+ *
41
+ */ class Zoom {
42
+ get pos() {
43
+ return [
44
+ this.container.clientWidth * this.percentPos[0],
45
+ this.container.clientHeight * this.percentPos[1]
46
+ ];
47
+ }
48
+ // 设置事件侦听器
49
+ setUpEventListeners() {
50
+ const refCurrentValue = this.container;
51
+ const hasMouseDevice = window.matchMedia('(pointer: fine)').matches;
52
+ if (hasMouseDevice) {
53
+ if (this.options.allowWheel) {
54
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('wheel', this.handleMouseWheel, {
55
+ passive: false
56
+ });
57
+ }
58
+ // Apply mouse events only to devices which include an accurate pointing device
59
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('mousedown', this.handleMouseStart, {
60
+ passive: false
61
+ });
62
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('mousemove', this.handleMouseMove, {
63
+ passive: false
64
+ });
65
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('mouseup', this.handleMouseStop, {
66
+ passive: false
67
+ });
68
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('mouseleave', this.handleMouseStop, {
69
+ passive: false
70
+ });
71
+ } else {
72
+ // Apply touch events to all other devices
73
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('touchstart', this.handleTouchStart, {
74
+ passive: false
75
+ });
76
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('touchmove', this.handleTouchMove, {
77
+ passive: false
78
+ });
79
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('touchend', this.handleTouchStop, {
80
+ passive: false
81
+ });
82
+ refCurrentValue == null ? void 0 : refCurrentValue.addEventListener('touchcancel', this.handleTouchStop, {
83
+ passive: false
84
+ });
85
+ }
86
+ }
87
+ // 移除事件侦听器
88
+ removeEventListeners() {
89
+ const refCurrentValue = this.container;
90
+ const hasMouseDevice = window.matchMedia('(pointer: fine)').matches;
91
+ if (hasMouseDevice) {
92
+ if (this.options.allowWheel) {
93
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('wheel', this.handleMouseWheel);
94
+ }
95
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('mousedown', this.handleMouseStart);
96
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('mousemove', this.handleMouseMove);
97
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('mouseup', this.handleMouseStop);
98
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('mouseleave', this.handleMouseStop);
99
+ } else {
100
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('touchstart', this.handleTouchStart);
101
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('touchmove', this.handleTouchMove);
102
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('touchend', this.handleTouchStop);
103
+ refCurrentValue == null ? void 0 : refCurrentValue.removeEventListener('touchcancel', this.handleTouchStop);
104
+ }
105
+ }
106
+ getPrecision(value = 1) {
107
+ const valueStr = value.toString();
108
+ if (valueStr.includes('.')) {
109
+ return valueStr.split('.')[1].length;
110
+ } else {
111
+ return 1;
112
+ }
113
+ }
114
+ /**
115
+ * 获取坐标 (伪横屏X、Y轴坐标转换, 相对值)
116
+ * @param event
117
+ * @returns
118
+ */ getCoordinates(event) {
119
+ const clientHeight = this.container.clientHeight;
120
+ const clientTop = this.container.clientTop;
121
+ const clientLeft = this.container.clientLeft;
122
+ const [x1, y1] = this.transform ? [
123
+ event.clientY,
124
+ clientHeight - event.clientX
125
+ ] : [
126
+ event.clientX - clientTop,
127
+ event.clientY - clientLeft
128
+ ];
129
+ return [
130
+ x1,
131
+ y1
132
+ ];
133
+ }
134
+ _touchOrMouseDrag(event) {
135
+ if (this.lastCursor) {
136
+ const [posX, posY] = this.getCoordinates(event);
137
+ const shiftX = posX - this.lastCursor[0];
138
+ const shiftY = posY - this.lastCursor[1];
139
+ this.move(shiftX, shiftY, 0);
140
+ this.lastCursor = [
141
+ posX,
142
+ posY
143
+ ];
144
+ this.lastShift = [
145
+ shiftX,
146
+ shiftY
147
+ ];
148
+ }
149
+ }
150
+ constructor(container, options){
151
+ this._dragging = false;
152
+ /**
153
+ * 销毁
154
+ * destroy
155
+ */ this.destroy = ()=>{
156
+ this.setAllowZoom(false);
157
+ this.reset();
158
+ this.removeEventListeners();
159
+ };
160
+ /**
161
+ * 设置是否旋转
162
+ * @param trans - 是否transform
163
+ */ this.setTransform = (trans)=>{
164
+ this.transform = trans;
165
+ };
166
+ /**
167
+ * 获取是否旋转
168
+ * @returns
169
+ */ this.getTransform = ()=>this.transform;
170
+ /**
171
+ * 更新x轴和Y轴平移值
172
+ */ this.updateTranslate = ()=>{
173
+ let translateX = 0;
174
+ let translateY = 0;
175
+ if (this.percentPos[0] < 0) {
176
+ translateX = this.percentPos[0] < -(0.5 * (this.zoom - 1)) ? -(0.5 * (this.zoom - 1)) : this.percentPos[0];
177
+ } else {
178
+ translateX = this.percentPos[0] > 0.5 * (this.zoom - 1) ? 0.5 * (this.zoom - 1) : this.percentPos[0];
179
+ }
180
+ if (this.percentPos[1] < 0) {
181
+ translateY = this.percentPos[1] < -(0.5 * (this.zoom - 1)) ? -(0.5 * (this.zoom - 1)) : this.percentPos[1];
182
+ } else {
183
+ translateY = this.percentPos[1] > 0.5 * (this.zoom - 1) ? 0.5 * (this.zoom - 1) : this.percentPos[1];
184
+ }
185
+ this.percentPos = [
186
+ translateX,
187
+ translateY
188
+ ];
189
+ };
190
+ /**
191
+ * 更新容器样式
192
+ */ this.update = ()=>{
193
+ if (!this.container) return;
194
+ this.updateTranslate();
195
+ this.container.style.transition = `transform ease-out ${this.transition}s`;
196
+ this.container.style.transform = `translate3d(${this.percentPos[0] * 100}%, ${this.percentPos[1] * 100}%, 0) scale(${this.zoom})`;
197
+ };
198
+ /**
199
+ * 设置支持缩放
200
+ * @param allow
201
+ */ this.setAllowZoom = (allow)=>{
202
+ this.options.allowZoom = allow;
203
+ };
204
+ /**
205
+ * 设置缩放值
206
+ * @param zoom - 缩放值
207
+ * @param reset - 是否重置
208
+ */ this.setZoom = (zoom, reset)=>{
209
+ zoom = parseFloat(zoom.toFixed(this.getPrecision(this.options.zoomStep)));
210
+ if (this.zoom !== zoom) {
211
+ this.zoom = zoom;
212
+ this.update();
213
+ this.options.onChange == null ? void 0 : this.options.onChange.call(this.options, +this.zoom.toFixed(this.getPrecision(this.options.zoomStep)), reset);
214
+ }
215
+ };
216
+ /**
217
+ * 获取缩放值
218
+ * @returns
219
+ */ this.getZoom = ()=>this.zoom;
220
+ /**
221
+ * 设置位置
222
+ * @param pos - 位置 [X轴坐标转换, Y轴坐标转换]
223
+ */ this.setPos = (pos)=>{
224
+ var _this_container, _this_container1;
225
+ const containerWidth = (_this_container = this.container) == null ? void 0 : _this_container.clientWidth;
226
+ const containerHeight = (_this_container1 = this.container) == null ? void 0 : _this_container1.clientHeight;
227
+ if (+this.pos[0] !== pos[0] || +this.pos[1] !== pos[1]) {
228
+ this.percentPos = [
229
+ pos[0] / containerWidth,
230
+ pos[1] / containerHeight
231
+ ];
232
+ this.update();
233
+ this.options.onTranslateChange == null ? void 0 : this.options.onTranslateChange.call(this.options, {
234
+ posX: pos[0],
235
+ posY: pos[1]
236
+ });
237
+ }
238
+ };
239
+ /**
240
+ * 设置过渡时间
241
+ * @param duration - 过渡时间, 单位秒
242
+ */ this.setTransitionDuration = (duration)=>{
243
+ this.transition = duration;
244
+ this.update();
245
+ };
246
+ /**
247
+ * 设置鼠标样式
248
+ * @param cursor
249
+ * @returns
250
+ */ this.setCursor = (cursor)=>{
251
+ if (!this.container) return;
252
+ this.container.style.cssText += `cursor:${cursor};`;
253
+ this.cursor = cursor;
254
+ };
255
+ this.zoomIn = (value)=>{
256
+ let newPosX = this.pos[0];
257
+ let newPosY = this.pos[1];
258
+ const prevZoom = this.zoom;
259
+ var _this_options_max, _this_options_max1;
260
+ const newZoom = prevZoom + value < ((_this_options_max = this.options.max) != null ? _this_options_max : 8) ? prevZoom + value : (_this_options_max1 = this.options.max) != null ? _this_options_max1 : 8;
261
+ if (newZoom !== prevZoom) {
262
+ newPosX = newPosX * (newZoom - 1) / (prevZoom > 1 ? prevZoom - 1 : prevZoom);
263
+ newPosY = newPosY * (newZoom - 1) / (prevZoom > 1 ? prevZoom - 1 : prevZoom);
264
+ }
265
+ this.setZoom(newZoom);
266
+ this.setPos([
267
+ newPosX,
268
+ newPosY
269
+ ]);
270
+ this.setTransitionDuration(this.options.animDuration);
271
+ };
272
+ this.zoomOut = (value)=>{
273
+ let newPosX = this.pos[0];
274
+ let newPosY = this.pos[1];
275
+ const prevZoom = this.zoom;
276
+ var _this_options_min, _this_options_min1;
277
+ const newZoom = prevZoom - value > ((_this_options_min = this.options.min) != null ? _this_options_min : 1) ? prevZoom - value : (_this_options_min1 = this.options.min) != null ? _this_options_min1 : 1;
278
+ if (newZoom !== prevZoom) {
279
+ newPosX = newPosX * (newZoom - 1) / (prevZoom - 1);
280
+ newPosY = newPosY * (newZoom - 1) / (prevZoom - 1);
281
+ }
282
+ this.setZoom(newZoom);
283
+ this.setPos([
284
+ newPosX,
285
+ newPosY
286
+ ]);
287
+ this.setTransitionDuration(this.options.animDuration);
288
+ };
289
+ this.zoomToZone = (relX, relY, relWidth, relHeight)=>{
290
+ var _this_container;
291
+ if (!this.container) return;
292
+ let newPosX = this.pos[0];
293
+ let newPosY = this.pos[1];
294
+ const parentRect = ((_this_container = this.container) == null ? void 0 : _this_container.parentNode).getBoundingClientRect();
295
+ const prevZoom = this.zoom;
296
+ // Calculate zoom factor to scale the zone
297
+ const optimalZoomX = parentRect.width / relWidth;
298
+ const optimalZoomY = parentRect.height / relHeight;
299
+ var _this_options_max;
300
+ const newZoom = Math.min(optimalZoomX, optimalZoomY, (_this_options_max = this.options.max) != null ? _this_options_max : 8);
301
+ // Calculate new position to center the zone
302
+ const rect = this.container.getBoundingClientRect();
303
+ const [centerX, centerY] = [
304
+ rect.width / prevZoom / 2,
305
+ rect.height / prevZoom / 2
306
+ ];
307
+ const [zoneCenterX, zoneCenterY] = [
308
+ relX + relWidth / 2,
309
+ relY + relHeight / 2
310
+ ];
311
+ newPosX = (centerX - zoneCenterX) * newZoom;
312
+ newPosY = (centerY - zoneCenterY) * newZoom;
313
+ this.setZoom(newZoom);
314
+ this.setPos([
315
+ newPosX,
316
+ newPosY
317
+ ]);
318
+ this.setTransitionDuration(this.options.animDuration);
319
+ };
320
+ this.getNewPosition = (x, y, newZoom)=>{
321
+ const [prevZoom] = [
322
+ this.zoom,
323
+ this.pos[0],
324
+ this.pos[1]
325
+ ];
326
+ if (newZoom === 1 || !this) return ZOOM_DEFAULT_POSITION;
327
+ const [clientWidth, clientHeight] = [
328
+ this.container.clientWidth,
329
+ this.container.clientHeight
330
+ ];
331
+ if (newZoom > prevZoom) {
332
+ return [
333
+ 0,
334
+ 0
335
+ ];
336
+ } else {
337
+ // 放到最大
338
+ let w = -((x - clientWidth / 2) / (clientWidth / 2)) * newZoom / 2;
339
+ let h = -((y - clientHeight / 2) / (clientHeight / 2)) * newZoom / 2;
340
+ if (w > newZoom / 2 - 0.5) {
341
+ w = 3.5;
342
+ }
343
+ if (h > newZoom / 2 - 0.5) {
344
+ h = 3.5;
345
+ }
346
+ return [
347
+ clientWidth * w,
348
+ clientHeight * h
349
+ ];
350
+ }
351
+ };
352
+ /**
353
+ * 缩放到最大
354
+ * @param x - 点击点X坐标
355
+ * @param y - 点击点Y坐标
356
+ */ this.fullZoomInOnPosition = (x, y)=>{
357
+ var _this_options_max;
358
+ const zoom = (_this_options_max = this.options.max) != null ? _this_options_max : DefaultOptions.max;
359
+ this.setZoom(zoom != null ? zoom : DefaultOptions.max);
360
+ this.setPos(this.getNewPosition(x, y, zoom));
361
+ this.setTransitionDuration(this.options.animDuration);
362
+ };
363
+ this.getLimitedShift = (shift, minLimit, maxLimit, minElement, maxElement)=>{
364
+ if (shift > 0) {
365
+ if (minElement > minLimit) {
366
+ return 0;
367
+ } else if (minElement + shift > minLimit) {
368
+ return minLimit - minElement;
369
+ }
370
+ } else if (shift < 0) {
371
+ if (maxElement < maxLimit) {
372
+ return 0;
373
+ } else if (maxElement + shift < maxLimit) {
374
+ return maxLimit - maxElement;
375
+ }
376
+ }
377
+ return shift;
378
+ };
379
+ this.getCursor = (canMoveOnX, canMoveOnY)=>{
380
+ if (canMoveOnX && canMoveOnY) {
381
+ return 'move';
382
+ } else if (canMoveOnX) {
383
+ return 'ew-resize';
384
+ } else if (canMoveOnY) {
385
+ return 'ns-resize';
386
+ } else {
387
+ return 'auto';
388
+ }
389
+ };
390
+ this.move = (shiftX, shiftY, transitionDuration = 0)=>{
391
+ if (!this.container) return;
392
+ let newPosX = this.pos[0];
393
+ let newPosY = this.pos[1];
394
+ // let canMoveOnX: boolean, canMoveOnY: boolean;
395
+ const rect = this.container.getBoundingClientRect();
396
+ const parentRect = this.container.parentNode.getBoundingClientRect();
397
+ // 根据是否进行了伪横屏旋转,决定是使用 shiftX 还是 shiftY 来对画面进行移动
398
+ const shiftHorizontal = this.transform ? shiftY : shiftX;
399
+ const shiftVertical = this.transform ? shiftX : shiftY;
400
+ const [isLargerHor, isOutLeftBoundary, isOutRightBoundary] = this.transform ? [
401
+ rect.height > parentRect.bottom - parentRect.top,
402
+ shiftVertical > 0 && rect.top - parentRect.top < 0,
403
+ shiftVertical < 0 && rect.bottom - parentRect.bottom > 0
404
+ ] : [
405
+ rect.width > parentRect.right - parentRect.left,
406
+ shiftHorizontal > 0 && rect.left - parentRect.left < 0,
407
+ shiftHorizontal < 0 && rect.right - parentRect.right > 0
408
+ ];
409
+ const canMoveOnX = isLargerHor || isOutLeftBoundary || isOutRightBoundary;
410
+ if (canMoveOnX) {
411
+ if (this.transform) {
412
+ newPosX += this.getLimitedShift(shiftVertical, parentRect.top, parentRect.bottom, rect.top, rect.bottom);
413
+ } else {
414
+ newPosX += this.getLimitedShift(shiftHorizontal, parentRect.left, parentRect.right, rect.left, rect.right);
415
+ }
416
+ }
417
+ const [isLargerVer, isOutTopBoundary, isOutBottomBoundary] = this.transform ? [
418
+ rect.width > parentRect.right - parentRect.left,
419
+ shiftHorizontal > 0 && rect.right - parentRect.right < 0,
420
+ shiftHorizontal < 0 && rect.left - parentRect.left > 0
421
+ ] : [
422
+ rect.height > parentRect.bottom - parentRect.top,
423
+ shiftVertical > 0 && rect.top - parentRect.top < 0,
424
+ shiftVertical < 0 && rect.bottom - parentRect.bottom > 0
425
+ ];
426
+ const canMoveOnY = isLargerVer || isOutTopBoundary || isOutBottomBoundary;
427
+ if (canMoveOnY) {
428
+ if (this.transform) {
429
+ const transformGetLimitedShift = (shift, minLimit, maxLimit, minElement, maxElement)=>{
430
+ // css伪横屏边界判断特殊处理
431
+ if (shift > 0) {
432
+ if (maxElement < maxLimit + 1) {
433
+ return 0;
434
+ } else if (maxElement + shift < maxLimit + 1) {
435
+ return maxLimit - maxElement;
436
+ }
437
+ } else if (shift < 0) {
438
+ if (minElement + 1 > minLimit) {
439
+ return 0;
440
+ } else if (minElement + 1 + shift > minLimit) {
441
+ return minLimit - minElement;
442
+ }
443
+ }
444
+ return shift;
445
+ };
446
+ newPosY += transformGetLimitedShift(shiftHorizontal, parentRect.left, parentRect.right, rect.left, rect.right);
447
+ } else {
448
+ newPosY += this.getLimitedShift(shiftVertical, parentRect.top, parentRect.bottom, rect.top, rect.bottom);
449
+ }
450
+ }
451
+ const cursor = this.getCursor(canMoveOnX, canMoveOnY);
452
+ this.setPos([
453
+ newPosX,
454
+ newPosY
455
+ ]);
456
+ this.setCursor(cursor);
457
+ this.setTransitionDuration(transitionDuration);
458
+ };
459
+ /**
460
+ * 移动端双击
461
+ * @returns
462
+ */ this.isDoubleTapping = ()=>{
463
+ const touchTime = new Date().getTime();
464
+ var _this_lastTouchTime, _this_options_doubleTouchMaxDelay, _this_lastDoubleTapTime, _this_options_doubleTouchMaxDelay1;
465
+ const isDoubleTap = touchTime - ((_this_lastTouchTime = this.lastTouchTime) != null ? _this_lastTouchTime : 0) < ((_this_options_doubleTouchMaxDelay = this.options.doubleTouchMaxDelay) != null ? _this_options_doubleTouchMaxDelay : 300) && touchTime - ((_this_lastDoubleTapTime = this.lastDoubleTapTime) != null ? _this_lastDoubleTapTime : 0) > ((_this_options_doubleTouchMaxDelay1 = this.options.doubleTouchMaxDelay) != null ? _this_options_doubleTouchMaxDelay1 : 750);
466
+ if (isDoubleTap) {
467
+ this.lastDoubleTapTime = touchTime;
468
+ return true;
469
+ }
470
+ this.lastTouchTime = touchTime;
471
+ return false;
472
+ };
473
+ this.startDeceleration = (lastShiftOnX, lastShiftOnY)=>{
474
+ let startTimestamp = null;
475
+ const startDecelerationMove = (timestamp)=>{
476
+ if (startTimestamp === null) startTimestamp = timestamp;
477
+ const progress = timestamp - startTimestamp;
478
+ var _this_options_decelerationDuration, _this_options_decelerationDuration1;
479
+ const ratio = (((_this_options_decelerationDuration = this.options.decelerationDuration) != null ? _this_options_decelerationDuration : 750) - progress) / ((_this_options_decelerationDuration1 = this.options.decelerationDuration) != null ? _this_options_decelerationDuration1 : 750);
480
+ const [shiftX, shiftY] = [
481
+ lastShiftOnX * ratio,
482
+ lastShiftOnY * ratio
483
+ ];
484
+ var _this_options_decelerationDuration2;
485
+ if (progress < ((_this_options_decelerationDuration2 = this.options.decelerationDuration) != null ? _this_options_decelerationDuration2 : 750) && Math.max(Math.abs(shiftX), Math.abs(shiftY)) > 1) {
486
+ this.move(shiftX, shiftY, 0);
487
+ this.lastRequestAnimationId = requestAnimationFrame(startDecelerationMove);
488
+ } else {
489
+ this.lastRequestAnimationId = null;
490
+ }
491
+ };
492
+ this.lastRequestAnimationId = requestAnimationFrame(startDecelerationMove);
493
+ };
494
+ this.reset = ()=>{
495
+ this.setZoom(this.options.initialZoom, true);
496
+ this.cursor = this.options.defaultCursor;
497
+ this.setTransitionDuration(this.options.animDuration);
498
+ this.setPos(ZOOM_DEFAULT_POSITION);
499
+ };
500
+ // api向前兼容
501
+ this.addScale = (scale = 1)=>{
502
+ this.handleZoomAdd(scale);
503
+ };
504
+ this.handleZoomAdd = (scale = 1)=>{
505
+ if (!this.options.allowZoom || !this.options.allowWheel) return;
506
+ let newZoom = parseFloat((this.zoom + scale).toFixed(this.getPrecision(this.options.zoomStep)));
507
+ var _this_options_max;
508
+ if (newZoom > ((_this_options_max = this.options.max) != null ? _this_options_max : 8)) {
509
+ newZoom = 8;
510
+ }
511
+ this.setZoom(newZoom);
512
+ this.setPos(this.pos);
513
+ this.setTransitionDuration(0.05);
514
+ };
515
+ // api向前兼容
516
+ this.subScale = (scale = 1)=>{
517
+ this.handleZoomSub(scale);
518
+ };
519
+ this.handleZoomSub = (scale = 1)=>{
520
+ if (!this.options.allowZoom || !this.options.allowWheel) return;
521
+ let newZoom = parseFloat((this.zoom - scale).toFixed(this.getPrecision(this.options.zoomStep)));
522
+ if (newZoom < 1) {
523
+ newZoom = 1;
524
+ }
525
+ this.setZoom(newZoom);
526
+ this.setPos(this.pos);
527
+ this.setTransitionDuration(0.05);
528
+ };
529
+ this.handleMouseWheel = (event)=>{
530
+ event.preventDefault();
531
+ if (!this.options.allowZoom || !this.options.allowWheel) return;
532
+ const velocity = event.deltaY < 0 ? this.options.scrollVelocity : 0 - this.options.scrollVelocity;
533
+ var _this_options_max, _this_options_min;
534
+ const newZoom = parseFloat(Math.max(Math.min(this.zoom + velocity, (_this_options_max = this.options.max) != null ? _this_options_max : 8), (_this_options_min = this.options.min) != null ? _this_options_min : 1).toFixed(this.getPrecision(this.options.zoomStep)));
535
+ this.setZoom(newZoom);
536
+ // this.setPos(this.getNewPosition(posX, posY, newZoom));
537
+ this.setTransitionDuration(0.05);
538
+ };
539
+ this.handleMouseStart = (event)=>{
540
+ var _this_options_ignoredMouseButtons;
541
+ event.preventDefault();
542
+ if (!this.options.allowPan || ((_this_options_ignoredMouseButtons = this.options.ignoredMouseButtons) == null ? void 0 : _this_options_ignoredMouseButtons.includes(event.button))) return;
543
+ this._dragging = true;
544
+ if (this.lastRequestAnimationId) cancelAnimationFrame(this.lastRequestAnimationId);
545
+ this.lastCursor = this.getCoordinates(event);
546
+ };
547
+ this.handleMouseMove = (event)=>{
548
+ event.preventDefault();
549
+ if (!this.options.allowPan || !this.lastCursor || !this._dragging) return;
550
+ this._touchOrMouseDrag(event);
551
+ };
552
+ this.handleMouseStop = (event)=>{
553
+ event.preventDefault();
554
+ if (this.lastShift) {
555
+ this.startDeceleration(this.lastShift[0], this.lastShift[1]);
556
+ this.lastShift = null;
557
+ }
558
+ this.lastCursor = null;
559
+ this.setCursor('auto');
560
+ this._dragging = false;
561
+ };
562
+ this.handleTouchStart = (event)=>{
563
+ const isThisDoubleTapping = this.isDoubleTapping();
564
+ this.isMultiTouch = event.touches.length;
565
+ if (!this.options.allowTouchEvents) event.preventDefault();
566
+ if (this.lastRequestAnimationId) cancelAnimationFrame(this.lastRequestAnimationId);
567
+ let [posX, posY] = this.getCoordinates(event.touches[0]);
568
+ if (this.isMultiTouch > 1) {
569
+ this.lastCursor = [
570
+ posX,
571
+ posY
572
+ ];
573
+ return;
574
+ }
575
+ if (isThisDoubleTapping && this.options.allowZoom) {
576
+ if (this.zoom === 1) {
577
+ let { top, left, x, y } = this.container.getBoundingClientRect();
578
+ [x, y] = this.transform ? [
579
+ y,
580
+ x
581
+ ] : [
582
+ x,
583
+ y
584
+ ];
585
+ [posX, posY] = [
586
+ posX - x,
587
+ posY - y
588
+ ];
589
+ // 双击放大到最大
590
+ this.fullZoomInOnPosition(posX, posY);
591
+ } else {
592
+ this.reset();
593
+ }
594
+ return;
595
+ }
596
+ this._tapStartTime = new Date().getTime();
597
+ if (this.options.allowPan) this.lastCursor = [
598
+ posX,
599
+ posY
600
+ ];
601
+ };
602
+ this.handleTouchMove = (event)=>{
603
+ if (!this.options.allowTouchEvents) event.preventDefault();
604
+ if (!this.lastCursor) return;
605
+ if (this.isMultiTouch === 1) {
606
+ this._touchOrMouseDrag(event.touches[0]);
607
+ this.lastTouchDistance = null;
608
+ } else if (this.isMultiTouch > 1) {
609
+ let newZoom = this.zoom;
610
+ // If we detect two points, we shall zoom up or down
611
+ const [pos1X, pos1Y] = this.getCoordinates(event.touches[0]);
612
+ const [pos2X, pos2Y] = this.getCoordinates(event.touches[1]);
613
+ const distance = Math.sqrt(Math.pow(pos2X - pos1X, 2) + Math.pow(pos2Y - pos1Y, 2));
614
+ if (this.lastTouchDistance && distance && distance !== this.lastTouchDistance) {
615
+ if (this.options.allowZoom) {
616
+ newZoom += (distance - this.lastTouchDistance) / 100;
617
+ var _this_options_max, _this_options_min;
618
+ if (newZoom > ((_this_options_max = this.options.max) != null ? _this_options_max : 8)) {
619
+ var _this_options_max1;
620
+ newZoom = (_this_options_max1 = this.options.max) != null ? _this_options_max1 : 8;
621
+ } else if (newZoom < ((_this_options_min = this.options.min) != null ? _this_options_min : 1)) {
622
+ var _this_options_min1;
623
+ newZoom = (_this_options_min1 = this.options.min) != null ? _this_options_min1 : 1;
624
+ }
625
+ }
626
+ // 不要做移动,因为会有冲突
627
+ this.setZoom(newZoom);
628
+ this.setTransitionDuration(0);
629
+ }
630
+ // Save data for the next move
631
+ this.lastCursor = [
632
+ pos1X,
633
+ pos1Y
634
+ ];
635
+ this.lastTouchDistance = distance;
636
+ }
637
+ };
638
+ this.handleTouchStop = ()=>{
639
+ if (this.lastShift) {
640
+ // Use the last shift to make a decelerating movement effect
641
+ this.startDeceleration(this.lastShift[0], this.lastShift[1]);
642
+ this.lastShift = null;
643
+ }
644
+ if (this._tapStartTime && new Date().getTime() - this._tapStartTime < 200) {
645
+ this.options.onTap == null ? void 0 : this.options.onTap.call(this.options);
646
+ }
647
+ this._tapStartTime = undefined;
648
+ this.lastCursor = null;
649
+ this.lastTouchDistance = null;
650
+ this.isMultiTouch = 0;
651
+ };
652
+ this.container = container;
653
+ this.options = Object.assign({}, DefaultOptions, options || {});
654
+ this.percentPos = ZOOM_DEFAULT_POSITION;
655
+ this.transition = this.options.animDuration;
656
+ this.zoom = 1;
657
+ this.cursor = 'auto';
658
+ this.lastCursor = [
659
+ 0,
660
+ 0
661
+ ];
662
+ this.lastShift = null;
663
+ this.lastTouchDistance = null;
664
+ this.lastRequestAnimationId = null;
665
+ this.lastTouchTime = new Date().getTime();
666
+ this.lastDoubleTapTime = new Date().getTime();
667
+ this.transform = false; // 是否为横屏模式
668
+ this.isMultiTouch = 1;
669
+ this.handleMouseMove = this.handleMouseMove.bind(this);
670
+ this.handleMouseStart = this.handleMouseStart.bind(this);
671
+ this.handleMouseStop = this.handleMouseStop.bind(this);
672
+ this.handleMouseWheel = this.handleMouseWheel.bind(this);
673
+ this.handleTouchStart = this.handleTouchStart.bind(this);
674
+ this.handleTouchMove = this.handleTouchMove.bind(this);
675
+ this.handleTouchStop = this.handleTouchStop.bind(this);
676
+ this.getZoom = this.getZoom.bind(this);
677
+ this.setZoom = this.setZoom.bind(this);
678
+ }
679
+ }
680
+ Zoom.VERSION = '0.0.1-alpha.1';
681
+
682
+ exports.default = Zoom;