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