vendor: 27,483 bytes, lines 1-923
1// ========================================================================== 2// 3// Guestures 4// Adds touch guestures, handles click and tap events 5// 6// ========================================================================== 7(function (window, document, $) { 8 "use strict"; 9 10 var requestAFrame = (function () { 11 return ( 12 window.requestAnimationFrame || 13 window.webkitRequestAnimationFrame || 14 window.mozRequestAnimationFrame || 15 window.oRequestAnimationFrame || 16 // if all else fails, use setTimeout 17 function (callback) { 18 return window.setTimeout(callback, 1000 / 60); 19 } 20 ); 21 })(); 22 23 var cancelAFrame = (function () { 24 return ( 25 window.cancelAnimationFrame || 26 window.webkitCancelAnimationFrame || 27 window.mozCancelAnimationFrame || 28 window.oCancelAnimationFrame || 29 function (id) { 30 window.clearTimeout(id); 31 } 32 ); 33 })(); 34 35 var getPointerXY = function (e) { 36 var result = []; 37 38 e = e.originalEvent || e || window.e; 39 e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e]; 40 41 for (var key in e) { 42 if (e[key].pageX) { 43 result.push({ 44 x: e[key].pageX, 45 y: e[key].pageY 46 }); 47 } else if (e[key].clientX) { 48 result.push({ 49 x: e[key].clientX, 50 y: e[key].clientY 51 }); 52 } 53 } 54 55 return result; 56 }; 57 58 var distance = function (point2, point1, what) { 59 if (!point1 || !point2) { 60 return 0; 61 } 62 63 if (what === "x") { 64 return point2.x - point1.x; 65 } else if (what === "y") { 66 return point2.y - point1.y; 67 } 68 69 return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)); 70 }; 71 72 var isClickable = function ($el) { 73 if ( 74 $el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') || 75 $.isFunction($el.get(0).onclick) || 76 $el.data("selectable") 77 ) { 78 return true; 79 } 80 81 // Check for attributes like data-fancybox-next or data-fancybox-close 82 for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) { 83 if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") { 84 return true; 85 } 86 } 87 88 return false; 89 }; 90 91 var hasScrollbars = function (el) { 92 var overflowY = window.getComputedStyle(el)["overflow-y"], 93 overflowX = window.getComputedStyle(el)["overflow-x"], 94 vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight, 95 horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth; 96 97 return vertical || horizontal; 98 }; 99 100 var isScrollable = function ($el) { 101 var rez = false; 102 103 while (true) { 104 rez = hasScrollbars($el.get(0)); 105 106 if (rez) { 107 break; 108 } 109 110 $el = $el.parent(); 111 112 if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) { 113 break; 114 } 115 } 116 117 return rez; 118 }; 119 120 var Guestures = function (instance) { 121 var self = this; 122 123 self.instance = instance; 124 125 self.$bg = instance.$refs.bg; 126 self.$stage = instance.$refs.stage; 127 self.$container = instance.$refs.container; 128 129 self.destroy(); 130 131 self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart")); 132 }; 133 134 Guestures.prototype.destroy = function () { 135 var self = this; 136 137 self.$container.off(".fb.touch"); 138 139 $(document).off(".fb.touch"); 140 141 if (self.requestId) { 142 cancelAFrame(self.requestId); 143 self.requestId = null; 144 } 145 146 if (self.tapped) { 147 clearTimeout(self.tapped); 148 self.tapped = null; 149 } 150 }; 151 152 Guestures.prototype.ontouchstart = function (e) { 153 var self = this, 154 $target = $(e.target), 155 instance = self.instance, 156 current = instance.current, 157 $slide = current.$slide, 158 $content = current.$content, 159 isTouchDevice = e.type == "touchstart"; 160 161 // Do not respond to both (touch and mouse) events 162 if (isTouchDevice) { 163 self.$container.off("mousedown.fb.touch"); 164 } 165 166 // Ignore right click 167 if (e.originalEvent && e.originalEvent.button == 2) { 168 return; 169 } 170 171 // Ignore taping on links, buttons, input elements 172 if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) { 173 return; 174 } 175 // Ignore clicks on the scrollbar 176 if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) { 177 return; 178 } 179 180 // Ignore clicks while zooming or closing 181 if (!current || instance.isAnimating || current.$slide.hasClass("fancybox-animated")) { 182 e.stopPropagation(); 183 e.preventDefault(); 184 185 return; 186 } 187 188 self.realPoints = self.startPoints = getPointerXY(e); 189 190 if (!self.startPoints.length) { 191 return; 192 } 193 194 // Allow other scripts to catch touch event if "touch" is set to false 195 if (current.touch) { 196 e.stopPropagation(); 197 } 198 199 self.startEvent = e; 200 201 self.canTap = true; 202 self.$target = $target; 203 self.$content = $content; 204 self.opts = current.opts.touch; 205 206 self.isPanning = false; 207 self.isSwiping = false; 208 self.isZooming = false; 209 self.isScrolling = false; 210 self.canPan = instance.canPan(); 211 212 self.startTime = new Date().getTime(); 213 self.distanceX = self.distanceY = self.distance = 0; 214 215 self.canvasWidth = Math.round($slide[0].clientWidth); 216 self.canvasHeight = Math.round($slide[0].clientHeight); 217 218 self.contentLastPos = null; 219 self.contentStartPos = $.fancybox.getTranslate(self.$content) || { 220 top: 0, 221 left: 0 222 }; 223 self.sliderStartPos = $.fancybox.getTranslate($slide); 224 225 // Since position will be absolute, but we need to make it relative to the stage 226 self.stagePos = $.fancybox.getTranslate(instance.$refs.stage); 227 228 self.sliderStartPos.top -= self.stagePos.top; 229 self.sliderStartPos.left -= self.stagePos.left; 230 231 self.contentStartPos.top -= self.stagePos.top; 232 self.contentStartPos.left -= self.stagePos.left; 233 234 $(document) 235 .off(".fb.touch") 236 .on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend")) 237 .on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove")); 238 239 if ($.fancybox.isMobile) { 240 document.addEventListener("scroll", self.onscroll, true); 241 } 242 243 // Skip if clicked outside the sliding area 244 if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) { 245 if ($target.is(".fancybox-image")) { 246 e.preventDefault(); 247 } 248 249 if (!($.fancybox.isMobile && $target.parents(".fancybox-caption").length)) { 250 return; 251 } 252 } 253 254 self.isScrollable = isScrollable($target) || isScrollable($target.parent()); 255 256 // Check if element is scrollable and try to prevent default behavior (scrolling) 257 if (!($.fancybox.isMobile && self.isScrollable)) { 258 e.preventDefault(); 259 } 260 261 // One finger or mouse click - swipe or pan an image 262 if (self.startPoints.length === 1 || current.hasError) { 263 if (self.canPan) { 264 $.fancybox.stop(self.$content); 265 266 self.isPanning = true; 267 } else { 268 self.isSwiping = true; 269 } 270 271 self.$container.addClass("fancybox-is-grabbing"); 272 } 273 274 // Two fingers - zoom image 275 if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) { 276 self.canTap = false; 277 self.isSwiping = false; 278 self.isPanning = false; 279 280 self.isZooming = true; 281 282 $.fancybox.stop(self.$content); 283 284 self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft(); 285 self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop(); 286 287 self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width; 288 self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height; 289 290 self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]); 291 } 292 }; 293 294 Guestures.prototype.onscroll = function (e) { 295 var self = this; 296 297 self.isScrolling = true; 298 299 document.removeEventListener("scroll", self.onscroll, true); 300 }; 301 302 Guestures.prototype.ontouchmove = function (e) { 303 var self = this; 304 305 // Make sure user has not released over iframe or disabled element 306 if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) { 307 self.ontouchend(e); 308 return; 309 } 310 311 if (self.isScrolling) { 312 self.canTap = false; 313 return; 314 } 315 316 self.newPoints = getPointerXY(e); 317 318 if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) { 319 return; 320 } 321 322 if (!(self.isSwiping && self.isSwiping === true)) { 323 e.preventDefault(); 324 } 325 326 self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x"); 327 self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y"); 328 329 self.distance = distance(self.newPoints[0], self.startPoints[0]); 330 331 // Skip false ontouchmove events (Chrome) 332 if (self.distance > 0) { 333 if (self.isSwiping) { 334 self.onSwipe(e); 335 } else if (self.isPanning) { 336 self.onPan(); 337 } else if (self.isZooming) { 338 self.onZoom(); 339 } 340 } 341 }; 342 343 Guestures.prototype.onSwipe = function (e) { 344 var self = this, 345 instance = self.instance, 346 swiping = self.isSwiping, 347 left = self.sliderStartPos.left || 0, 348 angle; 349 350 // If direction is not yet determined 351 if (swiping === true) { 352 // We need at least 10px distance to correctly calculate an angle 353 if (Math.abs(self.distance) > 10) { 354 self.canTap = false; 355 356 if (instance.group.length < 2 && self.opts.vertical) { 357 self.isSwiping = "y"; 358 } else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) { 359 self.isSwiping = "x"; 360 } else { 361 angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI); 362 363 self.isSwiping = angle > 45 && angle < 135 ? "y" : "x"; 364 } 365 366 if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) { 367 self.isScrolling = true; 368 369 return; 370 } 371 372 instance.isDragging = self.isSwiping; 373 374 // Reset points to avoid jumping, because we dropped first swipes to calculate the angle 375 self.startPoints = self.newPoints; 376 377 $.each(instance.slides, function (index, slide) { 378 var slidePos, stagePos; 379 380 $.fancybox.stop(slide.$slide); 381 382 slidePos = $.fancybox.getTranslate(slide.$slide); 383 stagePos = $.fancybox.getTranslate(instance.$refs.stage); 384 385 slide.$slide 386 .css({ 387 transform: "", 388 opacity: "", 389 "transition-duration": "" 390 }) 391 .removeClass("fancybox-animated") 392 .removeClass(function (index, className) { 393 return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" "); 394 }); 395 396 if (slide.pos === instance.current.pos) { 397 self.sliderStartPos.top = slidePos.top - stagePos.top; 398 self.sliderStartPos.left = slidePos.left - stagePos.left; 399 } 400 401 $.fancybox.setTranslate(slide.$slide, { 402 top: slidePos.top - stagePos.top, 403 left: slidePos.left - stagePos.left 404 }); 405 }); 406 407 // Stop slideshow 408 if (instance.SlideShow && instance.SlideShow.isActive) { 409 instance.SlideShow.stop(); 410 } 411 } 412 413 return; 414 } 415 416 // Sticky edges 417 if (swiping == "x") { 418 if ( 419 self.distanceX > 0 && 420 (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop)) 421 ) { 422 left = left + Math.pow(self.distanceX, 0.8); 423 } else if ( 424 self.distanceX < 0 && 425 (self.instance.group.length < 2 || 426 (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop)) 427 ) { 428 left = left - Math.pow(-self.distanceX, 0.8); 429 } else { 430 left = left + self.distanceX; 431 } 432 } 433 434 self.sliderLastPos = { 435 top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY, 436 left: left 437 }; 438 439 if (self.requestId) { 440 cancelAFrame(self.requestId); 441 442 self.requestId = null; 443 } 444 445 self.requestId = requestAFrame(function () { 446 if (self.sliderLastPos) { 447 $.each(self.instance.slides, function (index, slide) { 448 var pos = slide.pos - self.instance.currPos; 449 450 $.fancybox.setTranslate(slide.$slide, { 451 top: self.sliderLastPos.top, 452 left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter 453 }); 454 }); 455 456 self.$container.addClass("fancybox-is-sliding"); 457 } 458 }); 459 }; 460 461 Guestures.prototype.onPan = function () { 462 var self = this; 463 464 // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit) 465 if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) { 466 self.startPoints = self.newPoints; 467 return; 468 } 469 470 self.canTap = false; 471 472 self.contentLastPos = self.limitMovement(); 473 474 if (self.requestId) { 475 cancelAFrame(self.requestId); 476 } 477 478 self.requestId = requestAFrame(function () { 479 $.fancybox.setTranslate(self.$content, self.contentLastPos); 480 }); 481 }; 482 483 // Make panning sticky to the edges 484 Guestures.prototype.limitMovement = function () { 485 var self = this; 486 487 var canvasWidth = self.canvasWidth; 488 var canvasHeight = self.canvasHeight; 489 490 var distanceX = self.distanceX; 491 var distanceY = self.distanceY; 492 493 var contentStartPos = self.contentStartPos; 494 495 var currentOffsetX = contentStartPos.left; 496 var currentOffsetY = contentStartPos.top; 497 498 var currentWidth = contentStartPos.width; 499 var currentHeight = contentStartPos.height; 500 501 var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY; 502 503 if (currentWidth > canvasWidth) { 504 newOffsetX = currentOffsetX + distanceX; 505 } else { 506 newOffsetX = currentOffsetX; 507 } 508 509 newOffsetY = currentOffsetY + distanceY; 510 511 // Slow down proportionally to traveled distance 512 minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5); 513 minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5); 514 515 maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5); 516 maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5); 517 518 // -> 519 if (distanceX > 0 && newOffsetX > minTranslateX) { 520 newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0; 521 } 522 523 // <- 524 if (distanceX < 0 && newOffsetX < maxTranslateX) { 525 newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0; 526 } 527 528 // \/ 529 if (distanceY > 0 && newOffsetY > minTranslateY) { 530 newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0; 531 } 532 533 // /\ 534 if (distanceY < 0 && newOffsetY < maxTranslateY) { 535 newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0; 536 } 537 538 return { 539 top: newOffsetY, 540 left: newOffsetX 541 }; 542 }; 543 544 Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) { 545 var self = this; 546 547 var canvasWidth = self.canvasWidth; 548 var canvasHeight = self.canvasHeight; 549 550 if (newWidth > canvasWidth) { 551 newOffsetX = newOffsetX > 0 ? 0 : newOffsetX; 552 newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX; 553 } else { 554 // Center horizontally 555 newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2); 556 } 557 558 if (newHeight > canvasHeight) { 559 newOffsetY = newOffsetY > 0 ? 0 : newOffsetY; 560 newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY; 561 } else { 562 // Center vertically 563 newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2); 564 } 565 566 return { 567 top: newOffsetY, 568 left: newOffsetX 569 }; 570 }; 571 572 Guestures.prototype.onZoom = function () { 573 var self = this; 574 575 // Calculate current distance between points to get pinch ratio and new width and height 576 var contentStartPos = self.contentStartPos; 577 578 var currentWidth = contentStartPos.width; 579 var currentHeight = contentStartPos.height; 580 581 var currentOffsetX = contentStartPos.left; 582 var currentOffsetY = contentStartPos.top; 583 584 var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]); 585 586 var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers; 587 588 var newWidth = Math.floor(currentWidth * pinchRatio); 589 var newHeight = Math.floor(currentHeight * pinchRatio); 590 591 // This is the translation due to pinch-zooming 592 var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX; 593 var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY; 594 595 // Point between the two touches 596 var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft(); 597 var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop(); 598 599 // And this is the translation due to translation of the centerpoint 600 // between the two fingers 601 var translateFromTranslatingX = centerPointEndX - self.centerPointStartX; 602 var translateFromTranslatingY = centerPointEndY - self.centerPointStartY; 603 604 // The new offset is the old/current one plus the total translation 605 var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX); 606 var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY); 607 608 var newPos = { 609 top: newOffsetY, 610 left: newOffsetX, 611 scaleX: pinchRatio, 612 scaleY: pinchRatio 613 }; 614 615 self.canTap = false; 616 617 self.newWidth = newWidth; 618 self.newHeight = newHeight; 619 620 self.contentLastPos = newPos; 621 622 if (self.requestId) { 623 cancelAFrame(self.requestId); 624 } 625 626 self.requestId = requestAFrame(function () { 627 $.fancybox.setTranslate(self.$content, self.contentLastPos); 628 }); 629 }; 630 631 Guestures.prototype.ontouchend = function (e) { 632 var self = this; 633 634 var swiping = self.isSwiping; 635 var panning = self.isPanning; 636 var zooming = self.isZooming; 637 var scrolling = self.isScrolling; 638 639 self.endPoints = getPointerXY(e); 640 self.dMs = Math.max(new Date().getTime() - self.startTime, 1); 641 642 self.$container.removeClass("fancybox-is-grabbing"); 643 644 $(document).off(".fb.touch"); 645 646 document.removeEventListener("scroll", self.onscroll, true); 647 648 if (self.requestId) { 649 cancelAFrame(self.requestId); 650 651 self.requestId = null; 652 } 653 654 self.isSwiping = false; 655 self.isPanning = false; 656 self.isZooming = false; 657 self.isScrolling = false; 658 659 self.instance.isDragging = false; 660 661 if (self.canTap) { 662 return self.onTap(e); 663 } 664 665 self.speed = 100; 666 667 // Speed in px/ms 668 self.velocityX = (self.distanceX / self.dMs) * 0.5; 669 self.velocityY = (self.distanceY / self.dMs) * 0.5; 670 671 if (panning) { 672 self.endPanning(); 673 } else if (zooming) { 674 self.endZooming(); 675 } else { 676 self.endSwiping(swiping, scrolling); 677 } 678 679 return; 680 }; 681 682 Guestures.prototype.endSwiping = function (swiping, scrolling) { 683 var self = this, 684 ret = false, 685 len = self.instance.group.length, 686 distanceX = Math.abs(self.distanceX), 687 canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50), 688 speedX = 300; 689 690 self.sliderLastPos = null; 691 692 // Close if swiped vertically / navigate if horizontally 693 if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) { 694 // Continue vertical movement 695 $.fancybox.animate( 696 self.instance.current.$slide, { 697 top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150, 698 opacity: 0 699 }, 700 200 701 ); 702 ret = self.instance.close(true, 250); 703 } else if (canAdvance && self.distanceX > 0) { 704 ret = self.instance.previous(speedX); 705 } else if (canAdvance && self.distanceX < 0) { 706 ret = self.instance.next(speedX); 707 } 708 709 if (ret === false && (swiping == "x" || swiping == "y")) { 710 self.instance.centerSlide(200); 711 } 712 713 self.$container.removeClass("fancybox-is-sliding"); 714 }; 715 716 // Limit panning from edges 717 // ======================== 718 Guestures.prototype.endPanning = function () { 719 var self = this, 720 newOffsetX, 721 newOffsetY, 722 newPos; 723 724 if (!self.contentLastPos) { 725 return; 726 } 727 728 if (self.opts.momentum === false || self.dMs > 350) { 729 newOffsetX = self.contentLastPos.left; 730 newOffsetY = self.contentLastPos.top; 731 } else { 732 // Continue movement 733 newOffsetX = self.contentLastPos.left + self.velocityX * 500; 734 newOffsetY = self.contentLastPos.top + self.velocityY * 500; 735 } 736 737 newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height); 738 739 newPos.width = self.contentStartPos.width; 740 newPos.height = self.contentStartPos.height; 741 742 $.fancybox.animate(self.$content, newPos, 366); 743 }; 744 745 Guestures.prototype.endZooming = function () { 746 var self = this; 747 748 var current = self.instance.current; 749 750 var newOffsetX, newOffsetY, newPos, reset; 751 752 var newWidth = self.newWidth; 753 var newHeight = self.newHeight; 754 755 if (!self.contentLastPos) { 756 return; 757 } 758 759 newOffsetX = self.contentLastPos.left; 760 newOffsetY = self.contentLastPos.top; 761 762 reset = { 763 top: newOffsetY, 764 left: newOffsetX, 765 width: newWidth, 766 height: newHeight, 767 scaleX: 1, 768 scaleY: 1 769 }; 770 771 // Reset scalex/scaleY values; this helps for perfomance and does not break animation 772 $.fancybox.setTranslate(self.$content, reset); 773 774 if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) { 775 self.instance.scaleToFit(150); 776 } else if (newWidth > current.width || newHeight > current.height) { 777 self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150); 778 } else { 779 newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight); 780 781 $.fancybox.animate(self.$content, newPos, 150); 782 } 783 }; 784 785 Guestures.prototype.onTap = function (e) { 786 var self = this; 787 var $target = $(e.target); 788 789 var instance = self.instance; 790 var current = instance.current; 791 792 var endPoints = (e && getPointerXY(e)) || self.startPoints; 793 794 var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0; 795 var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0; 796 797 var where; 798 799 var process = function (prefix) { 800 var action = current.opts[prefix]; 801 802 if ($.isFunction(action)) { 803 action = action.apply(instance, [current, e]); 804 } 805 806 if (!action) { 807 return; 808 } 809 810 switch (action) { 811 case "close": 812 instance.close(self.startEvent); 813 814 break; 815 816 case "toggleControls": 817 instance.toggleControls(); 818 819 break; 820 821 case "next": 822 instance.next(); 823 824 break; 825 826 case "nextOrClose": 827 if (instance.group.length > 1) { 828 instance.next(); 829 } else { 830 instance.close(self.startEvent); 831 } 832 833 break; 834 835 case "zoom": 836 if (current.type == "image" && (current.isLoaded || current.$ghost)) { 837 if (instance.canPan()) { 838 instance.scaleToFit(); 839 } else if (instance.isScaledDown()) { 840 instance.scaleToActual(tapX, tapY); 841 } else if (instance.group.length < 2) { 842 instance.close(self.startEvent); 843 } 844 } 845 846 break; 847 } 848 }; 849 850 // Ignore right click 851 if (e.originalEvent && e.originalEvent.button == 2) { 852 return; 853 } 854 855 // Skip if clicked on the scrollbar 856 if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) { 857 return; 858 } 859 860 // Check where is clicked 861 if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) { 862 where = "Outside"; 863 } else if ($target.is(".fancybox-slide")) { 864 where = "Slide"; 865 } else if ( 866 instance.current.$content && 867 instance.current.$content 868 .find($target) 869 .addBack() 870 .filter($target).length 871 ) { 872 where = "Content"; 873 } else { 874 return; 875 } 876 877 // Check if this is a double tap 878 if (self.tapped) { 879 // Stop previously created single tap 880 clearTimeout(self.tapped); 881 self.tapped = null; 882 883 // Skip if distance between taps is too big 884 if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) { 885 return this; 886 } 887 888 // OK, now we assume that this is a double-tap 889 process("dblclick" + where); 890 } else { 891 // Single tap will be processed if user has not clicked second time within 300ms 892 // or there is no need to wait for double-tap 893 self.tapX = tapX; 894 self.tapY = tapY; 895 896 if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) { 897 self.tapped = setTimeout(function () { 898 self.tapped = null; 899 900 if (!instance.isAnimating) { 901 process("click" + where); 902 } 903 }, 500); 904 } else { 905 process("click" + where); 906 } 907 } 908 909 return this; 910 }; 911 912 $(document) 913 .on("onActivate.fb", function (e, instance) { 914 if (instance && !instance.Guestures) { 915 instance.Guestures = new Guestures(instance); 916 } 917 }) 918 .on("beforeClose.fb", function (e, instance) { 919 if (instance && instance.Guestures) { 920 instance.Guestures.destroy(); 921 } 922 }); 923})(window, document, jQuery);
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.