1/** 2* The MIT License (MIT) 3* 4* Copyright (c) 2015 Max Valiano | http://unitegallery.net 5* 6* Permission is hereby granted, free of charge, to any person 7* obtaining a copy of this software and associated documentation 8* files (the "Software"), to deal in the Software without 9* restriction, including without limitation the rights to use, 10* copy, modify, merge, publish, distribute, sublicense, and/or sell 11* copies of the Software, and to permit persons to whom the 12* Software is furnished to do so, subject to the following 13* conditions: 14* 15* The above copyright notice and this permission notice shall be 16* included in all copies or substantial portions of the Software. 17* 18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25* OTHER DEALINGS IN THE SOFTWARE. 26* 27* @author Max Valiano 28* @copyright Copyright (c) 2017 Max Valiano | http://unitegallery.net 29* @license The MIT License (MIT) 30*/ 31 32/** 33 * touch thumbs control class 34 * addon to strip gallery 35 */ 36function UGZoomSliderControl(){ 37 38 var g_objSlider, g_objInner, g_parent = new UGSlider(), g_objParent; 39 40 var g_functions = new UGFunctions(); 41 42 var t = this; 43 44 var g_options = { 45 slider_zoom_step: 1.2, //the step of zooming with mouse wheel or zoom button 46 slider_zoom_max_ratio: 6, //max zoom ratio 47 slider_zoom_return_pan_duration: 400, //the return from pan animation duration 48 slider_zoom_return_pan_easing: "easeOutCubic" //the return from pan wasing function 49 }; 50 51 var g_temp = { 52 isPanActive:false, 53 startMouseX:0, 54 startMouseY:0, 55 lastMouseX:0, 56 lastMouseY:0, 57 startImageX:0, 58 startImageY:0, 59 panXActive:false, 60 panYActive:false, 61 objImage:null, 62 objImageSize:null, 63 objParent:null, 64 objParentSize:null, 65 objSlide:null, 66 storeImageLastTime:0, 67 68 isZoomActive: false, 69 startDistance:0, 70 startMiddlePoint:null, 71 imageOrientPoint:null, 72 objFitImageSize:null, 73 isZoomedOnce:false 74 }; 75 76 77 /** 78 * init the object 79 */ 80 function initObject(objSlider, customOptions){ 81 82 g_parent = objSlider; 83 g_objParent = jQuery(g_parent); 84 g_objects = objSlider.getObjects(); 85 g_objSlider = g_objects.g_objSlider; 86 g_objInner = g_objects.g_objInner; 87 88 g_options = jQuery.extend(g_options, customOptions); 89 90 initEvents(); 91 } 92 93 94 /** 95 * get fit image to slider scale mode 96 * the fill become fit 97 */ 98 function getFitScaleMode(){ 99 100 var scaleMode = g_parent.getScaleMode(); 101 102 if(scaleMode != "down") 103 scaleMode = "fit"; 104 105 return(scaleMode); 106 } 107 108 109 /** 110 * cache current slide and image 111 */ 112 function storeCurrentImage(){ 113 114 //prevent continious image storring 115 var currentTime = jQuery.now(); 116 var diff = currentTime - g_temp.storeImageLastTime; 117 118 if(diff < 20) 119 return(false); 120 121 var slides = g_parent.getSlidesReference(); 122 g_temp.objSlide = slides.objCurrentSlide; 123 g_temp.objImage = slides.objCurrentSlide.find("img"); 124 125 if(g_temp.objImage.length == 0) 126 return(false); 127 128 g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage); 129 g_temp.objParent = g_temp.objImage.parent(); 130 g_temp.objParentSize = g_functions.getElementSize(g_temp.objParent); 131 132 var scaleMode = getFitScaleMode(); 133 134 objPadding = g_parent.getObjImagePadding(); 135 136 g_temp.objFitImageSize = g_functions.getImageInsideParentDataByImage(g_temp.objImage, scaleMode, objPadding); 137 138 var currentTime = jQuery.now(); 139 g_temp.storeImageLastTime = currentTime; 140 141 return(true); 142 } 143 144 145 /** 146 * zoom current image 147 * mode: in, out, back 148 */ 149 function zoomCurrentImage(mode, mousePos){ 150 151 var slides = g_parent.getSlidesReference(); 152 var objImage = slides.objCurrentSlide.find("img"); 153 var scaleMode = getFitScaleMode(); 154 155 g_objParent.trigger(g_parent.events.ZOOM_START); 156 157 //flag if the images zoomed 158 var isZoomed = true; 159 160 var objPadding = g_parent.getObjImagePadding(); 161 162 if(mode == "back"){ 163 var objOriginalSize = g_functions.getImageOriginalSize(objImage); 164 g_functions.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding); 165 } 166 else{ 167 var zoomIn = (mode == "in")?true:false; 168
169 isZoomed = g_functions.zoomImageInsideParent(objImage, zoomIn, g_options.slider_zoom_step, mousePos, scaleMode, g_options.slider_zoom_max_ratio, objPadding); 170 } 171 172 if(isZoomed == true){ 173 g_objParent.trigger(g_parent.events.ZOOMING); 174 g_objParent.trigger(g_parent.events.ZOOM_CHANGE); 175 g_objParent.trigger(g_parent.events.ZOOM_END); 176 } 177 178 } 179 180 181 function ____________PAN_____________(){}; 182 183 184 /** 185 * check if pan is posible for the current image 186 * check if the image is bigger then the parent 187 */ 188 function isPanPosible(objImage, event, stictTouchesCheck){ 189 190 //check num touches, strict means that even if 0 - pan not posible 191 var arrTouches = g_functions.getArrTouches(event); 192 193 if(stictTouchesCheck === true){ 194 195 if(arrTouches.length != 1) 196 return(false); 197 }else{ 198 if(arrTouches.length > 1) 199 return(false); 200 } 201 202 if(g_functions.isElementBiggerThenParent(objImage)) 203 return(true); 204 205 return(false); 206 } 207 208 209 /** 210 * store pan values 211 */ 212 function storePanInitValues(event){ 213 214 var mousePos = g_functions.getMousePosition(event); 215 216 g_temp.startMouseX = mousePos.pageX; 217 g_temp.startMouseY = mousePos.pageY; 218 219 g_temp.lastMouseX = g_temp.startMouseX; 220 g_temp.lastMouseY = g_temp.startMouseY; 221 222 g_temp.startImageX = g_temp.objImageSize.left; 223 g_temp.startImageY = g_temp.objImageSize.top; 224 225 g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width); 226 g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height); 227 228 } 229 230 231 /** 232 * check pan start, and start if posible 233 */ 234 function startPan(event){ 235 236 g_temp.isPanActive = true; 237 storePanInitValues(event); 238 239 } 240 241 242 /** 243 * pan the image 244 */ 245 function panImage(event){ 246 247 if(g_temp.objImage == undefined || g_temp.objImage.length == 0) 248 return(true); 249 250 var mousePos = g_functions.getMousePosition(event); 251 252 var diffX = mousePos.pageX - g_temp.startMouseX; 253 var diffY = mousePos.pageY - g_temp.startMouseY; 254 255 //get active direction 256 var diffLastX = mousePos.pageX - g_temp.lastMouseX; 257 var diffLastY = mousePos.pageY - g_temp.lastMouseY; 258 259 var directionX = (diffLastX < 0) ? "left":"right"; 260 var directionY = (diffLastY < 0) ? "up":"down"; 261 262 g_temp.lastMouseX = mousePos.pageX; 263 g_temp.lastMouseY = mousePos.pageY; 264 265 var posImage = g_functions.getElementSize(g_temp.objImage); 266 267 //var imageX = g_temp.startImageX + diffX; 268 //var imageY = g_temp.startImageY + diffY; 269 270 271 //slow down if no pan available in this point 272 //slow down y 273 274 if(g_temp.panYActive == false){ 275 276 diffLastY = 0; 277 278 }else{ //zoom enabled 279 280 if(directionY == "down" && posImage.top > 0){ 281 282 diffLastY = diffLastY / 3; 283 284 }else if(directionY == "up" && posImage.bottom < g_temp.objParentSize.height){ 285 286 diffLastY = diffLastY / 3; 287 288 } 289 } 290 291 //slow down x (only if the pan enabled) 292 if(g_temp.panXActive == false || g_parent.isInnerInPlace() == false){ 293 294 diffLastX = 0; 295 296 }else{ //zoom enabled 297 298 if(directionX == "right" && posImage.left > 0){ 299 diffLastX = diffLastX / 3; 300 } 301 else if(directionX == "left" && posImage.right < g_temp.objParentSize.width){ 302 diffLastX = diffLastX / 3; 303 } 304 } 305 306 var imageX = posImage.left + diffLastX; 307 var imageY = posImage.top + diffLastY; 308 309 310 g_functions.placeElement(g_temp.objImage, imageX, imageY); 311 312 } 313 314 315 316 317 /** 318 * return the image to place if it's out of borders 319 */ 320 function checkReturnAfterPan(){ 321 322 var isReturnX = false, isReturnY = false, newX = 0, newY = 0; 323 var objSize = g_functions.getElementSize(g_temp.objImage); 324 var objImagePadding = g_parent.getObjImagePadding(); 325 326 var objCenterPos = g_functions.getElementCenterPosition(g_temp.objImage, objImagePadding); 327 328 g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width); 329 g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height); 330 331 332 if(g_temp.panYActive == true){ 333 334 if(objSize.top > 0){ //off limit top 335 336 newY = 0; 337 isReturnY = true; 338 339 }else if(objSize.bottom < g_temp.objParentSize.height){ //off limit bottom 340 341 newY = g_temp.objParentSize.height - objSize.height; 342 isReturnY = true; 343 344 } 345 346 }else{ //pan not active y - return to center 347 348 if(objSize.top != objCenterPos.top){ 349 isReturnY = true; 350 newY = objCenterPos.top; 351 } 352 353 } 354 355 356 //check return x to place 357 if(g_temp.panXActive == true){ 358 359 if(objSize.left > 0){ //off limit left 360 361 newX = 0; 362 isReturnX = true; 363 364 }else if(objSize.right < g_temp.objParentSize.width){ //off limit right 365 366 newX = g_temp.objParentSize.width - objSize.width; 367 isReturnX = true; 368 369 } 370 371 }else{ //pan not active x - return to center 372 373 // debugLine("not active", true); 374 375 if(objSize.left != objCenterPos.left){ 376 isReturnX = true; 377 newX = objCenterPos.left; 378 } 379 } 380 381 382 //do the animation 383 var objCss = {}; 384 if(isReturnY == true) 385 objCss.top = newY + "px"; 386 387 if(isReturnX == true) 388 objCss.left = newX + "px"; 389 390 391 if(isReturnY == true || isReturnX == true){ 392 393 g_temp.objImage.animate(objCss,{ 394 duration: g_options.slider_zoom_return_pan_duration, 395 easing: g_options.slider_zoom_return_pan_easing, 396 queue: false 397 }); 398 399 } 400 401 } 402
403 /** 404 * check if the image animating or not 405 */ 406 function isImageAnimating(){ 407 408 if(g_temp.objImage && g_temp.objImage.is(":animated")) 409 return(true); 410 411 return(false); 412 } 413 414 function ____________END_PAN_____________(){}; 415 416 function ________TOUCH_ZOOM_____________(){}; 417 418 /** 419 * start touch zoom 420 */ 421 function startTouchZoom(arrTouches){ 422 423 g_temp.isZoomActive = true; 424 425 //store init diff 426 g_temp.startDistance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY); 427 if(g_temp.startDistance == 0) 428 g_temp.startDistance = 1; 429 430 431 //store init positions 432 g_temp.startMiddlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY); 433 434 g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage); 435 436 g_temp.startImageX = g_temp.objImageSize.left; 437 g_temp.startImageY = g_temp.objImageSize.top; 438 439 //set orient point 440 g_temp.imageOrientPoint = g_functions.getElementLocalPoint(g_temp.startMiddlePoint, g_temp.objImage); 441 442 var isInsideImage = g_functions.isPointInsideElement(g_temp.imageOrientPoint, g_temp.objImageSize); 443 if(isInsideImage == false){ 444 g_temp.imageOrientPoint = g_functions.getElementCenterPoint(g_temp.objImage); 445 } 446 447 //trigger start zoom event 448 g_objParent.trigger(g_parent.events.ZOOM_START); 449 } 450 451 452 /** 453 * check num touches, if not 2 - end zoom 454 */ 455 function checkTouchZoomEnd(event){ 456 457 if(g_temp.isZoomActive == false) 458 return(false); 459 460 var arrTouches = g_functions.getArrTouches(event); 461 if(arrTouches.length != 2){ //end touch zoom 462 463 g_temp.isZoomActive = false; 464 465 //trigger end zoom event 466 g_objParent.trigger(g_parent.events.ZOOM_END); 467 } 468 469 } 470 471 472 /** 473 * check start touch zoom 474 */ 475 function checkTouchZoomStart(event){ 476 477 if(g_temp.isZoomActive == true) 478 return(true); 479 480 481 var arrTouches = g_functions.getArrTouches(event); 482 483 if(arrTouches.length != 2) 484 return(true); 485 486 startTouchZoom(arrTouches); 487 } 488 489 490 /** 491 * do touch zoom on touch devices 492 */ 493 function doTouchZoom(event){ 494 495 var arrTouches = g_functions.getArrTouches(event); 496 497 var distance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY); 498 var zoomRatio = distance / g_temp.startDistance; 499 500 var middlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY); 501 502 //set zoom data: 503 var newWidth = g_temp.objImageSize.width * zoomRatio; 504 var newHeight = g_temp.objImageSize.height * zoomRatio; 505 506 //check max zoom ratio: 507 var objOriginalSize = g_functions.getImageOriginalSize(g_temp.objImage); 508 var expectedZoomRatio = 1; 509 if(objOriginalSize.width > 0) 510 expectedZoomRatio = newWidth / objOriginalSize.width; 511 512 if(expectedZoomRatio > g_options.slider_zoom_max_ratio) 513 return(true); 514 515 //set pan data: 516 panX = -(g_temp.imageOrientPoint.x * zoomRatio - g_temp.imageOrientPoint.x); 517 panY = -(g_temp.imageOrientPoint.y * zoomRatio - g_temp.imageOrientPoint.y); 518 519 var diffMiddleX = (middlePoint.x - g_temp.startMiddlePoint.x); 520 var diffMiddleY = (middlePoint.y - g_temp.startMiddlePoint.y); 521 522 var posx = g_temp.startImageX + panX + diffMiddleX; 523 var posy = g_temp.startImageY + panY + diffMiddleY; 524 525 526 //resize and place: 527 g_functions.setElementSizeAndPosition(g_temp.objImage, posx, posy, newWidth, newHeight); 528 529 //trigger zooming event 530 g_objParent.trigger(g_parent.events.ZOOMING); 531 g_objParent.trigger(g_parent.events.ZOOM_CHANGE); 532 533 /* 534 debugLine({ 535 middleStartX: g_temp.startMiddlePoint.x, 536 middleX: middlePoint.x, 537 diffMiddleX: diffMiddleX 538 }); 539 */ 540 541 } 542 543 544 /** 545 * check return the image from zoom 546 */ 547 function checkReturnFromZoom(){ 548 549 if(g_temp.objImage == undefined || g_temp.objImage.length == 0) 550 return(true); 551 552 var objSize = g_functions.getElementSize(g_temp.objImage); 553 554 if(objSize.width < g_temp.objFitImageSize.imageWidth){ 555 556 g_temp.objImage.css({ 557 position:"absolute", 558 margin:"none" 559 }); 560 561 var objCss = { 562 top: g_temp.objFitImageSize.imageTop + "px", 563 left: g_temp.objFitImageSize.imageLeft + "px", 564 width: g_temp.objFitImageSize.imageWidth + "px", 565 height: g_temp.objFitImageSize.imageHeight + "px" 566 }; 567 568 g_temp.objImage.animate(objCss,{ 569 duration: g_options.slider_zoom_return_pan_duration, 570 easing: g_options.slider_zoom_return_pan_easing, 571 queue: false 572 }); 573 574 }else{ 575 checkReturnAfterPan(); 576 } 577 578 } 579 580
581 function ________END_TOUCH_ZOOM_____________(){}; 582 583 584 /** 585 * 586 * touch start event - start pan, remember start pan data 587 */ 588 function onTouchStart(event){ 589 590 //if no image type, exit 591 if(g_parent.isCurrentSlideType("image") == false) 592 return(true); 593 594 var isStored = storeCurrentImage(); 595 596 if(g_temp.objImage == undefined || g_temp.objImage.length == 0) 597 return(true); 598 599 event.preventDefault(); 600 601 //stop animation if exists 602 if(isImageAnimating() == true){ 603 g_temp.objImage.stop(true); 604 } 605 606 if(g_temp.isZoomActive == true){ 607 608 checkTouchZoomEnd(event); 609 610 }else{ 611 612 checkTouchZoomStart(event); 613 614 } 615 616 //if zoom started stop panning, if not, start panning 617 if(g_temp.isZoomActive == true){ 618 619 g_temp.isPanActive = false; 620 621 }else if(isPanPosible(g_temp.objImage, event) == true && g_temp.isZoomedOnce == true){ 622 623 startPan(event); 624 } 625 626 /* 627 debugLine({ 628 pan: g_temp.isPanActive, 629 zoom: g_temp.isZoomActive, 630 event: "start" 631 }, true); 632 */ 633 634 } 635 636 637 /** 638 * touch end event - bring the image to place 639 */ 640 function onTouchEnd(event){ 641 642 if(g_parent.isCurrentSlideType("image") == false) 643 return(true); 644 645 //check if some gallery button clicked 646 var objTarget = jQuery(event.target); 647 if(objTarget.data("ug-button") == true){ 648 //event.preventDefault(); 649 return(false); 650 } 651 652 var isStored = storeCurrentImage(); 653 654 if(g_temp.objImage == undefined || g_temp.objImage.length == 0) 655 return(true); 656 657 var panWasActive = g_temp.isPanActive; 658 var zoomWasActive = g_temp.isZoomActive; 659 660 //if the inner not in place, don't return noting, let the slide change 661 if(g_parent.isInnerInPlace() == false){ 662 g_temp.isZoomActive = false; 663 g_temp.isPanActive = false; 664 return(true); 665 } 666 667 //check end zoom 668 if(g_temp.isZoomActive == true){ 669 checkTouchZoomEnd(event); 670 }else{ 671 checkTouchZoomStart(event); 672 } 673 674 675 if(g_temp.isZoomActive == true){ 676 677 g_temp.isPanActive = false; 678 679 }else{ 680 681 var panPosible = isPanPosible(g_temp.objImage, event, true); 682 683 if(g_temp.isPanActive == true ){ 684 685 g_temp.isPanActive = false; 686 687 }else if(panPosible == true){ 688 689 startPan(event); 690 } 691 692 } 693 694 /* 695 debugLine({ 696 pan:g_temp.isPanActive, 697 zoom: g_temp.isZoomActive 698 }, true); 699 */ 700 701 if((panWasActive || zoomWasActive) && g_temp.isZoomActive == false && g_temp.isPanActive == false){ 702 checkReturnFromZoom(); 703 } 704 705 706 } 707 708 709 /** 710 * 711 * touch move event - pan 712 */ 713 function onTouchMove(event){ 714 715 if(g_parent.isCurrentSlideType("image") == false) 716 return(true); 717 718 //check touch zoom (pinch gesture) 719 if(g_temp.isZoomActive == true){ 720 721 doTouchZoom(event); 722 723 }else if(g_temp.isPanActive == true){ 724 725 panImage(event); 726 727 } 728 729 730 } 731 732 733 /** 734 * on slider mousewheel event 735 */ 736 function onSliderMouseWheel(event, delta, deltaX, deltaY){ 737 738 if(g_options.slider_zoom_mousewheel == false) 739 return(true); 740 741 if(g_parent.isCurrentSlideType("image") == false) 742 return(true); 743 744 event.preventDefault(); 745 746 //prevent default only if needed 747 //if(zoomIn == true || zoomIn == false && g_functions.isElementBiggerThenParent(objImage)) 748 //event.preventDefault(); 749 750 751 var zoomIn = (delta > 0); 752 var mousePos = g_functions.getMousePosition(event); 753 var mode = (zoomIn == true) ? "in":"out"; 754 755 zoomCurrentImage(mode, mousePos); 756 } 757 758 759 /** 760 * init touch events 761 */ 762 function initEvents(){ 763 764 //debugLine("init"); 765 g_objSlider.on("mousewheel",onSliderMouseWheel); 766 767 //slider mouse down - pan start 768 g_objSlider.bind("mousedown touchstart",onTouchStart); 769 770 //on body move 771 jQuery("body").bind("mousemove touchmove",onTouchMove); 772 773 //on body mouse up - pan end 774 jQuery(window).add("body").bind("mouseup touchend", onTouchEnd); 775 776 //event before image returned to init position 777 g_objParent.bind(g_parent.events.BEFORE_RETURN, function(){ 778 779 checkReturnFromZoom(); 780 }); 781 782 //on item change update isZoomedOnce event. Allow panning only if zoomed once 783 g_objParent.bind(g_parent.events.ITEM_CHANGED, function(){ 784 g_temp.isZoomedOnce = false; 785 }); 786 787 g_objParent.bind(g_parent.events.ZOOM_CHANGE, function(){ 788 g_temp.isZoomedOnce = true; 789 }); 790 791 } 792 793 this.________EXTERNAL_____________ = function(){}; 794 795 /** 796 * check if the image is zoomed, and there is a place for left panning 797 */ 798 this.isPanEnabled = function(event, direction){ 799 800 storeCurrentImage(); 801 802 if(g_temp.objImage == undefined || g_temp.objImage.length == 0) 803 return(false); 804 805 if(g_temp.isZoomedOnce == false) 806 return(false); 807 808 if(isPanPosible(g_temp.objImage, event) == false) 809 return(false); 810 811 if(g_parent.isInnerInPlace() == false) 812 return(false); 813 814 if(direction == "left"){ 815 816 if(g_temp.objImageSize.right <= g_temp.objParentSize.width) 817 return(false); 818 819 }else{ //right direction 820 821 if(g_temp.objImageSize.left >= 0) 822 return(false); 823 } 824 825 return(true); 826 } 827 828 829 /** 830 * init function for avia controls 831 */ 832 this.init = function(objSlider, customOptions){ 833 834 initObject(objSlider, customOptions); 835 } 836 837 /** 838 * zoom in 839 */ 840 this.zoomIn = function(){ 841 zoomCurrentImage("in"); 842 } 843 844 /** 845 * zoom out 846 */ 847 this.zoomOut = function(){ 848 zoomCurrentImage("out"); 849 } 850 851 /** 852 * zoom back 853 */ 854 this.zoomBack = function(){ 855 856 zoomCurrentImage("back"); 857 } 858}
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.