PageSourceSearch

https://www.winterthur.org/wp-content/plugins/grid-kit-premium/js/…/lightgallery-modules/lg-zoom.js?ver=5.9.13

js winterthur.org collected 2026-09-24 08:59:48 UTC 17,673 bytes, 527 lines download raw bytes

1/*! lg-zoom - v1.1.0 - 2017-08-08
2* http://sachinchoolur.github.io/lightGallery
3* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
4
5(function (root, factory) {
6  if (typeof define === 'function' && define.amd) {
7    // AMD. Register as an anonymous module unless amdModuleId is set
8    define(['jquery'], function (a0) {
9      return (factory(a0));
10    });
11  } else if (typeof exports === 'object') {
12    // Node. Does not work with strict CommonJS, but
13    // only CommonJS-like environments that support module.exports,
14    // like Node.
15    module.exports = factory(require('jquery'));
16  } else {
17    factory(jQuery);
18  }
19}(this, function ($) {
20
21(function() {
22
23    'use strict';
24
25    var getUseLeft = function() {
26        var useLeft = false;
27        var isChrome = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
28        if (isChrome && parseInt(isChrome[2], 10) < 54) {
29            useLeft = true;
30        }
31
32        return useLeft;
33    };
34
35    var defaults = {
36        scale: 1,
37        zoom: true,
38        actualSize: true,
39        enableZoomAfter: 300,
40        useLeftForZoom: getUseLeft()
41    };
42
43    var Zoom = function(element) {
44
45        this.core = $(element).data('lightGallery');
46
47        this.core.s = $.extend({}, defaults, this.core.s);
48
49        if (this.core.s.zoom && this.core.doCss()) {
50            this.init();
51
52            // Store the zoomable timeout value just to clear it while closing
53            this.zoomabletimeout = false;
54
55            // Set the initial value center
56            this.pageX = $(window).width() / 2;
57            this.pageY = ($(window).height() / 2) + $(window).scrollTop();
58        }
59
60        return this;
61    };
62
63    Zoom.prototype.init = function() {
64
65        var _this = this;
66        var zoomIcons = '<span id="lg-zoom-in" class="lg-icon"></span><span id="lg-zoom-out" class="lg-icon"></span>';
67
68        if (_this.core.s.actualSize) {
69            zoomIcons += '<span id="lg-actual-size" class="lg-icon"></span>';
70        }
71
72        if (_this.core.s.useLeftForZoom) {
73            _this.core.$outer.addClass('lg-use-left-for-zoom');
74        } else {
75            _this.core.$outer.addClass('lg-use-transition-for-zoom');
76        }
77
78        this.core.$outer.find('.lg-toolbar').append(zoomIcons);
79
80        // Add zoomable class
81        _this.core.$el.on('onSlideItemLoad.lg.tm.zoom', function(event, index, delay) {
82
83            // delay will be 0 except first time
84            var _speed = _this.core.s.enableZoomAfter + delay;
85
86            // set _speed value 0 if gallery opened from direct url and if it is first slide
87            if ($('body').hasClass('lg-from-hash') && delay) {
88
89                // will execute only once
90                _speed = 0;
91            } else {
92
93                // Remove lg-from-hash to enable starting animation.
94                $('body').removeClass('lg-from-hash');
95            }
96
97            _this.zoomabletimeout = setTimeout(function() {
98                _this.core.$slide.eq(index).addClass('lg-zoomable');
99            }, _speed + 30);
100        });
101
102        var scale = 1;
103        /**
104         * @desc Image zoom
105         * Translate the wrap and scale the image to get better user experience
106         *
107         * @param {String} scaleVal - Zoom decrement/increment value
108         */
109        var zoom = function(scaleVal) {
110
111            var $image = _this.core.$outer.find('.lg-current .lg-image');
112            var _x;
113            var _y;
114
115            // Find offset manually to avoid issue after zoom
116            var offsetX = ($(window).width() - $image.prop('offsetWidth')) / 2;
117            var offsetY = (($(window).height() - $image.prop('offsetHeight')) / 2) + $(window).scrollTop();
118
119            _x = _this.pageX - offsetX;
120            _y = _this.pageY - offsetY;
121
122            var x = (scaleVal - 1) * (_x);
123            var y = (scaleVal - 1) * (_y);
124
125            $image.css('transform', 'scale3d(' + scaleVal + ', ' + scaleVal + ', 1)').attr('data-scale', scaleVal);
126
127            if (_this.core.s.useLeftForZoom) {
128                $image.parent().css({
129                    left: -x + 'px',
130                    top: -y + 'px'
131                }).attr('data-x', x).attr('data-y', y);
132            } else {
133                $image.parent().css('transform', 'translate3d(-' + x + 'px, -' + y + 'px, 0)').attr('data-x', x).attr('data-y', y);
134            }
135        };
136
137        var callScale = function() {
138            if (scale > 1) {
139                _this.core.$outer.addClass('lg-zoomed');
140            } else {
141                _this.resetZoom();
142            }
143
144            if (scale < 1) {
145                scale = 1;
146            }
147
148            zoom(scale);
149        };
150
151        var actualSize = function(event, $image, index, fromIcon) {
152            var w = $image.prop('offsetWidth');
153            var nw;
154            if (_this.core.s.dynamic) {
155                nw = _this.core.s.dynamicEl[index].width || $image[0].naturalWi
155dth || w;
156            } else {
157                nw = _this.core.$items.eq(index).attr('data-width') || $image[0].naturalWidth || w;
158            }
159
160            var _scale;
161
162            if (_this.core.$outer.hasClass('lg-zoomed')) {
163                scale = 1;
164            } else {
165                if (nw > w) {
166                    _scale = nw / w;
167                    scale = _scale || 2;
168                }
169            }
170
171            if (fromIcon) {
172                _this.pageX = $(window).width() / 2;
173                _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
174            } else {
175                _this.pageX = event.pageX || event.originalEvent.targetTouches[0].pageX;
176                _this.pageY = event.pageY || event.originalEvent.targetTouches[0].pageY;
177            }
178
179            callScale();
180            setTimeout(function() {
181                _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
182            }, 10);
183        };
184
185        var tapped = false;
186
187        // event triggered after appending slide content
188        _this.core.$el.on('onAferAppendSlide.lg.tm.zoom', function(event, index) {
189
190            // Get the current element
191            var $image = _this.core.$slide.eq(index).find('.lg-image');
192
193            $image.on('dblclick', function(event) {
194                actualSize(event, $image, index);
195            });
196
197            $image.on('touchstart', function(event) {
198                if (!tapped) {
199                    tapped = setTimeout(function() {
200                        tapped = null;
201                    }, 300);
202                } else {
203                    clearTimeout(tapped);
204                    tapped = null;
205                    actualSize(event, $image, index);
206                }
207
208                event.preventDefault();
209            });
210
211        });
212
213        // Update zoom on resize and orientationchange
214        $(window).on('resize.lg.zoom scroll.lg.zoom orientationchange.lg.zoom', function() {
215            _this.pageX = $(window).width() / 2;
216            _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
217            zoom(scale);
218        });
219
220        $('#lg-zoom-out').on('click.lg', function() {
221            if (_this.core.$outer.find('.lg-current .lg-image').length) {
222                scale -= _this.core.s.scale;
223                callScale();
224            }
225        });
226
227        $('#lg-zoom-in').on('click.lg', function() {
228            if (_this.core.$outer.find('.lg-current .lg-image').length) {
229                scale += _this.core.s.scale;
230                callScale();
231            }
232        });
233
234        $('#lg-actual-size').on('click.lg', function(event) {
235            actualSize(event, _this.core.$slide.eq(_this.core.index).find('.lg-image'), _this.core.index, true);
236        });
237
238        // Reset zoom on slide change
239        _this.core.$el.on('onBeforeSlide.lg.tm', function() {
240            scale = 1;
241            _this.resetZoom();
242        });
243
244        // Drag option after zoom
245        _this.zoomDrag();
246
247        _this.zoomSwipe();
248
249    };
250
251    // Reset zoom effect
252    Zoom.prototype.resetZoom = function() {
253        this.core.$outer.removeClass('lg-zoomed');
254        this.core.$slide.find('.lg-img-wrap').removeAttr('style data-x data-y');
255        this.core.$slide.find('.lg-image').removeAttr('style data-scale');
256
257        // Reset pagx pagy values to center
258        this.pageX = $(window).width() / 2;
259        this.pageY = ($(window).height() / 2) + $(window).scrollTop();
260    };
261
262    Zoom.prototype.zoomSwipe = function() {
263        var _this = this;
264        var startCoords = {};
265        var endCoords = {};
266        var isMoved = false;
267
268        // Allow x direction drag
269        var allowX = false;
270
271        // Allow Y direction drag
272        var allowY = false;
273
274        _this.core.$slide.on('touchstart.lg', function(e) {
275
276            if (_this.core.$outer.hasClass('lg-zoomed')) {
277                var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
278
279                allowY = $image.prop('offsetHeight') * $image.attr('data-scale') > _this.core.$outer.find('.lg').height();
280                allowX = $image.prop('offsetWidth') * $image.attr('data-scale') > _this.core.$outer.find('.lg').width();
281                if ((allowX || allowY)) {
282                    e.preventDefault();
283                    startCoords = {
284                        x: e.originalEvent.targetTouches[0].pageX,
285                        y: e.originalEvent.targetTouches[0].pageY
286                    };
287                }
288            }
289
290        });
291
292        _this.core.$slide.on('touchmove.lg', function(e) {
293
294            if (_this.core.$outer.hasClass('lg-zoomed')) {
295
296                var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
297                var distanceX;
298                var distanceY;
299
300                e.preventDefault();
301                isMoved = true;
302
303                endCoords = {
304                    x: e.originalEvent.targetTouches[0].pageX,
305                    y: e.originalEvent.targetTouches[0].pageY
306                };
307
308                // reset opacity and transition duration
309                _this.core.$outer.addClass('lg-zoom-dragging');
310
311                if (allowY) {
312                    distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
313                } else {
314                    distanceY = -Math.abs(_$el.attr('data-y'));
315                }
316
317                if (allowX) {
318                    distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
319                } else {
320                    distanceX = -Math.abs(_$el.attr('data-x'));
321                }
322
323                if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
324
325                    if (_this.core.s.useLeftForZoom) {
326                        _$el.css({
327                            left: distanceX + 'px',
328                            top: distanceY + 'px'
329                        });
330                    } else {
331                        _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
332                    }
333                }
334
335            }
336
337        });
338
339        _this.core.$slide.on('touchend.lg', function() {
340            if (_this.core.$outer.hasClass('lg-zoomed')) {
341                if (isMoved) {
342                    isMoved = false;
343                    _this.core.$outer.removeClass('lg-zoom-dragging');
344                    _this.touchendZoom(startCoords, endCoords, allowX, allowY);
345
346                }
347            }
348        });
349
350    };
351
352    Zoom.prototype.zoomDrag = function() {
353
354        var _this = this;
355        var startCoords = {};
356        var endCoords = {};
357        var isDraging = false;
358        var isMoved = false;
359
360        // Allow x direction drag
361        var allowX = false;
362
363        // Allow Y direction drag
364        var allowY = false;
365
366        _this.core.$slide.on('mousedown.lg.zoom', function(e) {
367
368            // execute only on .lg-object
369            var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
370
371            allowY = $image.prop('offsetHeight') * $image.attr('data-scale') > _this.core.$outer.find('.lg').height();
372            allowX = $image.prop('offsetWidth') * $image.attr('data-scale') > _this.core.$outer.find('.lg').width();
373
374            if (_this.core.$outer.hasClass('lg-zoomed')) {
375                if ($(e.target).hasClass('lg-object') && (allowX || allowY)) {
376                    e.preventDefault();
377                    startCoords = {
378                        x: e.pageX,
379                        y: e.pageY
380                    };
381
382                    isDraging = true;
383
384                    // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
385                    _this.core.$outer.scrollLeft += 1;
386                    _this.core.$outer.scrollLeft -= 1;
387
388                    _this.core.$outer.removeClass('lg-grab').addClass('lg-grabbing');
389                }
390            }
391        });
392
393        $(window).on('mousemove.lg.zoom', function(e) {
394            if (isDraging) {
395                var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
396                var distanceX;
397                var distanceY;
398
399                isMoved = true;
400                endCoords = {
401                    x: e.pageX,
402                    y: e.pageY
403                };
404
405                // reset opacity and transition duration
406                _this.core.$outer.addClass('lg-zoom-dragging');
407
408                if (allowY) {
409                    distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
410                } else {
411                    distanceY = -Math.abs(_$el.attr('data-y'));
412                }
413
414                if (allowX) {
415                    distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
416                } else {
417                    distanceX = -Math.abs(_$el.attr('data-x'));
418                }
419
420                if (_this.core.s.useLeftForZoom) {
421                    _$el.css({
422                        left: distanceX + 'px',
423                        top: distanceY + 'px'
424                    });
425                } else {
426                    _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
427                }
428            }
429        });
430
431        $(window).on('mouseup.lg.zoom', function(e) {
432
433            if (isDraging) {
434                isDraging = false;
435                _this.core.$outer.removeClass('lg-zoom-dragging');
436
437                // Fix for chrome mouse move on click
438                if (isMoved && ((startCoords.x !== endCoords.x) || (startCoords.y !== endCoords.y))) {
439                    endCoords = {
440                        x: e.pageX,
441                        y: e.pageY
442                    };
443                    _this.touchendZoom(startCoords, endCoords, allowX, allowY);
444
445                }
446
447                isMoved = false;
448            }
449
450            _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
451
452        });
453    };
454
455    Zoom.prototype.touchendZoom = function(startCoords, endCoords, allowX, allowY) {
456
457        var _this = this;
458        var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
459        var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
460        var distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
461        var distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
462        var minY = (_this.core.$outer.find('.lg').height() - $image.prop('offsetHeight')) / 2;
463        var maxY = Math.abs(($image.prop('offsetHeight') * Math.abs($image.attr('data-scale'))) - _this.core.$outer.find('.lg').height() + minY);
464        var minX = (_this.core.$outer.find('.lg').width() - $image.prop('offsetWidth')) / 2;
465        var maxX = Math.abs(($image.prop('offsetWidth') * Math.abs($image.attr('data-scale'))) - _this.core.$outer.find('.lg').width() + minX);
466
467        if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
468            if (allowY) {
469                if (distanceY <= -maxY) {
470                    distanceY = -maxY;
471                } else if (distanceY >= -minY) {
472                    distanceY = -minY;
473                }
474            }
475
476            if (allowX) {
477                if (distanceX <= -maxX) {
478                    distanceX = -maxX;
479                } else if (distanceX >= -minX) {
480                    distanceX = -minX;
481                }
482            }
483
484            if (allowY) {
485                _$el.attr('data-y', Math.abs(distanceY));
486            } else {
487                distanceY = -Math.abs(_$el.attr('data-y'));
488            }
489
490            if (allowX) {
491                _$el.attr('data-x', Math.abs(distanceX));
492            } else {
493                distanceX = -Math.abs(_$el.attr('data-x'));
494            }
495
496            if (_this.core.s.useLeftForZoom) {
497                _$el.css({
498                    left: distanceX + 'px',
499                    top: distanceY + 'px'
500                });
501            } else {
502                _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
503            }
504
505        }
506    };
507
508    Zoom.prototype.destroy = function() {
509
510        var _this = this;
511
512        // Unbind all events added by lightGallery zoom plugin
513        _this.core.$el.off('.lg.zoom');
514        $(window).off('.lg.zoom');
515        _this.core.$slide.off('.lg.zoom');
516        _this.core.$el.off('.lg.tm.zoom');
517        _this.resetZoom();
518        clearTimeout(_this.zoomabletimeout);
519        _this.zoomabletimeout = false;
520    };
521
522    $.fn.lightGallery.modules.zoom = Zoom;
523
524})();
525
526
527}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.