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.