dom-pan-zoom 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,771 @@
1
+ 'use strict';
2
+
3
+ class domPanZoom {
4
+ constructor(options = {}) {
5
+ const defaultOptions = {
6
+ // The wrapper and container element
7
+ // You can use an element object or a selector string
8
+ wrapperElement: null,
9
+ panZoomElement: null,
10
+
11
+ // Start with a centered position
12
+ // This option overrides options initalPanX and initialPanY
13
+ center: true,
14
+
15
+ // Setting the option bounds to 'contain' or 'cover' limits the boundries of the panZoomElement to the wrapperElement
16
+ // This works similar to the CSS property 'background-size: contain / cover'
17
+ // Disable bound by setting this option to 'false'
18
+ // This option might effect the option minZoom
19
+ bounds: 'contain',
20
+
21
+ // Minimum and maximum zoom
22
+ minZoom: 0.1,
23
+ maxZoom: 10,
24
+
25
+ // How many percent to pan by default with the panning methods panLeft, panRight, panUp and panDown
26
+ panStep: 10,
27
+
28
+ // How many percent to zoom by default with the methods zoomIn and zoomOut
29
+ zoomStep: 50,
30
+
31
+ // The speed in which to zoom when using mouse wheel
32
+ zoomSpeedWheel: 1,
33
+
34
+ // The speed in which to zoom when pinching with touch gestures
35
+ // TODO this seems to not work correctly
36
+ zoomSpeedPinch: 4,
37
+
38
+ // Initial zoom
39
+ // Use any zoom value between the options minZoom and maxZoom
40
+ // Use 'cover' or 'contain' to limit the panZoomElement bounds to the wrapperElement
41
+ initialZoom: 'contain',
42
+
43
+ // Initial pan in percent
44
+ // The option 'center' has to be 'false' for initial panning to work
45
+ initialPanX: 0,
46
+ initialPanY: 0,
47
+
48
+ // Prefer scrolling the page to zooming with mousewheel or panning with touch event
49
+ // TODO how does google do it with tough events (use two fingers) ??
50
+ preferPageScroll: true,
51
+
52
+ // The text to show when the option preferPageScroll is enabled
53
+ preferPageScrollText: {
54
+ // TODO Differentiate between mac and windows
55
+ },
56
+
57
+ // Transition speed for panning and zooming in milliseconds
58
+ // Higher values are slower
59
+ transitionSpeed: 400,
60
+
61
+ // Events
62
+ onInit: null,
63
+ onChange: null,
64
+ onZoom: null,
65
+ onPan: null
66
+ };
67
+
68
+ this.options = Object.assign({}, defaultOptions, options);
69
+
70
+ this.init();
71
+ }
72
+
73
+ // Initialize
74
+ init() {
75
+ // Init containers
76
+ const wrapper = this.getWrapper();
77
+ const container = this.getContainer();
78
+
79
+ // Add styles
80
+ wrapper.style.cursor = 'grab';
81
+ wrapper.style.overflow = 'hidden';
82
+
83
+ // Cache
84
+ this.evCache = [];
85
+ this.pinchDiffCache = 0;
86
+ this.pinchMoveCache = null;
87
+
88
+ // Attach events
89
+ this.attachEvents();
90
+
91
+ // Adjust minZoom for option bounds
92
+ if (this.options.bounds) {
93
+ const maxWidth = wrapper.clientWidth;
94
+ const maxHeight = wrapper.clientHeight;
95
+
96
+ const panZoomWidth = container.clientWidth;
97
+ const panZoomHeight = container.clientHeight;
98
+
99
+ const minZoomX = maxWidth / panZoomWidth;
100
+ const minZoomY = maxHeight / panZoomHeight;
101
+
102
+ if (this.options.bounds == 'cover') {
103
+ this.options.minZoom = Math.max(
104
+ this.options.minZoom,
105
+ minZoomX,
106
+ minZoomY
107
+ );
108
+ } else {
109
+ this.options.minZoom = Math.max(
110
+ this.options.minZoom,
111
+ Math.min(minZoomX, minZoomY)
112
+ );
113
+ }
114
+ }
115
+
116
+ // Set initial zoom
117
+ this.zoom = this.sanitizeZoom(this.options.initialZoom);
118
+
119
+ // Set initial pan
120
+ this.x = this.options.initialPanX;
121
+ this.y = this.options.initialPanY;
122
+
123
+ // Set position
124
+ if (this.options.center) {
125
+ this.center(true);
126
+ } else {
127
+ this.panTo(this.options.initialPanX, this.options.initialPanY, true);
128
+ }
129
+
130
+ // Trigger event
131
+ this.fireEvent('onInit', this.getPosition());
132
+ }
133
+
134
+ // Fire an event from the options
135
+ fireEvent(event, pass) {
136
+ this.options[event] && this.options[event].bind(this)(pass);
137
+ }
138
+
139
+ // Attach events
140
+ attachEvents() {
141
+ // Event while mouse moving
142
+ const setPositionEvent = (ev) => {
143
+ if (this.blockPan == true) {
144
+ return;
145
+ }
146
+
147
+ let event = ev;
148
+ if (ev.touches && ev.touches.length) {
149
+ event = ev.touches[0];
150
+ }
151
+
152
+ let movementX = 0;
153
+ let movementY = 0;
154
+
155
+ if (this.previousEvent) {
156
+ movementX = event.pageX - this.previousEvent.pageX;
157
+ movementY = event.pageY - this.previousEvent.pageY;
158
+ }
159
+
160
+ this.x += movementX;
161
+ this.y += movementY;
162
+ this.setPosition(true);
163
+
164
+ this.previousEvent = event;
165
+
166
+ // Trigger event
167
+ this.fireEvent('onPan', this.getPosition());
168
+ };
169
+
170
+ // Mouse down or touchstart event
171
+ const mouseDownTouchStartEvent = (ev) => {
172
+ ev.preventDefault();
173
+ document.body.style.cursor = 'grabbing';
174
+ this.getWrapper().style.cursor = 'grabbing';
175
+ document.addEventListener('mousemove', setPositionEvent, {
176
+ passive: true
177
+ });
178
+ document.addEventListener('touchmove', setPositionEvent, {
179
+ passive: true
180
+ });
181
+ };
182
+
183
+ this.getWrapper().addEventListener('mousedown', mouseDownTouchStartEvent, {
184
+ passive: false
185
+ });
186
+
187
+ this.getWrapper().addEventListener('touchstart', mouseDownTouchStartEvent, {
188
+ passive: false
189
+ });
190
+
191
+ const mouseUpTouchEndEvent = () => {
192
+ this.previousEvent = null;
193
+ document.body.style.cursor = null;
194
+ this.getWrapper().style.cursor = 'grab';
195
+ document.removeEventListener('mousemove', setPositionEvent, {
196
+ passive: true
197
+ });
198
+ document.removeEventListener('touchmove', setPositionEvent, {
199
+ passive: true
200
+ });
201
+ };
202
+
203
+ document.addEventListener('mouseup', mouseUpTouchEndEvent, {
204
+ passive: true
205
+ });
206
+ document.addEventListener('touchend', mouseUpTouchEndEvent, {
207
+ passive: true
208
+ });
209
+
210
+ // Mouse wheel events
211
+ const mouseWheelEvent = (ev) => {
212
+ ev.preventDefault();
213
+
214
+ // Delta
215
+ let delta = ev.deltaY;
216
+ if (ev.deltaMode > 0) {
217
+ delta *= 100;
218
+ }
219
+
220
+ // Speed
221
+ const speed = this.options.zoomSpeedWheel;
222
+
223
+ // Adjust speed (https://github.com/anvaka/panzoom/blob/master/index.js#L884)
224
+ const sign = Math.sign(delta);
225
+ const deltaAdjustedSpeed = 1 - sign * Math.min(0.25, Math.abs((speed * delta) / 128));
226
+ const nextZoom = this.sanitizeZoom(this.zoom * deltaAdjustedSpeed);
227
+
228
+ // Get offset to center, then adjust
229
+ const offsetToCenter = this.getEventOffsetToCenter(ev);
230
+ this.adjustPositionByZoom(nextZoom, offsetToCenter.x, offsetToCenter.y);
231
+
232
+ // Update position
233
+ this.zoom = nextZoom;
234
+ this.setPosition(true);
235
+
236
+ // Trigger event
237
+ this.fireEvent('onZoom', this.getPosition());
238
+ };
239
+
240
+ this.getWrapper().addEventListener('wheel', mouseWheelEvent, {
241
+ passive: false
242
+ });
243
+
244
+ // Pinch events
245
+ const pointerDownEvent = (ev) => {
246
+ this.evCache.push(ev);
247
+ this.zoomCache = this.zoom;
248
+ this.xCache = this.x;
249
+ this.yCache = this.y;
250
+
251
+ if (this.evCache.length == 2) {
252
+ this.blockPan = true;
253
+ this.pinchDiffCache = this.getTouchEventsDistance(
254
+ this.evCache[0],
255
+ this.evCache[1]
256
+ );
257
+ this.touchEventsCenterCache = this.getTouchEventsCenter(
258
+ this.evCache[0],
259
+ this.evCache[1]
260
+ );
261
+ }
262
+ };
263
+
264
+ this.getWrapper().addEventListener('pointerdown', pointerDownEvent, {
265
+ passive: false
266
+ });
267
+
268
+ const pointerMoveEvent = (ev) => {
269
+ for (let i = 0; i < this.evCache.length; i++) {
270
+ if (ev.pointerId == this.evCache[i].pointerId) {
271
+ this.evCache[i] = ev;
272
+ break;
273
+ }
274
+ }
275
+
276
+ // Proceed if two touch gestures detected
277
+ if (this.evCache.length == 2) {
278
+ // Calculate distance between fingers
279
+ let pinchDiff = this.getTouchEventsDistance(
280
+ this.evCache[0],
281
+ this.evCache[1]
282
+ );
283
+ pinchDiff -= this.pinchDiffCache;
284
+
285
+ let pinchDiffPercent = pinchDiff / this.getContainer().clientWidth;
286
+ pinchDiffPercent *= this.options.zoomSpeedPinch;
287
+ pinchDiffPercent += 1;
288
+
289
+ const nextZoom = this.sanitizeZoom(this.zoomCache * pinchDiffPercent);
290
+
291
+ // Get offset to center, then adjust
292
+ const touchEventsCenter = this.getTouchEventsCenter(
293
+ this.evCache[0],
294
+ this.evCache[1]
295
+ );
296
+ const offsetToCenter = this.getEventOffsetToCenter({
297
+ target: this.evCache[0].target,
298
+ clientX: touchEventsCenter.clientX,
299
+ clientY: touchEventsCenter.clientY
300
+ });
301
+ this.adjustPositionByZoom(nextZoom, offsetToCenter.x, offsetToCenter.y);
302
+
303
+ // Adjust position when moving while pinching
304
+ const touchEventsCenterDiff = {
305
+ x: touchEventsCenter.clientX - this.touchEventsCenterCache.clientX,
306
+ y: touchEventsCenter.clientY - this.touchEventsCenterCache.clientY
307
+ };
308
+ this.x = this.xCache + touchEventsCenterDiff.x;
309
+ this.y = this.yCache + touchEventsCenterDiff.y;
310
+
311
+ // Update position
312
+ this.zoom = nextZoom;
313
+ this.setPosition(true);
314
+
315
+ // Trigger events
316
+ this.fireEvent('onZoom', this.getPosition());
317
+ this.fireEvent('onPan', this.getPosition());
318
+ }
319
+ };
320
+
321
+ this.getWrapper().addEventListener('pointermove', pointerMoveEvent, {
322
+ passive: false
323
+ });
324
+
325
+ const pointerUpEvent = (ev) => {
326
+ for (var i = 0; i < this.evCache.length; i++) {
327
+ if (this.evCache[i].pointerId == ev.pointerId) {
328
+ this.evCache.splice(i, 1);
329
+ break;
330
+ }
331
+ }
332
+
333
+ if (this.evCache.length < 2) {
334
+ this.blockPan = false;
335
+ }
336
+ };
337
+
338
+ ['pointerup', 'pointercancel', 'pointerout', 'pointerleave'].forEach(
339
+ (event) => {
340
+ this.getWrapper().addEventListener(event, pointerUpEvent, {
341
+ passive: false
342
+ });
343
+ }
344
+ );
345
+ }
346
+
347
+ // https://stackoverflow.com/questions/8389156/what-substitute-should-we-use-for-layerx-layery-since-they-are-deprecated-in-web
348
+ getEventOffsetToParent(ev) {
349
+ let el = ev.target;
350
+ let x = 0;
351
+ let y = 0;
352
+
353
+ while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
354
+ x += el.offsetLeft - el.scrollLeft;
355
+ y += el.offsetTop - el.scrollTop;
356
+ el = el.offsetParent;
357
+ }
358
+
359
+ x = ev.clientX - x;
360
+ y = ev.clientY - y;
361
+
362
+ return { x: x, y: y };
363
+ }
364
+
365
+ // Get the event offset to the center
366
+ getEventOffsetToCenter(ev) {
367
+ const wrapper = this.getWrapper();
368
+ const container = this.getContainer();
369
+ const diffX = wrapper.clientWidth - container.clientWidth;
370
+ const diffY = wrapper.clientHeight - container.clientHeight;
371
+ const centerX = diffX * 0.5;
372
+ const centerY = diffY * 0.5;
373
+
374
+ const offsetToCenter = {
375
+ x: 0,
376
+ y: 0
377
+ };
378
+
379
+ if (ev) {
380
+ const offsetToParent = this.getEventOffsetToParent(ev);
381
+ offsetToCenter.x =
382
+ (wrapper.clientWidth / 2 - offsetToParent.x - window.scrollX) * -1;
383
+ offsetToCenter.y =
384
+ (wrapper.clientHeight / 2 - offsetToParent.y - window.scrollY) * -1;
385
+ }
386
+
387
+ const offsetX = this.x - centerX - offsetToCenter.x;
388
+ const offsetY = this.y - centerY - offsetToCenter.y;
389
+
390
+ return {
391
+ x: offsetX,
392
+ y: offsetY
393
+ };
394
+ }
395
+
396
+ // Get the distance between two touch events
397
+ getTouchEventsDistance(ev1, ev2) {
398
+ return Math.abs(Math.hypot(ev1.pageX - ev1.pageX, ev1.pageY - ev2.pageY));
399
+ }
400
+
401
+ // Get the center point between two touch events
402
+ getTouchEventsCenter(ev1, ev2) {
403
+ return {
404
+ pageX: (ev1.pageX + ev2.pageX) / 2,
405
+ pageY: (ev1.pageY + ev2.pageX) / 2,
406
+ clientX: (ev1.clientX + ev2.clientX) / 2,
407
+ clientY: (ev1.clientY + ev2.clientY) / 2
408
+ };
409
+ }
410
+
411
+ // Get current position values
412
+ getPosition() {
413
+ return {
414
+ zoom: this.zoom,
415
+ x: this.x,
416
+ y: this.y
417
+ };
418
+ }
419
+
420
+ // Initialize
421
+ setPosition(instant) {
422
+ this.transition(!instant);
423
+
424
+ // Fit to bounds
425
+ if (this.options.bounds) {
426
+ const wrapper = this.getWrapper();
427
+ const container = this.getContainer();
428
+ const wrapperWidth = wrapper.clientWidth;
429
+ const wrapperHeight = wrapper.clientHeight;
430
+ const containerWidth = container.clientWidth;
431
+ const containerHeight = container.clientHeight;
432
+ const containerZoomWidth = containerWidth * this.zoom;
433
+ const containerZoomHeight = containerHeight * this.zoom;
434
+
435
+ const upperOffsetX = (containerWidth / 2) * (this.zoom - 1);
436
+ const lowerOffsetX = upperOffsetX * -1 + wrapperWidth - containerWidth;
437
+
438
+ if (containerZoomWidth < wrapperWidth) {
439
+ this.x < upperOffsetX && (this.x = upperOffsetX);
440
+ this.x > lowerOffsetX && (this.x = lowerOffsetX);
441
+ } else {
442
+ this.x = Math.min(this.x, upperOffsetX);
443
+ this.x = Math.max(this.x, lowerOffsetX);
444
+ }
445
+
446
+ const upperOffsetY = (containerHeight / 2) * (this.zoom - 1);
447
+ const lowerOffsetY = upperOffsetY * -1 + wrapperHeight - containerHeight;
448
+
449
+ if (containerZoomHeight < wrapperHeight) {
450
+ this.y < upperOffsetY && (this.y = upperOffsetY);
451
+ this.y > lowerOffsetY && (this.y = lowerOffsetY);
452
+ } else {
453
+ this.y = Math.min(this.y, upperOffsetY);
454
+ this.y = Math.max(this.y, lowerOffsetY);
455
+ }
456
+ }
457
+
458
+ // Set position
459
+ this.getContainer().style.transform =
460
+ 'matrix(' +
461
+ this.zoom +
462
+ ', 0, 0, ' +
463
+ this.zoom +
464
+ ', ' +
465
+ this.x +
466
+ ', ' +
467
+ this.y +
468
+ ')';
469
+
470
+ // Trigger event
471
+ this.fireEvent('onChange', this.getPosition());
472
+
473
+ // Return instance
474
+ return this;
475
+ }
476
+
477
+ // Sanitize zoom value
478
+ sanitizeZoom(zoom) {
479
+ // Get values for 'cover' and 'contain'
480
+ if (zoom == 'cover' || zoom == 'contain') {
481
+ const wrapper = this.getWrapper();
482
+ const container = this.getContainer();
483
+
484
+ const maxWidth = wrapper.clientWidth;
485
+ const maxHeight = wrapper.clientHeight;
486
+
487
+ const panZoomWidth = container.clientWidth;
488
+ const panZoomHeight = container.clientHeight;
489
+
490
+ const minZoomX = maxWidth / panZoomWidth;
491
+ const minZoomY = maxHeight / panZoomHeight;
492
+
493
+ // TODO is first cebter OK?
494
+ this.center(true, true);
495
+
496
+ if (zoom == 'cover') {
497
+ zoom = Math.max(minZoomX, minZoomY);
498
+ } else {
499
+ zoom = Math.min(minZoomX, minZoomY);
500
+ }
501
+ }
502
+
503
+ // Adjust for minZoom
504
+ if (zoom < this.options.minZoom) {
505
+ zoom = this.options.minZoom;
506
+ }
507
+
508
+ // Adjust for maxZoom
509
+ if (zoom > this.options.maxZoom) {
510
+ zoom = this.options.maxZoom;
511
+ }
512
+
513
+ return zoom;
514
+ }
515
+
516
+ // Getter for zoom
517
+ getZoom() {
518
+ return this.zoom;
519
+ }
520
+
521
+ // Zoom to
522
+ zoomTo(zoom, instant) {
523
+ // Sanitize zoom
524
+ zoom = this.sanitizeZoom(zoom);
525
+
526
+ // Get offset to center, then adjust
527
+ const offsetToCenter = this.getEventOffsetToCenter();
528
+ this.adjustPositionByZoom(zoom, offsetToCenter.x, offsetToCenter.y);
529
+
530
+ // Set new zoom
531
+ this.zoom = zoom;
532
+ this.setPosition(instant);
533
+
534
+ // Trigger event
535
+ this.fireEvent('onZoom', this.getPosition());
536
+
537
+ // Return instance
538
+ return this;
539
+ }
540
+
541
+ // Zoom in
542
+ zoomIn(step, instant) {
543
+ return this.zoomInOut(step, instant, 'in');
544
+ }
545
+
546
+ // Zoom out
547
+ zoomOut(step, instant) {
548
+ return this.zoomInOut(step, instant, 'out');
549
+ }
550
+
551
+ // Zoom in or out
552
+ zoomInOut(step, instant, direction) {
553
+ // Step is an optional attribute
554
+ if (step === true || step === false) {
555
+ instant = step;
556
+ step = null;
557
+ }
558
+ step = step || this.options.zoomStep;
559
+
560
+ // Calculate nextZoom
561
+ const currentZoom = this.zoom;
562
+ const zoomStep = (100 + step) / 100;
563
+ if (direction === 'out') {
564
+ zoomStep = 1 / zoomStep;
565
+ }
566
+ const nextZoom = currentZoom * zoomStep;
567
+
568
+ // Update zoom
569
+ return this.zoomTo(nextZoom, instant);
570
+ }
571
+
572
+ // Adjust position when zooming
573
+ adjustPositionByZoom(zoom, x, y) {
574
+ const currentZoom = this.zoom;
575
+ const zoomGrowth = (zoom - currentZoom) / currentZoom;
576
+
577
+ const container = this.getContainer();
578
+ const maxOffsetX = container.clientWidth * 0.5 * currentZoom;
579
+ const maxOffsetY = container.clientHeight * 0.5 * currentZoom;
580
+
581
+ x > maxOffsetX && (x = Math.min(x, maxOffsetX));
582
+ x < maxOffsetX * -1 && (x = Math.max(x, maxOffsetX * -1));
583
+
584
+ y > maxOffsetY && (y = Math.min(y, maxOffsetY));
585
+ y < maxOffsetY * -1 && (y = Math.max(y, maxOffsetY * -1));
586
+
587
+ this.x += x * zoomGrowth;
588
+ this.y += y * zoomGrowth;
589
+ }
590
+
591
+ // Center container within wrapper
592
+ center(instant, ignorePosition) {
593
+ return this.panTo(50, 50, instant, ignorePosition);
594
+ }
595
+
596
+ // Getters for pan
597
+ getPan(pixelValues) {
598
+ return {
599
+ x: this.getPanX(pixelValues),
600
+ y: this.getPanY(pixelValues)
601
+ };
602
+ }
603
+
604
+ getPanX(pixelValues) {
605
+ const wrapper = this.getWrapper();
606
+ const container = this.getContainer();
607
+ let panX = wrapper.clientWidth * 0.5 + this.x * -1;
608
+ panX += (this.zoom - 1) * (container.clientWidth * 0.5);
609
+ const percentX = (panX / (container.clientWidth * this.zoom)) * 100;
610
+ return pixelValues ? panX : percentX;
611
+ }
612
+
613
+ getPanY(pixelValues) {
614
+ const wrapper = this.getWrapper();
615
+ const container = this.getContainer();
616
+ let panY = wrapper.clientHeight * 0.5 + this.y * -1;
617
+ panY += (this.zoom - 1) * (container.clientHeight * 0.5);
618
+ const percentY = (panY / (container.clientHeight * this.zoom)) * 100;
619
+ return pixelValues ? panY : percentY;
620
+ }
621
+
622
+ // Pan to position
623
+ panTo(x, y, instant, ignorePosition) {
624
+ const wrapper = this.getWrapper();
625
+ const container = this.getContainer();
626
+
627
+ let panX = ((container.clientWidth * this.zoom * x) / 100) * -1;
628
+ panX += (this.zoom - 1) * (container.clientWidth * 0.5);
629
+ panX += wrapper.clientWidth * 0.5;
630
+
631
+ let panY = ((container.clientHeight * this.zoom * y) / 100) * -1;
632
+ panY += (this.zoom - 1) * (container.clientHeight * 0.5);
633
+ panY += wrapper.clientHeight * 0.5;
634
+
635
+ this.x = panX;
636
+ this.y = panY;
637
+
638
+ // Update position
639
+ if (!ignorePosition) {
640
+ this.setPosition(instant);
641
+ }
642
+
643
+ // Trigger event
644
+ this.fireEvent('onPan', this.getPosition());
645
+
646
+ // Return instance
647
+ return this;
648
+ }
649
+
650
+ panLeft(step, instant) {
651
+ return this.pan(step, instant, 'left');
652
+ }
653
+
654
+ panRight(step, instant) {
655
+ return this.pan(step, instant, 'right');
656
+ }
657
+
658
+ panUp(step, instant) {
659
+ return this.pan(step, instant, 'up');
660
+ }
661
+
662
+ panDown(step, instant) {
663
+ return this.pan(step, instant, 'down');
664
+ }
665
+
666
+ pan(step, instant, direction) {
667
+ if (step === true || step === false) {
668
+ instant = step;
669
+ step = null;
670
+ }
671
+ step = step || this.options.panStep;
672
+
673
+ const container = this.getContainer();
674
+ const panWidth = ((container.clientWidth * step) / 100) * this.zoom;
675
+ const panHeight = ((container.clientWidth * step) / 100) * this.zoom;
676
+
677
+ direction === 'left' && (this.x += panWidth * -1);
678
+ direction === 'right' && (this.x += panWidth);
679
+ direction === 'up' && (this.y += panHeight * -1);
680
+ direction === 'down' && (this.y += panHeight);
681
+
682
+ // Update position
683
+ this.setPosition(instant);
684
+
685
+ // Trigger event
686
+ this.fireEvent('onPan', this.getPosition());
687
+
688
+ // Return instance
689
+ return this;
690
+ }
691
+
692
+ // Get the wrapper element
693
+ getWrapper() {
694
+ // Return element if it is cached
695
+ if (this.wrapperElement) {
696
+ return this.wrapperElement;
697
+ }
698
+
699
+ // Abort if option is empty
700
+ if (!this.options.wrapperElement) {
701
+ console.error('The option wrapperElement is required.');
702
+ return null;
703
+ }
704
+
705
+ // Find the element if selector provided
706
+ if (typeof this.options.wrapperElement === 'string') {
707
+ this.options.wrapperElement = document.querySelector(
708
+ this.options.wrapperElement
709
+ );
710
+ }
711
+
712
+ // Cache element if valid
713
+ if (
714
+ this.options.wrapperElement &&
715
+ this.options.wrapperElement instanceof Element
716
+ ) {
717
+ this.wrapperElement = this.options.wrapperElement;
718
+ return this.options.wrapperElement;
719
+ }
720
+
721
+ console.error(
722
+ 'The option wrapperElement needs to be a valid selector string or an instance of Element.'
723
+ );
724
+ return null;
725
+ }
726
+
727
+ // Get the container element
728
+ getContainer() {
729
+ // Return element if it is cached
730
+ if (this.containerElement) {
731
+ return this.containerElement;
732
+ }
733
+
734
+ // Abort if option is empty
735
+ if (!this.options.panZoomElement) {
736
+ console.error('The option panZoomElement is required.');
737
+ return null;
738
+ }
739
+
740
+ // Find the element if selector provided
741
+ if (typeof this.options.panZoomElement === 'string') {
742
+ this.options.panZoomElement = document.querySelector(
743
+ this.options.panZoomElement
744
+ );
745
+ }
746
+
747
+ // Cache element if valid
748
+ if (
749
+ this.options.panZoomElement &&
750
+ this.options.panZoomElement instanceof Element
751
+ ) {
752
+ this.containerElement = this.options.panZoomElement;
753
+ return this.options.panZoomElement;
754
+ }
755
+
756
+ console.error(
757
+ 'The option panZoomElement needs to be a valid selector string or an instance of Element.'
758
+ );
759
+ return null;
760
+ }
761
+
762
+ // Enable or disable transitions
763
+ transition(enabled) {
764
+ this.getContainer().style.transition = enabled
765
+ ? 'transform ' + this.options.transitionSpeed + 'ms'
766
+ : null;
767
+ }
768
+ }
769
+
770
+ module.exports = domPanZoom;
771
+ //# sourceMappingURL=index.cjs.map