UNPKG

44.1 kBJavaScriptView Raw
1/*!
2 * lightgallery | 2.7.2 | September 20th 2023
3 * http://www.lightgalleryjs.com/
4 * Copyright (c) 2020 Sachin Neravath;
5 * @license GPLv3
6 */
7
8(function (global, factory) {
9 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10 typeof define === 'function' && define.amd ? define(factory) :
11 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory());
12}(this, (function () { 'use strict';
13
14 /*! *****************************************************************************
15 Copyright (c) Microsoft Corporation.
16
17 Permission to use, copy, modify, and/or distribute this software for any
18 purpose with or without fee is hereby granted.
19
20 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
23 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
24 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26 PERFORMANCE OF THIS SOFTWARE.
27 ***************************************************************************** */
28
29 var __assign = function() {
30 __assign = Object.assign || function __assign(t) {
31 for (var s, i = 1, n = arguments.length; i < n; i++) {
32 s = arguments[i];
33 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
34 }
35 return t;
36 };
37 return __assign.apply(this, arguments);
38 };
39
40 var zoomSettings = {
41 scale: 1,
42 zoom: true,
43 infiniteZoom: true,
44 actualSize: true,
45 showZoomInOutIcons: false,
46 actualSizeIcons: {
47 zoomIn: 'lg-zoom-in',
48 zoomOut: 'lg-zoom-out',
49 },
50 enableZoomAfter: 300,
51 zoomPluginStrings: {
52 zoomIn: 'Zoom in',
53 zoomOut: 'Zoom out',
54 viewActualSize: 'View actual size',
55 },
56 };
57
58 /**
59 * List of lightGallery events
60 * All events should be documented here
61 * Below interfaces are used to build the website documentations
62 * */
63 var lGEvents = {
64 afterAppendSlide: 'lgAfterAppendSlide',
65 init: 'lgInit',
66 hasVideo: 'lgHasVideo',
67 containerResize: 'lgContainerResize',
68 updateSlides: 'lgUpdateSlides',
69 afterAppendSubHtml: 'lgAfterAppendSubHtml',
70 beforeOpen: 'lgBeforeOpen',
71 afterOpen: 'lgAfterOpen',
72 slideItemLoad: 'lgSlideItemLoad',
73 beforeSlide: 'lgBeforeSlide',
74 afterSlide: 'lgAfterSlide',
75 posterClick: 'lgPosterClick',
76 dragStart: 'lgDragStart',
77 dragMove: 'lgDragMove',
78 dragEnd: 'lgDragEnd',
79 beforeNextSlide: 'lgBeforeNextSlide',
80 beforePrevSlide: 'lgBeforePrevSlide',
81 beforeClose: 'lgBeforeClose',
82 afterClose: 'lgAfterClose',
83 rotateLeft: 'lgRotateLeft',
84 rotateRight: 'lgRotateRight',
85 flipHorizontal: 'lgFlipHorizontal',
86 flipVertical: 'lgFlipVertical',
87 autoplay: 'lgAutoplay',
88 autoplayStart: 'lgAutoplayStart',
89 autoplayStop: 'lgAutoplayStop',
90 };
91
92 var ZOOM_TRANSITION_DURATION = 500;
93 var Zoom = /** @class */ (function () {
94 function Zoom(instance, $LG) {
95 // get lightGallery core plugin instance
96 this.core = instance;
97 this.$LG = $LG;
98 this.settings = __assign(__assign({}, zoomSettings), this.core.settings);
99 return this;
100 }
101 // Append Zoom controls. Actual size, Zoom-in, Zoom-out
102 Zoom.prototype.buildTemplates = function () {
103 var zoomIcons = this.settings.showZoomInOutIcons
104 ? "<button id=\"" + this.core.getIdName('lg-zoom-in') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-in lg-icon\"></button><button id=\"" + this.core.getIdName('lg-zoom-out') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-out lg-icon\"></button>"
105 : '';
106 if (this.settings.actualSize) {
107 zoomIcons += "<button id=\"" + this.core.getIdName('lg-actual-size') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['viewActualSize'] + "\" class=\"" + this.settings.actualSizeIcons.zoomIn + " lg-icon\"></button>";
108 }
109 this.core.outer.addClass('lg-use-transition-for-zoom');
110 this.core.$toolbar.first().append(zoomIcons);
111 };
112 /**
113 * @desc Enable zoom option only once the image is completely loaded
114 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted
115 *
116 * Zoom styles are defined under lg-zoomable CSS class.
117 */
118 Zoom.prototype.enableZoom = function (event) {
119 var _this = this;
120 // delay will be 0 except first time
121 var _speed = this.settings.enableZoomAfter + event.detail.delay;
122 // set _speed value 0 if gallery opened from direct url and if it is first slide
123 if (this.$LG('body').first().hasClass('lg-from-hash') &&
124 event.detail.delay) {
125 // will execute only once
126 _speed = 0;
127 }
128 else {
129 // Remove lg-from-hash to enable starting animation.
130 this.$LG('body').first().removeClass('lg-from-hash');
131 }
132 this.zoomableTimeout = setTimeout(function () {
133 if (!_this.isImageSlide(_this.core.index)) {
134 return;
135 }
136 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable');
137 if (event.detail.index === _this.core.index) {
138 _this.setZoomEssentials();
139 }
140 }, _speed + 30);
141 };
142 Zoom.prototype.enableZoomOnSlideItemLoad = function () {
143 // Add zoomable class
144 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this));
145 };
146 Zoom.prototype.getDragCords = function (e) {
147 return {
148 x: e.pageX,
149 y: e.pageY,
150 };
151 };
152 Zoom.prototype.getSwipeCords = function (e) {
153 var x = e.touches[0].pageX;
154 var y = e.touches[0].pageY;
155 return {
156 x: x,
157 y: y,
158 };
159 };
160 Zoom.prototype.getDragAllowedAxises = function (scale, scaleDiff) {
161 var $image = this.core
162 .getSlideItem(this.core.index)
163 .find('.lg-image')
164 .first()
165 .get();
166 var height = 0;
167 var width = 0;
168 var rect = $image.getBoundingClientRect();
169 if (scale) {
170 height = $image.offsetHeight * scale;
171 width = $image.offsetWidth * scale;
172 }
173 else if (scaleDiff) {
174 height = rect.height + scaleDiff * rect.height;
175 width = rect.width + scaleDiff * rect.width;
176 }
177 else {
178 height = rect.height;
179 width = rect.width;
180 }
181 var allowY = height > this.containerRect.height;
182 var allowX = width > this.containerRect.width;
183 return {
184 allowX: allowX,
185 allowY: allowY,
186 };
187 };
188 Zoom.prototype.setZoomEssentials = function () {
189 this.containerRect = this.core.$content.get().getBoundingClientRect();
190 };
191 /**
192 * @desc Image zoom
193 * Translate the wrap and scale the image to get better user experience
194 *
195 * @param {String} scale - Zoom decrement/increment value
196 */
197 Zoom.prototype.zoomImage = function (scale, scaleDiff, reposition, resetToMax) {
198 if (Math.abs(scaleDiff) <= 0)
199 return;
200 var offsetX = this.containerRect.width / 2 + this.containerRect.left;
201 var offsetY = this.containerRect.height / 2 +
202 this.containerRect.top +
203 this.scrollTop;
204 var originalX;
205 var originalY;
206 if (scale === 1) {
207 this.positionChanged = false;
208 }
209 var dragAllowedAxises = this.getDragAllowedAxises(0, scaleDiff);
210 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX;
211 if (this.positionChanged) {
212 originalX = this.left / (this.scale - scaleDiff);
213 originalY = this.top / (this.scale - scaleDiff);
214 this.pageX = offsetX - originalX;
215 this.pageY = offsetY - originalY;
216 this.positionChanged = false;
217 }
218 var possibleSwipeCords = this.getPossibleSwipeDragCords(scaleDiff);
219 var x;
220 var y;
221 var _x = offsetX - this.pageX;
222 var _y = offsetY - this.pageY;
223 if (scale - scaleDiff > 1) {
224 var scaleVal = (scale - scaleDiff) / Math.abs(scaleDiff);
225 _x =
226 (scaleDiff < 0 ? -_x : _x) +
227 this.left * (scaleVal + (scaleDiff < 0 ? -1 : 1));
228 _y =
229 (scaleDiff < 0 ? -_y : _y) +
230 this.top * (scaleVal + (scaleDiff < 0 ? -1 : 1));
231 x = _x / scaleVal;
232 y = _y / scaleVal;
233 }
234 else {
235 var scaleVal = (scale - scaleDiff) * scaleDiff;
236 x = _x * scaleVal;
237 y = _y * scaleVal;
238 }
239 if (reposition) {
240 if (allowX) {
241 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) {
242 x = possibleSwipeCords.minX;
243 }
244 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) {
245 x = possibleSwipeCords.maxX;
246 }
247 }
248 else {
249 if (scale > 1) {
250 if (x < possibleSwipeCords.minX) {
251 x = possibleSwipeCords.minX;
252 }
253 else if (x > possibleSwipeCords.maxX) {
254 x = possibleSwipeCords.maxX;
255 }
256 }
257 }
258 // @todo fix this
259 if (allowY) {
260 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) {
261 y = possibleSwipeCords.minY;
262 }
263 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) {
264 y = possibleSwipeCords.maxY;
265 }
266 }
267 else {
268 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out
269 if (scale > 1) {
270 //If image goes beyond viewport top, use the minim possible translate value
271 if (y < possibleSwipeCords.minY) {
272 y = possibleSwipeCords.minY;
273 }
274 else if (y > possibleSwipeCords.maxY) {
275 y = possibleSwipeCords.maxY;
276 }
277 }
278 }
279 }
280 this.setZoomStyles({
281 x: x,
282 y: y,
283 scale: scale,
284 });
285 this.left = x;
286 this.top = y;
287 if (resetToMax) {
288 this.setZoomImageSize();
289 }
290 };
291 Zoom.prototype.resetImageTranslate = function (index) {
292 if (!this.isImageSlide(index)) {
293 return;
294 }
295 var $image = this.core.getSlideItem(index).find('.lg-image').first();
296 this.imageReset = false;
297 $image.removeClass('reset-transition reset-transition-y reset-transition-x');
298 this.core.outer.removeClass('lg-actual-size');
299 $image.css('width', 'auto').css('height', 'auto');
300 setTimeout(function () {
301 $image.removeClass('no-transition');
302 }, 10);
303 };
304 Zoom.prototype.setZoomImageSize = function () {
305 var _this = this;
306 var $image = this.core
307 .getSlideItem(this.core.index)
308 .find('.lg-image')
309 .first();
310 setTimeout(function () {
311 var actualSizeScale = _this.getCurrentImageActualSizeScale();
312 if (_this.scale >= actualSizeScale) {
313 $image.addClass('no-transition');
314 _this.imageReset = true;
315 }
316 }, ZOOM_TRANSITION_DURATION);
317 setTimeout(function () {
318 var actualSizeScale = _this.getCurrentImageActualSizeScale();
319 if (_this.scale >= actualSizeScale) {
320 var dragAllowedAxises = _this.getDragAllowedAxises(_this.scale);
321 $image
322 .css('width', $image.get().naturalWidth + 'px')
323 .css('height', $image.get().naturalHeight + 'px');
324 _this.core.outer.addClass('lg-actual-size');
325 if (dragAllowedAxises.allowX && dragAllowedAxises.allowY) {
326 $image.addClass('reset-transition');
327 }
328 else if (dragAllowedAxises.allowX &&
329 !dragAllowedAxises.allowY) {
330 $image.addClass('reset-transition-x');
331 }
332 else if (!dragAllowedAxises.allowX &&
333 dragAllowedAxises.allowY) {
334 $image.addClass('reset-transition-y');
335 }
336 }
337 }, ZOOM_TRANSITION_DURATION + 50);
338 };
339 /**
340 * @desc apply scale3d to image and translate to image wrap
341 * @param {style} X,Y and scale
342 */
343 Zoom.prototype.setZoomStyles = function (style) {
344 var $imageWrap = this.core
345 .getSlideItem(this.core.index)
346 .find('.lg-img-wrap')
347 .first();
348 var $image = this.core
349 .getSlideItem(this.core.index)
350 .find('.lg-image')
351 .first();
352 var $dummyImage = this.core.outer
353 .find('.lg-current .lg-dummy-img')
354 .first();
355 this.scale = style.scale;
356 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
357 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
358 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)';
359 $imageWrap.css('transform', transform);
360 };
361 /**
362 * @param index - Index of the current slide
363 * @param event - event will be available only if the function is called on clicking/taping the imags
364 */
365 Zoom.prototype.setActualSize = function (index, event) {
366 var _this = this;
367 if (this.zoomInProgress) {
368 return;
369 }
370 this.zoomInProgress = true;
371 var currentItem = this.core.galleryItems[this.core.index];
372 this.resetImageTranslate(index);
373 setTimeout(function () {
374 // Allow zoom only on image
375 if (!currentItem.src ||
376 _this.core.outer.hasClass('lg-first-slide-loading')) {
377 return;
378 }
379 var scale = _this.getCurrentImageActualSizeScale();
380 var prevScale = _this.scale;
381 if (_this.core.outer.hasClass('lg-zoomed')) {
382 _this.scale = 1;
383 }
384 else {
385 _this.scale = _this.getScale(scale);
386 }
387 _this.setPageCords(event);
388 _this.beginZoom(_this.scale);
389 _this.zoomImage(_this.scale, _this.scale - prevScale, true, true);
390 }, 50);
391 setTimeout(function () {
392 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
393 }, 60);
394 setTimeout(function () {
395 _this.zoomInProgress = false;
396 }, ZOOM_TRANSITION_DURATION + 110);
397 };
398 Zoom.prototype.getNaturalWidth = function (index) {
399 var $image = this.core.getSlideItem(index).find('.lg-image').first();
400 var naturalWidth = this.core.galleryItems[index].width;
401 return naturalWidth
402 ? parseFloat(naturalWidth)
403 : $image.get().naturalWidth;
404 };
405 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) {
406 var _scale;
407 var scale;
408 if (naturalWidth >= width) {
409 _scale = naturalWidth / width;
410 scale = _scale || 2;
411 }
412 else {
413 scale = 1;
414 }
415 return scale;
416 };
417 Zoom.prototype.getCurrentImageActualSizeScale = function () {
418 var $image = this.core
419 .getSlideItem(this.core.index)
420 .find('.lg-image')
421 .first();
422 var width = $image.get().offsetWidth;
423 var naturalWidth = this.getNaturalWidth(this.core.index) || width;
424 return this.getActualSizeScale(naturalWidth, width);
425 };
426 Zoom.prototype.getPageCords = function (event) {
427 var cords = {};
428 if (event) {
429 cords.x = event.pageX || event.touches[0].pageX;
430 cords.y = event.pageY || event.touches[0].pageY;
431 }
432 else {
433 var containerRect = this.core.$content
434 .get()
435 .getBoundingClientRect();
436 cords.x = containerRect.width / 2 + containerRect.left;
437 cords.y =
438 containerRect.height / 2 + this.scrollTop + containerRect.top;
439 }
440 return cords;
441 };
442 Zoom.prototype.setPageCords = function (event) {
443 var pageCords = this.getPageCords(event);
444 this.pageX = pageCords.x;
445 this.pageY = pageCords.y;
446 };
447 Zoom.prototype.manageActualPixelClassNames = function () {
448 var $actualSize = this.core.getElementById('lg-actual-size');
449 $actualSize
450 .removeClass(this.settings.actualSizeIcons.zoomIn)
451 .addClass(this.settings.actualSizeIcons.zoomOut);
452 };
453 // If true, zoomed - in else zoomed out
454 Zoom.prototype.beginZoom = function (scale) {
455 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
456 if (scale > 1) {
457 this.core.outer.addClass('lg-zoomed');
458 this.manageActualPixelClassNames();
459 }
460 else {
461 this.resetZoom();
462 }
463 return scale > 1;
464 };
465 Zoom.prototype.getScale = function (scale) {
466 var actualSizeScale = this.getCurrentImageActualSizeScale();
467 if (scale < 1) {
468 scale = 1;
469 }
470 else if (scale > actualSizeScale) {
471 scale = actualSizeScale;
472 }
473 return scale;
474 };
475 Zoom.prototype.init = function () {
476 var _this = this;
477 if (!this.settings.zoom) {
478 return;
479 }
480 this.buildTemplates();
481 this.enableZoomOnSlideItemLoad();
482 var tapped = null;
483 this.core.outer.on('dblclick.lg', function (event) {
484 if (!_this.$LG(event.target).hasClass('lg-image')) {
485 return;
486 }
487 _this.setActualSize(_this.core.index, event);
488 });
489 this.core.outer.on('touchstart.lg', function (event) {
490 var $target = _this.$LG(event.target);
491 if (event.touches.length === 1 && $target.hasClass('lg-image')) {
492 if (!tapped) {
493 tapped = setTimeout(function () {
494 tapped = null;
495 }, 300);
496 }
497 else {
498 clearTimeout(tapped);
499 tapped = null;
500 event.preventDefault();
501 _this.setActualSize(_this.core.index, event);
502 }
503 }
504 });
505 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () {
506 if (!_this.core.lgOpened ||
507 !_this.isImageSlide(_this.core.index) ||
508 _this.core.touchAction) {
509 return;
510 }
511 var _LGel = _this.core
512 .getSlideItem(_this.core.index)
513 .find('.lg-img-wrap')
514 .first();
515 _this.top = 0;
516 _this.left = 0;
517 _this.setZoomEssentials();
518 _this.setZoomSwipeStyles(_LGel, { x: 0, y: 0 });
519 _this.positionChanged = true;
520 });
521 // Update zoom on resize and orientationchange
522 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () {
523 if (!_this.core.lgOpened)
524 return;
525 _this.scrollTop = _this.$LG(window).scrollTop();
526 });
527 this.core.getElementById('lg-zoom-out').on('click.lg', function () {
528 // Allow zoom only on image
529 if (!_this.isImageSlide(_this.core.index)) {
530 return;
531 }
532 var timeout = 0;
533 if (_this.imageReset) {
534 _this.resetImageTranslate(_this.core.index);
535 timeout = 50;
536 }
537 setTimeout(function () {
538 var scale = _this.scale - _this.settings.scale;
539 if (scale < 1) {
540 scale = 1;
541 }
542 _this.beginZoom(scale);
543 _this.zoomImage(scale, -_this.settings.scale, true, !_this.settings.infiniteZoom);
544 }, timeout);
545 });
546 this.core.getElementById('lg-zoom-in').on('click.lg', function () {
547 _this.zoomIn();
548 });
549 this.core.getElementById('lg-actual-size').on('click.lg', function () {
550 _this.setActualSize(_this.core.index);
551 });
552 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () {
553 _this.core.outer.find('.lg-item').removeClass('lg-zoomable');
554 });
555 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () {
556 _this.scrollTop = _this.$LG(window).scrollTop();
557 // Set the initial value center
558 _this.pageX = _this.core.outer.width() / 2;
559 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop;
560 _this.scale = 1;
561 });
562 // Reset zoom on slide change
563 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) {
564 var prevIndex = event.detail.prevIndex;
565 _this.scale = 1;
566 _this.positionChanged = false;
567 _this.zoomInProgress = false;
568 _this.resetZoom(prevIndex);
569 _this.resetImageTranslate(prevIndex);
570 if (_this.isImageSlide(_this.core.index)) {
571 _this.setZoomEssentials();
572 }
573 });
574 // Drag option after zoom
575 this.zoomDrag();
576 this.pinchZoom();
577 this.zoomSwipe();
578 // Store the zoomable timeout value just to clear it while closing
579 this.zoomableTimeout = false;
580 this.positionChanged = false;
581 this.zoomInProgress = false;
582 };
583 Zoom.prototype.zoomIn = function () {
584 // Allow zoom only on image
585 if (!this.isImageSlide(this.core.index)) {
586 return;
587 }
588 var scale = this.scale + this.settings.scale;
589 if (!this.settings.infiniteZoom) {
590 scale = this.getScale(scale);
591 }
592 this.beginZoom(scale);
593 this.zoomImage(scale, Math.min(this.settings.scale, scale - this.scale), true, !this.settings.infiniteZoom);
594 };
595 // Reset zoom effect
596 Zoom.prototype.resetZoom = function (index) {
597 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition');
598 var $actualSize = this.core.getElementById('lg-actual-size');
599 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index);
600 $actualSize
601 .removeClass(this.settings.actualSizeIcons.zoomOut)
602 .addClass(this.settings.actualSizeIcons.zoomIn);
603 $item.find('.lg-img-wrap').first().removeAttr('style');
604 $item.find('.lg-image').first().removeAttr('style');
605 this.scale = 1;
606 this.left = 0;
607 this.top = 0;
608 // Reset pagx pagy values to center
609 this.setPageCords();
610 };
611 Zoom.prototype.getTouchDistance = function (e) {
612 return Math.sqrt((e.touches[0].pageX - e.touches[1].pageX) *
613 (e.touches[0].pageX - e.touches[1].pageX) +
614 (e.touches[0].pageY - e.touches[1].pageY) *
615 (e.touches[0].pageY - e.touches[1].pageY));
616 };
617 Zoom.prototype.pinchZoom = function () {
618 var _this = this;
619 var startDist = 0;
620 var pinchStarted = false;
621 var initScale = 1;
622 var prevScale = 0;
623 var $item = this.core.getSlideItem(this.core.index);
624 this.core.outer.on('touchstart.lg', function (e) {
625 $item = _this.core.getSlideItem(_this.core.index);
626 if (!_this.isImageSlide(_this.core.index)) {
627 return;
628 }
629 if (e.touches.length === 2) {
630 e.preventDefault();
631 if (_this.core.outer.hasClass('lg-first-slide-loading')) {
632 return;
633 }
634 initScale = _this.scale || 1;
635 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
636 _this.setPageCords(e);
637 _this.resetImageTranslate(_this.core.index);
638 _this.core.touchAction = 'pinch';
639 startDist = _this.getTouchDistance(e);
640 }
641 });
642 this.core.$inner.on('touchmove.lg', function (e) {
643 if (e.touches.length === 2 &&
644 _this.core.touchAction === 'pinch' &&
645 (_this.$LG(e.target).hasClass('lg-item') ||
646 $item.get().contains(e.target))) {
647 e.preventDefault();
648 var endDist = _this.getTouchDistance(e);
649 var distance = startDist - endDist;
650 if (!pinchStarted && Math.abs(distance) > 5) {
651 pinchStarted = true;
652 }
653 if (pinchStarted) {
654 prevScale = _this.scale;
655 var _scale = Math.max(1, initScale + -distance * 0.02);
656 _this.scale =
657 Math.round((_scale + Number.EPSILON) * 100) / 100;
658 var diff = _this.scale - prevScale;
659 _this.zoomImage(_this.scale, Math.round((diff + Number.EPSILON) * 100) / 100, false, false);
660 }
661 }
662 });
663 this.core.$inner.on('touchend.lg', function (e) {
664 if (_this.core.touchAction === 'pinch' &&
665 (_this.$LG(e.target).hasClass('lg-item') ||
666 $item.get().contains(e.target))) {
667 pinchStarted = false;
668 startDist = 0;
669 if (_this.scale <= 1) {
670 _this.resetZoom();
671 }
672 else {
673 var actualSizeScale = _this.getCurrentImageActualSizeScale();
674 if (_this.scale >= actualSizeScale) {
675 var scaleDiff = actualSizeScale - _this.scale;
676 if (scaleDiff === 0) {
677 scaleDiff = 0.01;
678 }
679 _this.zoomImage(actualSizeScale, scaleDiff, false, true);
680 }
681 _this.manageActualPixelClassNames();
682 _this.core.outer.addClass('lg-zoomed');
683 }
684 _this.core.touchAction = undefined;
685 }
686 });
687 };
688 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration) {
689 var distanceXnew = endCoords.x - startCoords.x;
690 var distanceYnew = endCoords.y - startCoords.y;
691 var speedX = Math.abs(distanceXnew) / touchDuration + 1;
692 var speedY = Math.abs(distanceYnew) / touchDuration + 1;
693 if (speedX > 2) {
694 speedX += 1;
695 }
696 if (speedY > 2) {
697 speedY += 1;
698 }
699 distanceXnew = distanceXnew * speedX;
700 distanceYnew = distanceYnew * speedY;
701 var _LGel = this.core
702 .getSlideItem(this.core.index)
703 .find('.lg-img-wrap')
704 .first();
705 var distance = {};
706 distance.x = this.left + distanceXnew;
707 distance.y = this.top + distanceYnew;
708 var possibleSwipeCords = this.getPossibleSwipeDragCords();
709 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) {
710 if (allowY) {
711 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
712 distance.y = possibleSwipeCords.minY;
713 }
714 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
715 distance.y = possibleSwipeCords.maxY;
716 }
717 }
718 if (allowX) {
719 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
720 distance.x = possibleSwipeCords.minX;
721 }
722 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
723 distance.x = possibleSwipeCords.maxX;
724 }
725 }
726 if (allowY) {
727 this.top = distance.y;
728 }
729 else {
730 distance.y = this.top;
731 }
732 if (allowX) {
733 this.left = distance.x;
734 }
735 else {
736 distance.x = this.left;
737 }
738 this.setZoomSwipeStyles(_LGel, distance);
739 this.positionChanged = true;
740 }
741 };
742 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) {
743 var distance = {};
744 if (allowY) {
745 distance.y = this.top + (endCoords.y - startCoords.y);
746 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
747 var diffMinY = possibleSwipeCords.minY - distance.y;
748 distance.y = possibleSwipeCords.minY - diffMinY / 6;
749 }
750 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
751 var diffMaxY = distance.y - possibleSwipeCords.maxY;
752 distance.y = possibleSwipeCords.maxY + diffMaxY / 6;
753 }
754 }
755 else {
756 distance.y = this.top;
757 }
758 if (allowX) {
759 distance.x = this.left + (endCoords.x - startCoords.x);
760 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
761 var diffMinX = possibleSwipeCords.minX - distance.x;
762 distance.x = possibleSwipeCords.minX - diffMinX / 6;
763 }
764 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
765 var difMaxX = distance.x - possibleSwipeCords.maxX;
766 distance.x = possibleSwipeCords.maxX + difMaxX / 6;
767 }
768 }
769 else {
770 distance.x = this.left;
771 }
772 return distance;
773 };
774 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) {
775 return x >= minX;
776 };
777 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) {
778 return x <= maxX;
779 };
780 Zoom.prototype.isBeyondPossibleTop = function (y, minY) {
781 return y >= minY;
782 };
783 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) {
784 return y <= maxY;
785 };
786 Zoom.prototype.isImageSlide = function (index) {
787 var currentItem = this.core.galleryItems[index];
788 return this.core.getSlideType(currentItem) === 'image';
789 };
790 Zoom.prototype.getPossibleSwipeDragCords = function (scale) {
791 var $image = this.core
792 .getSlideItem(this.core.index)
793 .find('.lg-image')
794 .first();
795 var bottom = this.core.mediaContainerPosition.bottom;
796 var imgRect = $image.get().getBoundingClientRect();
797 var imageHeight = imgRect.height;
798 var imageWidth = imgRect.width;
799 if (scale) {
800 imageHeight = imageHeight + scale * imageHeight;
801 imageWidth = imageWidth + scale * imageWidth;
802 }
803 var minY = (imageHeight - this.containerRect.height) / 2;
804 var maxY = (this.containerRect.height - imageHeight) / 2 + bottom;
805 var minX = (imageWidth - this.containerRect.width) / 2;
806 var maxX = (this.containerRect.width - imageWidth) / 2;
807 var possibleSwipeCords = {
808 minY: minY,
809 maxY: maxY,
810 minX: minX,
811 maxX: maxX,
812 };
813 return possibleSwipeCords;
814 };
815 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) {
816 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)');
817 };
818 Zoom.prototype.zoomSwipe = function () {
819 var _this = this;
820 var startCoords = {};
821 var endCoords = {};
822 var isMoved = false;
823 // Allow x direction drag
824 var allowX = false;
825 // Allow Y direction drag
826 var allowY = false;
827 var startTime = new Date();
828 var endTime = new Date();
829 var possibleSwipeCords;
830 var _LGel;
831 var $item = this.core.getSlideItem(this.core.index);
832 this.core.$inner.on('touchstart.lg', function (e) {
833 // Allow zoom only on image
834 if (!_this.isImageSlide(_this.core.index)) {
835 return;
836 }
837 $item = _this.core.getSlideItem(_this.core.index);
838 if ((_this.$LG(e.target).hasClass('lg-item') ||
839 $item.get().contains(e.target)) &&
840 e.touches.length === 1 &&
841 _this.core.outer.hasClass('lg-zoomed')) {
842 e.preventDefault();
843 startTime = new Date();
844 _this.core.touchAction = 'zoomSwipe';
845 _LGel = _this.core
846 .getSlideItem(_this.core.index)
847 .find('.lg-img-wrap')
848 .first();
849 var dragAllowedAxises = _this.getDragAllowedAxises(0);
850 allowY = dragAllowedAxises.allowY;
851 allowX = dragAllowedAxises.allowX;
852 if (allowX || allowY) {
853 startCoords = _this.getSwipeCords(e);
854 }
855 possibleSwipeCords = _this.getPossibleSwipeDragCords();
856 // reset opacity and transition duration
857 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition');
858 }
859 });
860 this.core.$inner.on('touchmove.lg', function (e) {
861 if (e.touches.length === 1 &&
862 _this.core.touchAction === 'zoomSwipe' &&
863 (_this.$LG(e.target).hasClass('lg-item') ||
864 $item.get().contains(e.target))) {
865 e.preventDefault();
866 _this.core.touchAction = 'zoomSwipe';
867 endCoords = _this.getSwipeCords(e);
868 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
869 if (Math.abs(endCoords.x - startCoords.x) > 15 ||
870 Math.abs(endCoords.y - startCoords.y) > 15) {
871 isMoved = true;
872 _this.setZoomSwipeStyles(_LGel, distance);
873 }
874 }
875 });
876 this.core.$inner.on('touchend.lg', function (e) {
877 if (_this.core.touchAction === 'zoomSwipe' &&
878 (_this.$LG(e.target).hasClass('lg-item') ||
879 $item.get().contains(e.target))) {
880 e.preventDefault();
881 _this.core.touchAction = undefined;
882 _this.core.outer.removeClass('lg-zoom-dragging');
883 if (!isMoved) {
884 return;
885 }
886 isMoved = false;
887 endTime = new Date();
888 var touchDuration = endTime.valueOf() - startTime.valueOf();
889 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration);
890 }
891 });
892 };
893 Zoom.prototype.zoomDrag = function () {
894 var _this = this;
895 var startCoords = {};
896 var endCoords = {};
897 var isDragging = false;
898 var isMoved = false;
899 // Allow x direction drag
900 var allowX = false;
901 // Allow Y direction drag
902 var allowY = false;
903 var startTime;
904 var endTime;
905 var possibleSwipeCords;
906 var _LGel;
907 this.core.outer.on('mousedown.lg.zoom', function (e) {
908 // Allow zoom only on image
909 if (!_this.isImageSlide(_this.core.index)) {
910 return;
911 }
912 var $item = _this.core.getSlideItem(_this.core.index);
913 if (_this.$LG(e.target).hasClass('lg-item') ||
914 $item.get().contains(e.target)) {
915 startTime = new Date();
916 _LGel = _this.core
917 .getSlideItem(_this.core.index)
918 .find('.lg-img-wrap')
919 .first();
920 var dragAllowedAxises = _this.getDragAllowedAxises(0);
921 allowY = dragAllowedAxises.allowY;
922 allowX = dragAllowedAxises.allowX;
923 if (_this.core.outer.hasClass('lg-zoomed')) {
924 if (_this.$LG(e.target).hasClass('lg-object') &&
925 (allowX || allowY)) {
926 e.preventDefault();
927 startCoords = _this.getDragCords(e);
928 possibleSwipeCords = _this.getPossibleSwipeDragCords();
929 isDragging = true;
930 _this.core.outer
931 .removeClass('lg-grab')
932 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging');
933 // reset opacity and transition duration
934 }
935 }
936 }
937 });
938 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) {
939 if (isDragging) {
940 isMoved = true;
941 endCoords = _this.getDragCords(e);
942 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
943 _this.setZoomSwipeStyles(_LGel, distance);
944 }
945 });
946 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) {
947 if (isDragging) {
948 endTime = new Date();
949 isDragging = false;
950 _this.core.outer.removeClass('lg-zoom-dragging');
951 // Fix for chrome mouse move on click
952 if (isMoved &&
953 (startCoords.x !== endCoords.x ||
954 startCoords.y !== endCoords.y)) {
955 endCoords = _this.getDragCords(e);
956 var touchDuration = endTime.valueOf() - startTime.valueOf();
957 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration);
958 }
959 isMoved = false;
960 }
961 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
962 });
963 };
964 Zoom.prototype.closeGallery = function () {
965 this.resetZoom();
966 this.zoomInProgress = false;
967 };
968 Zoom.prototype.destroy = function () {
969 // Unbind all events added by lightGallery zoom plugin
970 this.$LG(window).off(".lg.zoom.global" + this.core.lgId);
971 this.core.LGel.off('.lg.zoom');
972 this.core.LGel.off('.zoom');
973 clearTimeout(this.zoomableTimeout);
974 this.zoomableTimeout = false;
975 };
976 return Zoom;
977 }());
978
979 return Zoom;
980
981})));
982//# sourceMappingURL=lg-zoom.umd.js.map