UNPKG

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