Best Python code snippet using Airtest
jquery.pinchzoomer.js
Source:jquery.pinchzoomer.js
1/*!2 * VERSION: 1.1 beta3 * DATE: 07-17-20154 * 5 * PinchZoomer jQuery Plugin6 *7 * @license Copyright (c) 2014, Ron Feliciano. All rights reserved.8 * This work is subject to the terms at http://codecanyon.net/licenses9 * 10 * @author: Ron Feliciano11 * contact me through http://codecanyon.net/user/ronfeliciano/?ref=ronfeliciano12 **/13 14(function(window, $)15{16 var ua = navigator.userAgent;17 18 function Utils()19 {20 21 }22 23 Utils.isFirefox = ua.indexOf('firefox') >= 0;24 Utils.isAndroid = (ua.indexOf("Android") >= 0);25 Utils.androidVer = (Utils.isAndroid) ? parseFloat(ua.slice(ua.indexOf("Android")+8)) : null;26 27 Utils.isiPad = navigator.userAgent.match(/iPad/i) != null;28 Utils.isiPhone = (navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1);29 30 31 Utils.browser = (function()32 {33 var ua= navigator.userAgent, 34 tem, 35 M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i) || [];36 37 if(/trident/i.test(M[1]))38 {39 tem= /\brv[ :]+(\d+(\.\d+)?)/g.exec(ua) || [];40 return {name:"IE", version:(tem[1] || '') };41 }42 M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];43 44 if((tem= ua.match(/version\/([\.\d]+)/i))!= null) 45 {46 M[2]= tem[1];47 }48 49 if(M.length > 2)50 {51 return {name:M[0], version:M[2] };52 }53 else54 {55 return {name:M[0], version:M[1] };56 }57 58 })();59 Utils.objectToString = function(o)60 {61 var parse = function(_o)62 {63 var a = [], t;64 for(var p in _o)65 {66 if(_o.hasOwnProperty(p))67 {68 t = _o[p];69 if(t && typeof t == "object")70 {71 a[a.length]= p + ":{ " + arguments.callee(t).join(", ") + "}";72 }73 else 74 {75 if(typeof t == "string")76 {77 a[a.length] = [ p+ ": \"" + t.toString() + "\"" ];78 }79 else80 {81 if(t != null)82 {83 a[a.length] = [ p+ ": " + t.toString()];84 }85 }86 }87 }88 }89 90 return a;91 }92 93 return "{" + parse(o).join(", ") + "}";94 }95 96 Utils.getRealValue = function (str)97 {98 val = str;99 if(str !== undefined)100 {101 if(!isNaN(Number(str)))102 {103 val = Number(str);104 }105 else if(str.toLowerCase !== undefined && (str.toLowerCase() == "true" || str.toLowerCase() == "false"))106 {107 val = (str.toLowerCase() == "true");108 }109 else110 {111 var temp = Utils.getObj(str);112 if(temp != null)113 {114 val = temp;115 }116 }117 }118 119 return val;120 }121 122 Utils.getObj = function(str)123 {124 str = (str === undefined) ? "" : str;125 var f = window;126 var m = str.split(".");127 var length = m.length;128 for(var i = 0; i < length; i++)129 {130 if(f[m[i]] !== undefined)131 {132 f = f[m[i]];133 }134 else135 {136 i = length; 137 }138 }139 140 f = (f !== window) ? f : null;141 142 return f;143 }144 145 Utils.getObjects = function(value)146 {147 var objectNames = value.split(";");148 var objects = [];149 var i;150 var length = objectNames.length;151 152 if(length == 0)153 {154 objectNames = value.split(",");155 length = objectNames.length;156 }157 158 for(i = 0; i < length; i++)159 {160 var objectName = Utils.hyphenToCamelCase($.trim(objectNames[i]));161 var object = Utils.getObj(objectName);162 if(object != null)163 {164 if($.isArray(object))165 {166 var objectLength = object.length;167 var j;168 for(j = 0; j < objectLength; j++)169 {170 objects.push(object[j]);171 }172 }173 else174 {175 objects.push(object); 176 }177 }178 }179 180 return objects;181 }182 183 Utils.getScope = function(str)184 { 185 var f = window;186 var m = str.split(".");187 188 if(m.length > 0)189 {190 var length = m.length;191 for(var i = 1; i < length - 1; i++)192 {193 if(f[m[i]] !== undefined)194 {195 f = f[m[i]];196 }197 else198 {199 i = length; 200 } 201 }202 }203 204 return f;205 }206 207 Utils.getParams = function(str)208 {209 var params = null;210 if(str !== undefined)211 {212 params = [];213 var values = str.split(",");214 var i;215 var length = values.length;216 for(i = 0; i < values.length; i++)217 {218 params.push(Utils.getRealValue($.trim(values[i])))219 }220 }221 222 return params;223 }224 225 Utils.trimSpaces = function(str)226 {227 var trimStr = "";228 if(str !== undefined)229 {230 trimStr = str;231 var length = trimStr.length;232 var startIndex = 0;233 var endIndex = length - 1;234 var i;235 236 for(i = 0; i < length; i++)237 {238 if(trimStr.charAt(i) != ' ')239 {240 startIndex = i;241 i = length;242 }243 }244 245 for(i = length - 1; i >= 0; i--)246 {247 if(trimStr.charAt(i) != ' ')248 {249 endIndex = i;250 i = -1;251 }252 }253 254 trimStr = trimStr.substr(startIndex, endIndex - startIndex + 1);255 }256 257 return trimStr;258 }259 260 Utils.getAttrObjectFromString = function(str, initObject)261 {262 str = str || "";263 var o = (initObject == null) ? {} : initObject;264 265 if(str != "")266 {267 var groups = str.split(";"),268 i,269 length = groups.length;270 271 if(length == 0)272 {273 groups = str.split(",");274 length = groups.length;275 }276 277 for(i = 0; i < length; i++)278 {279 var attr = groups[i].split(":"),280 prop = Utils.hyphenToCamelCase($.trim(attr[0])),281 val = attr[1];282 283 for(var j = 2; j < attr.length; j++)284 {285 val += ":" + attr[j];286 }287 288 val = Utils.getRealValue($.trim(val));289 290 291 if(prop != "")292 {293 o[prop] = val; 294 }295 }296 }297 298 return o;299 }300 301 Utils.getChildAttrObjectFromElem = function(elem, pluginName)302 {303 var o = {};304 305 var children = elem.children();306 var length = children.length;307 for (var i = 0; i < length; i++)308 { 309 var child = children.eq(i);310 if(child.is(pluginName))311 {312 var elemChild = children.get(i);313 for (var j = 0; j < elemChild.attributes.length; j++) 314 {315 var attr = elemChild.attributes[j];316 o[attr.name] = getRealValue(attr.value);317 }318 }319 }320 321 return o;322 }323 324 Utils.hyphenToCamelCase = function(value)325 {326 return value.replace(/-([a-z])/gi, function(s, g) { return g.toUpperCase(); } );327 }328 329 Utils.getStyleSheetObject = function (selector)330 {331 var styleObj = {};332 333 for(var i = 0; i < document.styleSheets.length; i++)334 {335 var cssRules = document.styleSheets[i].cssRules || document.styleSheets[i].rules || [];336 for(var j = 0; j < cssRules.length; j++)337 {338 var selectorText = cssRules[j].selectorText;339 if(selectorText !== undefined)340 {341 var selectors = selectorText.split(",");342 343 for(var k = 0; k < selectors.length; k++)344 {345 var styleSelector = $.trim(selectors[k]);346 if(styleSelector == selector)347 {348 styleObj = $.extend(styleObj, Utils.getAttrObjectFromString(cssRules[j].style.cssText));349 }350 }351 }352 }353 }354 355 return styleObj;356 }357 358 Utils.preventDefault = function (e)359 {360 if (e.preventDefault) 361 { 362 e.preventDefault(); 363 } 364 else 365 { 366 e.returnValue = false; 367 }368 }369 370 Utils.preventGestureDefault = function (e)371 {372 e.gesture.preventDefault();373 }374 375 Utils.shuffleArray = function(array) 376 {377 var currentIndex = array.length, 378 temporaryValue,379 randomIndex;380 381 while (0 !== currentIndex) 382 {383 randomIndex = Math.floor(Math.random() * currentIndex);384 currentIndex -= 1;385 386 temporaryValue = array[currentIndex];387 array[currentIndex] = array[randomIndex];388 array[randomIndex] = temporaryValue;389 }390 391 return array;392 }393 394 window.Utils = Utils;395 396}(window, jQuery));397(function(window, $)398{399 function PinchZoomer(_pinchZoomerDiv, imageUrl, varsObj)400 {401 TweenLite.defaultOverwrite = "auto";402 //_vars403 var _vars = $.extend({ animDuration:0.3, maxZoom:5, minZoom:1, ease:Power4.easeOut, allowZoom:true, allowMouseWheel:true, doubleTapZoom:2, zoomStep:0.5, adjustWidth:0, adjustHeight:0, preloaderUrl:null, resizeDuration:-1, initXPercent:0.5, initYPercent:0.5, scrollTarget:window, force3D:true, onZoom:null, onZoomParams:null, onZoomStart:null, onZoomStartParams:null, onZoomComplete:null, onZoomCompleteParams:null, onImageLoad:null, onImageLoadParams:null, onInit:null, onInitParams:null, handleOverDragX:true, handleOverDragY:false }, varsObj),404 //elements405 pinchZoomerDiv = $(_pinchZoomerDiv),406 imageHolder = $("<div style='position:absolute; width:100%; height:100%; overflow:hidden; -ms-touch-action:none; touch-action:none;'></div>"),407 _image = $("<img style='position:absolute; max-width:none; display:block;'>").load(onImageLoad),408 preloader = ($.type(_vars.preloaderUrl) === "string") ? $("<img style='position:absolute; max-width:none; display:block;'>").load( onPreloaderImageLoad ) : null,409 hiddenHolder = $("<div style='width:1px; height:1px; left:-1px; top:-1px; position:absolute; overflow:hidden'></div>"),410 411 //size _vars412 _imageHolderWidth = -1,413 _imageHolderHeight = -1,414 prevHolderWidth = -1,415 prevHolderHeight = -1,416 _imageWidth = 0,417 _imageHeight = 0,418 preloaderWidth = 0,419 preloaderHeight = 0,420 _newImageWidth = 0,421 _newImageHeight = 0,422 realLeft = 0,423 realTop = 0,424 _imageLoaded = false,425 mouseEnabled = true,426 mouseTweenObj = {},427 428 //browser function test429 useTransform = (window.Modernizr != undefined) ? Modernizr.csstransforms : true,430 431 //touch events432 touchHandler = null,433 imageTouchHandler = null,434 435 //transform _vars436 endZoom = 1,437 computedZoom = 1,438 oldZoom = -1,439 curX = 0,440 curY = 0,441 oldX = 0,442 oldY = 0,443 oldScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0},444 parScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0},445 newScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0},446 dragDistanceX = 0,447 dragDistanceY = 0,448 snap = false,449 oldSlideIndex = 0,450 startDragX = 0,451 startDragY = 0,452 touchCount = 0,453 oldTouchCount = -1,454 touchId = 0,455 oldTouchId = -1,456 transformInit = false,457 dragInit = false,458 touchReady = true,459 useControls = false,460 sliderLeft = 0,461 sliderTop = 0,462 startScrollX = 0,463 startScrollY = 0,464 startScrollLeft = 0,465 startScrollTop = 0,466 appendScrollX = 0,467 appendScrollY = 0,468 scrollInit = true,469 useSize = false,470 _enableMouseWheel = _vars.allowMouseWheel,471 multiPointer = (navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) || (navigator.maxTouchPoints && navigator.maxTouchPoints > 1),472 curTouchAction = "",473 panTouchAction = "pan-x pan-y",474 use3D = Utils.browser.name != "Chrome" && !useSize;475 476 var zoomSpx = null,477 zoomSpy = null;478 479 if($(_vars.scrollTarget).length != 0)480 {481 _vars.scrollTarget = $(_vars.scrollTarget);482 }483 else484 {485 _vars.scrollTarget = $(window);486 }487 488 this.zoomIn = _zoomIn;489 this.zoomOut = _zoomOut;490 this.zoom = _zoom;491 this.imageWidth = getImageWidth;492 this.imageHeight = getImageHeight;493 this.newImageWidth = getNewImageWidth;494 this.newImageHeight = getNewImageHeight;495 this.resize = onWindowResize;496 this.imageLoaded = isImageLoaded;497 this.image = _image;498 this.vars = _vars;499 this.imageX = _imageX;500 this.imageY = _imageY;501 this.imageHolderWidth = getImageHolderWidth;502 this.imageHolderHeight = getImageHolderHeight;503 504 this.naturalWidth = getImageWidth;505 this.naturalHeight = getImageHeight;506 this.naturalOffsetX = getNaturalOffsetX;507 this.naturalOffsetY = getNaturalOffsetY;508 this.enableMouseWheel = enableMouseWheel;509 510 _init();511 512 function _init()513 {514 pinchZoomerDiv.prepend(imageHolder);515 useSize = (Utils.isAndroid || Utils.isiPad || Utils.isiPhone) && (imageUrl.indexOf(".svg") != -1) || (Utils.androidVer !== null && Utils.androidVer < 3);516 517 518 $("body").append(hiddenHolder);519 520 if(preloader != null)521 {522 TweenMax.set(preloader, { autoAlpha:0 } );523 hiddenHolder.append(preloader);524 preloader.attr("src", _vars.preloaderUrl);525 }526 527 hiddenHolder.append(_image);528 TweenMax.set(_image, { autoAlpha:0 } );529 _image.attr("src", imageUrl);530 531 onWindowResize();532 533 //touch events534 touchHandler = imageHolder.hammer( 535 {536 swipe:false,537 dragMaxTouches: 4538 });539 540 var touchEvt = "touchstart touchend";541 542 if(window.PointerEvent) 543 {544 touchEvt = "pointerdown pointerup";545 } 546 else if (window.MSPointerEvent)547 {548 touchEvt = "MSPointerDown MSPointerUp";549 }550 else551 {552 //enableMouse(); 553 }554 555 //touchHandler.on(touchEvt, onTouch);556 touchHandler.on("gesture", onGesture);557 558 if(_vars.allowZoom && _vars.allowMouseWheel)559 {560 imageHolder.on("mousewheel", Utils.preventDefault);561 imageHolder.on("mousewheel", onImageWheel);562 }563 564 imageTouchHandler = _image.hammer( 565 {566 dragMinDistance: 0,567 swipe:false,568 dragMaxTouches: 4569 });570 571 imageTouchHandler.on("doubletap", onDoubleTap);572 //document.ondragstart = function () { return false; };573 //imageTouchHandler.on("drag", Utils.preventGestureDefault);574 575 if(_vars.scaleMode != "fullWidth" && _vars.scaleMode != "fullHeight")576 {577 _vars.initXPercent = 0.5;578 _vars.initYPercent = 0.5;579 }580 581 $(window).resize(onWindowResize);582 583 if(!isNaN(_vars.resizeDuration) && _vars.resizeDuration > 0)584 {585 TweenMax.to(this, _vars.resizeDuration, { onRepeat:onWindowResize, repeat:-1 } );586 }587 }588 589 function onGesture(e)590 {591 var type = e.gesture.eventType;592 593 touchCount = e.gesture.touches.length;594 if(type != "move")595 {596 if(type == "end")597 {598 touchCount = 0; 599 if(touchCount > 1 || endZoom > 1)600 {601 setTouchAction("none");602 603 }604 else 605 {606 setTouchAction(panTouchAction);607 } 608 }609 if(touchCount != oldTouchCount)610 {611 setupGestures();612 }613 oldTouchCount = touchCount;614 if(touchCount > 1 || endZoom > 1)615 {616 setTouchAction("none");617 e.gesture.srcEvent.preventDefault(); 618 }619 else 620 {621 setTouchAction(panTouchAction);622 }623 }624 625 if(touchCount > 1 || endZoom > 1)626 {627 e.gesture.srcEvent.preventDefault(); 628 }629 }630 631 function setTouchAction(value)632 {633 if(multiPointer && value != curTouchAction)634 {635 curTouchAction = value;636 if(imageHolder != null)637 {638 TweenLite.set(imageHolder, { touchAction:curTouchAction });639 }640 }641 }642 643 function enableMouseWheel(val)644 {645 if(val !== undefined)646 {647 _enableMouseWheel = val == true;648 if(_enableMouseWheel)649 {650 imageHolder.on("mousewheel", Utils.preventDefault);651 imageHolder.on("mousewheel", onImageWheel);652 }653 else654 {655 imageHolder.off("mousewheel", Utils.preventDefault);656 imageHolder.off("mousewheel", onImageWheel);657 }658 }659 660 return _enableMouseWheel;661 }662 663 function onPreloaderImageLoad(e)664 {665 if(!_imageLoaded)666 {667 preloaderWidth = preloader.width();668 preloaderHeight = preloader.height();669 670 var preloaderX = ((_imageHolderWidth - preloaderWidth) * 0.5) + "px",671 preloaderY = ((_imageHolderHeight - preloaderHeight) * 0.5) + "px";672 673 TweenMax.set(preloader, { position:"absolute", maxWidth:"none", x:preloaderX, y:preloaderY, autoAlpha:1} );674 imageHolder.append(preloader);675 }676 }677 678 function onWindowResize(e)679 {680 var forceResize = ($.type(e) === "boolean") ? e : false;681 682 _imageHolderWidth = imageHolder.width() + _vars.adjustWidth;683 _imageHolderHeight = imageHolder.height() + _vars.adjustHeight;684 685 if(forceResize || prevHolderWidth != _imageHolderWidth || prevHolderHeight != _imageHolderHeight)686 {687 688 if(preloaderWidth != 0)689 {690 onPreloaderImageLoad();691 }692 693 resetImage();694 695 dragDistanceX = 0;696 dragDistanceY = 0;697 698 resetTransform();699 700 touchCount = 0;701 touchId = 0;702 oldTouchId = -1;703 snap = false;704 touchReady = true;705 706 prevHolderWidth = _imageHolderWidth;707 prevHolderHeight = _imageHolderHeight;708 }709 }710 711 function onImageLoad(e)712 {713 TweenMax.set(_image, { width:"auto", height:"auto" } );714 _imageWidth = _image.width();715 _imageHeight = _image.height();716 _imageLoaded = true;717 718 TweenMax.to(_image, _vars.animDuration, { autoAlpha:1, ease:_vars.ease } );719 TweenMax.set(_image, { display:"block" } );720 if(preloader != null)721 {722 preloader.detach();723 }724 725 imageHolder.prepend(_image);726 727 resetImage();728 onWindowResize();729 730 if($.isFunction(_vars.onImageLoad))731 {732 _vars.onImageLoad.apply(null, _vars.onImageLoadParams);733 }734 735 if($.isFunction(_vars.onInit))736 {737 _vars.onInit.apply(null, _vars.onInitParams);738 }739 740 }741 742 function getImageWidth()743 {744 return _imageWidth; 745 }746 747 function getImageHeight()748 {749 return _imageHeight; 750 }751 752 function getNaturalWidth()753 {754 return _imageWidth; 755 }756 757 function getNaturalHeight()758 {759 return _imageHeight; 760 }761 762 function getNaturalOffsetX()763 {764 return curX / _newImageWidth;765 }766 767 function getNaturalOffsetY()768 {769 return curY / _newImageHeight;770 }771 772 function getNewImageWidth()773 {774 return _newImageWidth; 775 }776 777 function getNewImageHeight()778 {779 return _newImageHeight; 780 }781 782 function isImageLoaded()783 {784 return _imageLoaded; 785 }786 787 function resetImage()788 {789 if(_imageLoaded)790 {791 if(_imageWidth == 0 || _imageHeight == 0)792 {793 _imageWidth = _image.width();794 _imageHeight = _image.height();795 }796 797 var tempImageWidth = _imageWidth,798 tempImageHeight = _imageHeight,799 horizontalScale = _imageHolderWidth / tempImageWidth, 800 verticalScale = _imageHolderHeight / tempImageHeight,801 curScale = horizontalScale;802 803 if(_vars.scaleMode == "fullWidth")804 {805 curScale = horizontalScale;806 }807 else if(_vars.scaleMode == "fullHeight")808 {809 curScale = verticalScale;810 }811 else if(tempImageHeight * horizontalScale > _imageHolderHeight)812 {813 curScale = verticalScale;814 }815 816 if(tempImageWidth == 0 || tempImageHeight == 0 || isNaN(curScale))817 {818 curScale = 1;819 }820 821 _newImageWidth = Math.ceil(tempImageWidth * curScale),822 _newImageHeight = Math.ceil(tempImageHeight * curScale);823 824 _imageWidth = tempImageWidth;825 _imageHeight = tempImageHeight;826 827 realLeft = ((((_imageHolderWidth - _newImageWidth) * _vars.initXPercent)) >> 0);828 realTop = ((((_imageHolderHeight - _newImageHeight) * _vars.initYPercent)) >> 0);829 830 831 var cssObj = { width:_newImageWidth, height:_newImageHeight, left:realLeft + "px", top:realTop + "px" };832 833 if(useTransform && !useSize)834 {835 cssObj.scale = 1;836 cssObj.transformOrigin = "0 0";837 cssObj.x = 0;838 cssObj.y = 0; 839 }840 else841 {842 cssObj.marginLeft = 0;843 cssObj.marginTop = 0; 844 }845 846 TweenMax.set(_image, cssObj);847 }848 }849 850 function onImageWheel(e, delta, deltaX, deltaY)851 {852 if(_vars.allowZoom)853 {854 sliderLeft = imageHolder.offset().left;855 sliderTop = imageHolder.offset().top;856 var spx = (e.pageX - realLeft - curX - sliderLeft) / endZoom,857 spy = (e.pageY - realTop - curY - sliderTop) / endZoom;858 859 initZoom(spx, spy);860 if(delta > 0)861 {862 computedZoom += _vars.zoomStep;863 }864 else865 {866 computedZoom -= _vars.zoomStep;867 }868 setPosition();869 adjustPosition();870 endZoom = computedZoom;871 872 handleZoom();873 }874 875 Utils.preventDefault(e);876 }877 878 function onTouch(e)879 {880 var type = e.type;881 882 if(type !== undefined && type.indexOf("ointer") != -1)883 {884 if(type == "pointerdown" || type == "MSPointerDown")885 {886 touchCount ++;887 }888 else if(type == "pointerup" || type == "MSPointerUp")889 {890 touchCount --;891 if(touchCount < 0)892 {893 touchCount = 0;894 }895 }896 }897 else898 {899 touchCount = e.originalEvent.touches.length;900 if(touchCount > 0)901 {902 TweenMax.to(mouseTweenObj, 0.0, { onComplete:disableMouse } );903 }904 else905 {906 TweenMax.to(mouseTweenObj, 0.5, { onComplete:enableMouse } );907 }908 }909 910 if(touchCount != oldTouchCount)911 {912 setupGestures();913 }914 915 oldTouchCount = touchCount;916 }917 918 function onImageDown(e)919 {920 921 if(mouseEnabled)922 {923 touchCount = 1;924 925 if(touchCount != oldTouchCount)926 {927 setupGestures();928 }929 930 oldTouchCount = touchCount;931 }932 933 }934 935 function onImageUp(e)936 {937 938 if(mouseEnabled)939 {940 touchCount = 0;941 942 if(touchCount != oldTouchCount)943 {944 setupGestures();945 }946 947 oldTouchCount = touchCount;948 }949 950 }951 952 function enableMouse()953 {954 imageHolder.on("mousedown", onImageDown);955 imageHolder.on("mouseup mouseleave", onImageUp);956 mouseEnabled = true;957 }958 959 function disableMouse()960 {961 imageHolder.off("mousedown", onImageDown);962 imageHolder.off("mouseup mouseleave", onImageUp);963 mouseEnabled = false;964 }965 966 function setupGestures()967 {968 touchId = (touchCount > 1) ? 2 : touchCount;969 var gestureInit = (touchId != oldTouchId);970 971 if(touchCount == 1)972 {973 if(touchReady)974 {975 dragInit = gestureInit;976 disableTransform();977 enableDrag();978 }979 980 if(oldTouchId == 2)981 {982 endZoom = computedZoom;983 }984 }985 else if(touchCount > 1)986 {987 if(touchReady)988 {989 transformInit = gestureInit;990 disableDrag();991 enableTransform();992 }993 }994 else995 {996 disableTransform();997 disableDrag();998 onGestureEnd();999 }1000 1001 oldTouchId = touchId;1002 }1003 1004 function onGestureEnd()1005 {1006 endZoom = computedZoom;1007 }1008 1009 function enableDrag()1010 {1011 dragInit = true;1012 scrollInit = true;1013 touchHandler.on("drag", onDrag);1014 }1015 1016 function enableTransform()1017 {1018 if(_vars.allowZoom)1019 {1020 touchHandler.on("transform", onTransform);1021 }1022 }1023 1024 function disableDrag()1025 {1026 touchHandler.off("drag", onDrag);1027 }1028 1029 function disableTransform()1030 {1031 touchHandler.off("transform", onTransform);1032 }1033 1034 function onDoubleTap(e)1035 {1036 sliderLeft = imageHolder.offset().left;1037 sliderTop = imageHolder.offset().top;1038 var spx = (e.gesture.touches[0].pageX - realLeft - curX - sliderLeft) / endZoom,1039 spy = (e.gesture.touches[0].pageY- realTop - curY - sliderTop) / endZoom;1040 1041 initZoom(spx, spy);1042 transformInit = false;1043 1044 computedZoom = (endZoom == 1) ? _vars.doubleTapZoom : 1;1045 1046 setPosition();1047 adjustPosition();1048 endZoom = computedZoom;1049 handleZoom();1050 }1051 1052 function onTransform(e)1053 {1054 if(transformInit)1055 { 1056 sliderLeft = imageHolder.offset().left;1057 sliderTop = imageHolder.offset().top;1058 var spx = (e.gesture.center.pageX - realLeft - curX - sliderLeft) / endZoom,1059 spy = (e.gesture.center.pageY - realTop - curY - sliderTop) / endZoom;1060 1061 initZoom(spx, spy);1062 transformInit = false;1063 }1064 1065 computedZoom = endZoom * e.gesture.scale;1066 1067 setPosition();1068 adjustPosition();1069 handleZoom();1070 }1071 1072 function onDrag(e)1073 {1074 if(dragInit)1075 {1076 startDragX = e.gesture.center.clientX;1077 startDragY = e.gesture.center.clientY;1078 oldX = curX;1079 oldY = curY;1080 dragInit = false;1081 }1082 curX = oldX + e.gesture.center.clientX - startDragX;1083 curY = oldY + e.gesture.center.clientY - startDragY;1084 1085 //console.log("cx: " + curX + " cy: " + curY);1086 //console.log(e);1087 setMove();1088 }1089 1090 function adjustPosition()1091 {1092 var computedWidth = _newImageWidth * computedZoom;1093 computedHeight = _newImageHeight * computedZoom;1094 1095 var oY = curY;1096 if(computedWidth <= _imageHolderWidth)1097 {1098 curX = ((_imageHolderWidth - computedWidth) * _vars.initXPercent) - realLeft;1099 }1100 else if(curX + realLeft > 0 || curX + computedWidth + realLeft < _imageHolderWidth)1101 {1102 if(curX + realLeft > 0)1103 {1104 curX = -realLeft;1105 }1106 else if(curX + computedWidth + realLeft < _imageHolderWidth)1107 {1108 curX = _imageHolderWidth - computedWidth - realLeft;1109 }1110 }1111 1112 if(computedHeight <= _imageHolderHeight)1113 {1114 curY = ((_imageHolderHeight - computedHeight) * _vars.initYPercent) - realTop;1115 }1116 else if(curY + realTop > 0 || curY + computedHeight + realTop < _imageHolderHeight)1117 {1118 if(curY + realTop > 0)1119 {1120 curY = -realTop;1121 }1122 else if(curY + computedHeight + realTop < _imageHolderHeight)1123 {1124 curY = _imageHolderHeight - computedHeight - realTop;1125 }1126 }1127 1128 curX = curX >> 0;1129 curY = curY >> 0;1130 1131 //_vars.scrollTarget.scrollLeft(_vars.scrollTarget.scrollLeft() + (appendScrollX));1132 /*1133 if(curY != oY)1134 {1135 var minus = Math.abs(oY - curY);1136 //_vars.scrollTarget.scrollTop(_vars.scrollTarget.scrollTop() + (appendScrollY + minus));1137 }1138 */1139 }1140 1141 function setPosition()1142 {1143 if(computedZoom > _vars.maxZoom)1144 {1145 computedZoom = _vars.maxZoom;1146 }1147 else if(computedZoom < _vars.minZoom)1148 {1149 computedZoom = _vars.minZoom;1150 }1151 1152 newScalePosObj.spx = parScalePosObj.spx;1153 newScalePosObj.spy = parScalePosObj.spy;1154 1155 newScalePosObj.nspx = (newScalePosObj.spx * computedZoom);1156 newScalePosObj.nspy = (newScalePosObj.spy * computedZoom);1157 1158 newScalePosObj.cx = (newScalePosObj.spx - newScalePosObj.nspx) >> 0;1159 newScalePosObj.cy = (newScalePosObj.spy - newScalePosObj.nspy) >> 0;1160 1161 curX = oldScalePosObj.cx + newScalePosObj.cx - parScalePosObj.cx;1162 curY = oldScalePosObj.cy + newScalePosObj.cy - parScalePosObj.cy;1163 }1164 1165 function resetTransform()1166 {1167 endZoom = 1;1168 computedZoom = 1;1169 1170 curX = 0;1171 curY = 0;1172 1173 oldScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0};1174 parScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0};1175 newScalePosObj = {spx:0, spy:0, nspx:0, nspy:0, cx:0, cy:0};1176 1177 zoomSpx = null;1178 zoomSpy = null;1179 1180 if($.isFunction(_vars.onZoom))1181 {1182 _vars.onZoom.apply(null, _vars.onZoomParams);1183 }1184 }1185 1186 function initZoom(spx, spy)1187 {1188 zoomSpx = spx;1189 zoomSpy = spy;1190 1191 oldScalePosObj.spx = newScalePosObj.spx;1192 oldScalePosObj.spy = newScalePosObj.spy;1193 oldScalePosObj.nspx = newScalePosObj.nspx;1194 oldScalePosObj.nspy = newScalePosObj.nspy;1195 oldScalePosObj.cx = curX;1196 oldScalePosObj.cy = curY;1197 1198 parScalePosObj.spx = spx >> 0;1199 parScalePosObj.spy = spy >> 0;1200 1201 parScalePosObj.nspx = (parScalePosObj.spx * endZoom);1202 parScalePosObj.nspy = (parScalePosObj.spy * endZoom);1203 1204 parScalePosObj.cx = (parScalePosObj.spx - parScalePosObj.nspx) >> 0;1205 parScalePosObj.cy = (parScalePosObj.spy - parScalePosObj.nspy) >> 0;1206 1207 computedZoom = endZoom;1208 }1209 1210 function handleZoom(duration)1211 {1212 var cssObj = { position:"absolute", ease:_vars.ease },1213 computedWidth = _newImageWidth * computedZoom;1214 computedHeight = _newImageHeight * computedZoom;1215 1216 if(use3D)1217 {1218 cssObj.force3D = _vars.force3D;1219 }1220 1221 duration = (!isNaN(duration)) ? duration : _vars.animDuration;1222 1223 //if($.isFunction(_vars.onZoomStart))1224 //{1225 1226 // if(oldZoom == 1 && computedZoom > 1 || oldZoom > 1 && computedZoom == _vars.maxZoom)1227 // {1228 cssObj.onStart = _vars.onZoomStart;1229 cssObj.onStartParams = _vars.onZoomStartParams;1230 // oldZoom = computedZoom;1231 // }1232 //}1233 1234 //if($.isFunction(_vars.onZoomComplete))1235 //{1236 cssObj.onComplete = _vars.onZoomComplete;1237 cssObj.onCompleteParams = _vars.onZoomCompleteParams;1238 //}1239 1240 if(useSize)1241 {1242 cssObj.width = computedWidth;1243 cssObj.height = computedHeight;1244 }1245 else1246 {1247 cssObj.scale = computedZoom; 1248 }1249 1250 if(useTransform && !useSize)1251 {1252 cssObj.x = curX;1253 cssObj.y = curY;1254 }1255 else1256 {1257 cssObj.marginLeft = curX;1258 cssObj.marginTop = curY;1259 }1260 1261 TweenMax.to(_image, duration, cssObj );1262 1263 1264 if($.isFunction(_vars.onZoom))1265 {1266 _vars.onZoom.apply(null, _vars.onZoomParams);1267 }1268 }1269 1270 1271 function setMove()1272 {1273 var adjX = curX,1274 adjY = curY;1275 1276 adjustPosition();1277 1278 snap = false;1279 1280 var cssObj = { ease:_vars.ease };1281 /*1282 if(use3D)1283 {1284 cssObj.force3D = _vars.force3D;1285 }1286 1287 if(useTransform && !useSize)1288 {1289 cssObj.x = curX;1290 cssObj.y = curY;1291 }1292 else1293 {1294 cssObj.marginLeft = curX;1295 cssObj.marginTop = curY;1296 }*/1297 cssObj.x = curX;1298 cssObj.y = curY;1299 TweenMax.to(_image, _vars.animDuration, cssObj );1300 1301 /*1302 if($.isFunction(_vars.onDrag))1303 {1304 _vars.onDrag.apply(null, _vars.onDrag);1305 }1306 */1307 }1308 1309 function _zoomIn()1310 {1311 _zoom(computedZoom + _vars.zoomStep);1312 }1313 1314 function _zoomOut()1315 {1316 _zoom(computedZoom - _vars.zoomStep);1317 }1318 1319 function _zoom(value, duration)1320 {1321 if(value !== undefined && _vars.allowZoom)1322 {1323 duration = (!isNaN(duration)) ? duration : _vars.animDuration;1324 var spx = Math.abs(curX / computedZoom) + ((_imageHolderWidth * 0.5) / computedZoom),1325 spy = Math.abs(curY / computedZoom) + ((_imageHolderHeight * 0.5) / computedZoom); 1326 1327 initZoom(spx, spy);1328 computedZoom = value;1329 1330 setPosition();1331 1332 adjustPosition();1333 endZoom = computedZoom;1334 1335 handleZoom(duration);1336 }1337 1338 return computedZoom;1339 }1340 1341 function _imageX(val)1342 {1343 if(val !== undefined)1344 {1345 curX = val;1346 adjustPosition(); 1347 handleZoom();1348 }1349 return curX;1350 }1351 1352 function _imageY(val)1353 {1354 if(val !== undefined)1355 {1356 curY = val;1357 adjustPosition(); 1358 handleZoom();1359 }1360 1361 return curY;1362 }1363 1364 function getImageHolderWidth()1365 {1366 return _imageHolderWidth; 1367 }1368 1369 function getImageHolderHeight()1370 {1371 return _imageHolderHeight;1372 }1373 }1374 1375 window.PinchZoomer = PinchZoomer;1376 PinchZoomer.objs = [];1377 PinchZoomer.lastIndex = 0;1378 PinchZoomer.fullscreenDiv = $("<div style='width:100%; height:100%; top:0px; left:0px; position:absolute;' class='fullscreenDivBg'></div>");1379 PinchZoomer.initFullScreenEvent = false;1380 PinchZoomer.fullscreenAllowed = window.screenfull !== undefined && screenfull.enabled;1381 PinchZoomer.curScrollLeft = $("body").scrollLeft();1382 PinchZoomer.curScrollTop = $("body").scrollTop();1383 PinchZoomer.curBodyOverflow = $("body").css("overflow");1384 1385 PinchZoomer.remove = function(idOrIndex)1386 {1387 var pinchZoomerObj = null;1388 1389 if(!isNaN(idOrIndex))1390 {1391 pinchZoomerObj = PinchZoomer.objs[idOrIndex];1392 pinchZoomerObj.outerDiv.remove();1393 PinchZoomer.objs[i] = null;1394 PinchZoomer.objs[i] = { removed:true };1395 }1396 else1397 {1398 var len = PinchZoomer.objs.length;1399 for(var i = 0; i < len; i++)1400 {1401 if(PinchZoomer.objs[i].id == idOrIndex)1402 {1403 pinchZoomerObj = PinchZoomer.objs[i];1404 pinchZoomerObj.outerDiv.remove();1405 PinchZoomer.objs[i] = null;1406 PinchZoomer.objs[i] = { removed:true };1407 i = len;1408 }1409 }1410 }1411 }1412 1413 PinchZoomer.removeAll = function()1414 {1415 var len = PinchZoomer.objs.length;1416 for(var i = 0; i < len; i++)1417 {1418 var pinchZoomerObj = PinchZoomer.objs[i];1419 if(!pinchZoomerObj.removed)1420 {1421 pinchZoomerObj.outerDiv.remove();1422 }1423 PinchZoomer.objs[i] = null;1424 }1425 1426 PinchZoomer.objs = null;1427 PinchZoomer.objs = [];1428 }1429 1430 1431 PinchZoomer.getObj = function(idOrIndex)1432 {1433 var pinchZoomerObj = null;1434 1435 if(!isNaN(idOrIndex))1436 {1437 pinchZoomerObj = PinchZoomer.objs[idOrIndex];1438 }1439 else1440 {1441 var len = PinchZoomer.objs.length;1442 for(var i = 0; i < len; i++)1443 {1444 if(PinchZoomer.objs[i].id == idOrIndex)1445 {1446 pinchZoomerObj = PinchZoomer.objs[i];1447 i = len;1448 }1449 }1450 }1451 1452 return pinchZoomerObj;1453 }1454 1455 PinchZoomer.get = function(idOrIndex)1456 {1457 var pinchZoomerObj = PinchZoomer.getObj(idOrIndex),1458 pinchZoomer = (pinchZoomerObj != null && !pinchZoomerObj.removed) ? pinchZoomerObj.pinchZoomer : null;1459 1460 return pinchZoomer;1461 }1462 1463 PinchZoomer.init = function(imgs, _vars)1464 {1465 _vars = _vars || {};1466 1467 if (!PinchZoomer.initFullScreenEvent && PinchZoomer.fullscreenAllowed) 1468 {1469 var versionNum = Number(Utils.browser.version.split(".")[0]);1470 1471 if(Utils.browser.name == "Safari" && versionNum < 6)1472 {1473 PinchZoomer.fullscreenAllowed = false; 1474 }1475 else1476 { 1477 document.addEventListener(screenfull.raw.fullscreenchange, onFullScreenChange);1478 document.addEventListener(screenfull.raw.fullscreenerror, onFullScreenError);1479 }1480 }1481 1482 if (!PinchZoomer.initFullScreenEvent)1483 {1484 PinchZoomer.fullscreenDiv.hammer().on("drag", Utils.preventGestureDefault);1485 }1486 1487 PinchZoomer.initFullScreenEvent = true;1488 1489 var pinchZoomerImages = $(imgs || "img[data-elem='pinchzoomer']").filter("img"),1490 pinchZoomerLen = pinchZoomerImages.length;1491 1492 for(var i = 0; i < pinchZoomerLen; i++)1493 {1494 var pinchZoomerObj = {},1495 index = PinchZoomer.objs.length;1496 1497 pinchZoomerObj.removed = false;1498 pinchZoomerObj.image = pinchZoomerImages.eq(i);1499 pinchZoomerObj.originalImage = pinchZoomerImages.eq(i);1500 pinchZoomerObj.id = pinchZoomerObj.image.attr("id") || "img" + PinchZoomer.lastIndex;1501 pinchZoomerObj.vars = $.extend( { scaleMode:"widthOnly" }, (_vars.imageOptions || Utils.getAttrObjectFromString(pinchZoomerObj.image.data("options"))));1502 pinchZoomerObj.origScaleMode = pinchZoomerObj.vars.scaleMode;1503 pinchZoomerObj.controlVars = $.extend( { alwaysShow:false }, (_vars.controlOptions || Utils.getAttrObjectFromString(pinchZoomerObj.image.data("control-options"))));1504 pinchZoomerObj.vars.onImageLoad = onPinchZoomerImageLoad;1505 pinchZoomerObj.vars.onImageLoadParams = [index];1506 pinchZoomerObj.vars.onZoomStart = onImageZoom;1507 pinchZoomerObj.vars.onZoomStartParams = [index];1508 1509 pinchZoomerObj.outerDiv = $("<div class='outerDiv' style='position:relative;'></div>")1510 pinchZoomerObj.innerDiv = $("<div class='innerDiv' style='position:absolute: top:0px; left:0px; width:100%; height:100%;'></div>");1511 1512 pinchZoomerObj.outerDiv.append(pinchZoomerObj.innerDiv);1513 pinchZoomerObj.originalParent = pinchZoomerObj.image.parent();1514 pinchZoomerObj.tempDiv = $("<div></div>");1515 pinchZoomerObj.image.replaceWith(pinchZoomerObj.outerDiv);1516 1517 pinchZoomerObj.zoomInButton = $("<div></div>");1518 pinchZoomerObj.outerDiv.append(pinchZoomerObj.zoomInButton);1519 1520 pinchZoomerObj.zoomInOnObj = getStyle(_vars.zoomInOnStyle || pinchZoomerObj.image.data("zoomin-on") || "zoomInOn");1521 pinchZoomerObj.zoomInOffObj = getStyle(_vars.zoomInOffStyle || pinchZoomerObj.image.data("zoomin-off") || "zoomInOff");1522 1523 pinchZoomerObj.zoomOutButton = $("<div></div>");1524 pinchZoomerObj.outerDiv.append(pinchZoomerObj.zoomOutButton);1525 1526 pinchZoomerObj.zoomOutOnObj = getStyle(_vars.zoomOutOnStyle || pinchZoomerObj.image.data("zoomout-on") || "zoomOutOn");1527 pinchZoomerObj.zoomOutOffObj = getStyle(_vars.zoomOutOffStyle || pinchZoomerObj.image.data("zoomout-off") || "zoomOutOff");1528 1529 1530 pinchZoomerObj.zoomInButton.hammer().on("tap", {index:index}, onZoomIn);1531 pinchZoomerObj.zoomOutButton.hammer().on("tap", {index:index}, onZoomOut);1532 1533 pinchZoomerObj.fullscreenButton = $("<div></div>");1534 if(PinchZoomer.fullscreenAllowed)1535 {1536 pinchZoomerObj.outerDiv.append(pinchZoomerObj.fullscreenButton);1537 }1538 pinchZoomerObj.fullscreenObj = getStyle(_vars.fullscreenStyle || pinchZoomerObj.image.data("fullscreen") || "fullscreen");1539 pinchZoomerObj.fullscreenButton.on("click", {index:index}, onFullscreenToggle);1540 1541 pinchZoomerObj.controlVisible = false;1542 pinchZoomerObj.oldZoomInEnabled = true;1543 pinchZoomerObj.oldZoomOutEnabled = false;1544 1545 pinchZoomerObj.image.remove();1546 1547 pinchZoomerObj.outerDiv.hammer().on("tap", {index:index}, onInput);1548 pinchZoomerObj.outerDiv.on("mouseover", {index:index}, onInput);1549 pinchZoomerObj.outerDiv.on("mouseout", {index:-1}, onInput);1550 1551 var imgSrc = pinchZoomerObj.image.attr("src"), 1552 src = (imgSrc != "#") ? imgSrc : pinchZoomerObj.image.data("src");1553 1554 1555 pinchZoomerObj.pinchZoomer = new PinchZoomer(pinchZoomerObj.innerDiv, src, pinchZoomerObj.vars );1556 1557 PinchZoomer.objs.push(pinchZoomerObj);1558 setZoomButtonState(index, true);1559 PinchZoomer.lastIndex ++;1560 }1561 1562 1563 1564 setActiveControls(-1);1565 $(window).resize(resizeAll);1566 1567 function getStyle(value)1568 {1569 var style = {};1570 1571 if(value.indexOf(":") == -1)1572 {1573 style = { className:value };1574 1575 }1576 else1577 {1578 style = Utils.getAttrObjectFromString(value);1579 }1580 1581 return style;1582 }1583 1584 function resizeAll()1585 {1586 for(var i = 0; i < PinchZoomer.objs.length; i++)1587 {1588 var pinchZoomerObj = PinchZoomer.objs[i],1589 scaleMode = pinchZoomerObj.vars.scaleMode;1590 1591 if(scaleMode != "none" && PinchZoomer.objs[i].outerDiv.is(":visible"))1592 {1593 resizeOuterDiv(i);1594 }1595 }1596 }1597 1598 function onPinchZoomerImageLoad(index)1599 {1600 resizeOuterDiv(index);1601 setActiveControls(-1);1602 }1603 1604 function resizeOuterDiv(index)1605 {1606 var pinchZoomerObj = PinchZoomer.objs[index];1607 1608 if(!pinchZoomerObj.removed) 1609 { 1610 var pinchZoomer = PinchZoomer.objs[index].pinchZoomer;1611 1612 if(pinchZoomer.imageLoaded())1613 {1614 var scaleMode = pinchZoomerObj.vars.scaleMode,1615 imageWidth = pinchZoomer.imageWidth(),1616 imageHeight = pinchZoomer.imageHeight(),1617 holderWidth = pinchZoomerObj.outerDiv.parent().width(),1618 holderHeight = pinchZoomerObj.outerDiv.parent().height(),1619 widthScale = holderWidth / imageWidth,1620 heightScale = holderHeight / imageHeight,1621 newOuterWidth = imageWidth * heightScale,1622 newOuterHeight = imageHeight * widthScale;1623 1624 if(scaleMode.indexOf("full") != -1)1625 {1626 newOuterWidth = "100%";1627 newOuterHeight = "100%";1628 }1629 else1630 {1631 if(scaleMode == "widthOnly")1632 {1633 newOuterWidth = holderWidth;1634 newOuterHeight = (holderWidth / imageWidth) * imageHeight;1635 }1636 else if(scaleMode == "heightOnly")1637 {1638 newOuterHeight = holderHeight;1639 newOuterWidth = (holderHeight / imageHeight) * imageWidth;1640 }1641 else if(scaleMode == "proportionalInside")1642 {1643 if(newOuterHeight <= holderHeight)1644 {1645 newOuterWidth = holderWidth;1646 }1647 else1648 {1649 newOuterHeight = holderHeight;1650 }1651 }1652 else if(scaleMode == "proportionalOutside")1653 {1654 if(newOuterHeight >= holderHeight)1655 {1656 newOuterWidth = holderWidth;1657 scale = holderWidth / newOuterWidth;1658 }1659 else1660 {1661 newOuterHeight = holderHeight;1662 scale = holderHeight / newOuterHeight;1663 }1664 }1665 else1666 {1667 newOuterWidth = imageWidth;1668 newOuterHeight = imageHeight;1669 }1670 1671 newOuterWidth = Math.ceil(newOuterWidth);1672 newOuterHeight = Math.ceil(newOuterHeight);1673 }1674 1675 TweenMax.set(pinchZoomerObj.outerDiv, {width:newOuterWidth, height:newOuterHeight });1676 pinchZoomer.resize();1677 }1678 }1679 }1680 1681 function onInput(e)1682 {1683 var index = e.data.index;1684 setActiveControls(index);1685 }1686 1687 function onFullScreenChange()1688 {1689 if(!screenfull.isFullscreen)1690 {1691 PinchZoomer.fullscreenDiv.detach();1692 1693 var pinchZoomerObj = PinchZoomer.objs[PinchZoomer.fullscreenIndex];1694 if(!pinchZoomerObj.removed)1695 {1696 if(PinchZoomer.fullscreenDiv.find(pinchZoomerObj.outerDiv).length == 1)1697 { 1698 pinchZoomerObj.vars.scaleMode = pinchZoomerObj.origScaleMode;1699 pinchZoomerObj.tempDiv.after(pinchZoomerObj.outerDiv);1700 pinchZoomerObj.tempDiv.detach();1701 1702 if(!PinchZoomer.fullscreenAllowed)1703 {1704 returnScroll();1705 }1706 1707 $(window).trigger("resize");1708 }1709 }1710 }1711 }1712 1713 function onFullScreenError()1714 {1715 //console.log("fullscreen error");1716 }1717 1718 function onFullscreenToggle(e)1719 {1720 var index = e.data.index,1721 pinchZoomerObj = PinchZoomer.objs[index],1722 isFullscreen = false;1723 1724 if(PinchZoomer.fullscreenAllowed)1725 {1726 isFullscreen = screenfull.isFullscreen;1727 }1728 else1729 {1730 isFullscreen = (PinchZoomer.fullscreenDiv.parent().length > 0);1731 }1732 1733 if(!isFullscreen)1734 {1735 pinchZoomerObj.vars.scaleMode = "full";1736 PinchZoomer.fullscreenIndex = index;1737 $("body").append(PinchZoomer.fullscreenDiv);1738 pinchZoomerObj.outerDiv.after(pinchZoomerObj.tempDiv);1739 PinchZoomer.fullscreenDiv.append(pinchZoomerObj.outerDiv);1740 1741 if(PinchZoomer.fullscreenAllowed)1742 {1743 screenfull.request(PinchZoomer.fullscreenDiv.get(0));1744 }1745 else1746 {1747 resetScroll();1748 }1749 triggerResize();1750 }1751 else1752 {1753 if(PinchZoomer.fullscreenAllowed)1754 {1755 screenfull.exit();1756 }1757 else1758 {1759 onFullScreenChange();1760 }1761 }1762 }1763 1764 function returnScroll()1765 {1766 window.scrollTo(PinchZoomer.curScrollLeft, PinchZoomer.curScrollTop); 1767 TweenMax.set($("body"), {overflow:PinchZoomer.curBodyOverflow});1768 }1769 1770 function resetScroll()1771 {1772 PinchZoomer.curScrollLeft = $("body").scrollLeft();1773 PinchZoomer.curScrollTop = $("body").scrollTop();1774 1775 if(PinchZoomer.curScrollLeft != 0 || PinchZoomer.curScrollTop != 0)1776 { 1777 window.scrollTo(0, 0);1778 }1779 1780 PinchZoomer.curBodyOverflow = $("body").css("overflow");1781 TweenMax.set($("body"), {overflow:"hidden"});1782 }1783 1784 function triggerResize()1785 {1786 $(window).trigger("resize");1787 }1788 1789 function onZoomIn(e)1790 {1791 1792 var index = e.data.index,1793 pinchZoomerObj = PinchZoomer.objs[index];1794 1795 if(!pinchZoomerObj.removed)1796 {1797 pinchZoomerObj.pinchZoomer.zoomIn();1798 setActiveControls(index);1799 }1800 }1801 1802 function onZoomOut(e)1803 {1804 var index = e.data.index,1805 pinchZoomerObj = PinchZoomer.objs[index];1806 1807 if(!pinchZoomerObj.removed)1808 {1809 pinchZoomerObj.pinchZoomer.zoomOut();1810 setActiveControls(index);1811 }1812 }1813 1814 function onImageZoom(index)1815 {1816 setActiveControls(index);1817 }1818 1819 function setZoomButtonState(index, forceCss)1820 {1821 forceCss = (forceCss === true);1822 1823 if(index >= 0 && index < PinchZoomer.objs.length)1824 {1825 var pinchZoomerObj = PinchZoomer.objs[index];1826 1827 if(!pinchZoomerObj.removed)1828 {1829 var pinchZoomer = pinchZoomerObj.pinchZoomer,1830 curZoom = pinchZoomer.zoom();1831 1832 if(curZoom == pinchZoomer.vars.minZoom)1833 {1834 if(pinchZoomerObj.oldZoomOutEnabled || forceCss)1835 {1836 TweenMax.set(pinchZoomerObj.zoomOutButton, pinchZoomerObj.zoomOutOffObj);1837 }1838 1839 pinchZoomerObj.oldZoomOutEnabled = false;1840 }1841 else1842 {1843 if(!pinchZoomerObj.oldZoomOutEnabled || forceCss)1844 {1845 TweenMax.set(pinchZoomerObj.zoomOutButton, pinchZoomerObj.zoomOutOnObj);1846 }1847 1848 pinchZoomerObj.oldZoomOutEnabled = true;1849 }1850 1851 if(curZoom == pinchZoomer.vars.maxZoom)1852 {1853 if(pinchZoomerObj.oldZoomInEnabled || forceCss)1854 {1855 TweenMax.set(pinchZoomerObj.zoomInButton, pinchZoomerObj.zoomInOffObj);1856 }1857 1858 pinchZoomerObj.oldZoomInEnabled = false;1859 }1860 else1861 {1862 if(!pinchZoomerObj.oldZoomInEnabled || forceCss)1863 {1864 TweenMax.set(pinchZoomerObj.zoomInButton, pinchZoomerObj.zoomInOnObj);1865 }1866 1867 pinchZoomerObj.oldZoomInEnabled = true;1868 }1869 1870 //TweenMax.set(pinchZoomerObj.fullscreenButton, pinchZoomerObj.fullscreenObj);1871 }1872 }1873 } 1874 1875 function setActiveControls(index)1876 {1877 for(var i = 0; i < PinchZoomer.objs.length; i++)1878 {1879 var pinchZoomerObj = PinchZoomer.objs[i];1880 if(!pinchZoomerObj.removed)1881 {1882 if(i == index)1883 {1884 if(!pinchZoomerObj.controlVisible)1885 {1886 if(!pinchZoomerObj.controlVars.alwaysShow)1887 {1888 TweenMax.set([pinchZoomerObj.zoomInButton, pinchZoomerObj.zoomOutButton, pinchZoomerObj.fullscreenButton], { visibility:"visible" });1889 }1890 }1891 1892 pinchZoomerObj.controlVisible = true;1893 1894 setZoomButtonState(i);1895 }1896 else1897 {1898 if(pinchZoomerObj.controlVisible || index == -1)1899 {1900 if(!pinchZoomerObj.controlVars.alwaysShow)1901 {1902 TweenMax.set([pinchZoomerObj.zoomInButton, pinchZoomerObj.zoomOutButton, pinchZoomerObj.fullscreenButton], { visibility:"hidden" });1903 }1904 }1905 1906 pinchZoomerObj.controlVisible = false;1907 }1908 }1909 }1910 }1911 }1912 1913}(window, jQuery));1914(function ($) 1915{1916 $.fn.pinchzoomer = function(_vars) 1917 {1918 PinchZoomer.init(this, _vars);1919 };1920 1921}(jQuery));1922(function($)1923{1924 function onReady()1925 {1926 PinchZoomer.init();1927 }1928 1929 $(onReady);1930 ...
touch-input.js
Source:touch-input.js
1var TouchInput = pc.createScript('touchInput');2TouchInput.MASK_VALUE = 2;3TouchInput.attributes.add('orbitSensitivity', {4 type: 'number',5 default: 0.4,6 title: 'Orbit Sensitivity',7 description: 'How fast the camera moves around the orbit. Higher is faster'8});9TouchInput.attributes.add('distanceSensitivity', {10 type: 'number',11 default: 0.2,12 title: 'Distance Sensitivity',13 description: 'How fast the camera moves in and out. Higher is faster'14});15TouchInput.attributes.add('panEnabled', {16 type: 'boolean',17 default: true,18 title: 'Panning Allowed',19 description: 'Is panning allowed via 2-touches and drag?'20});21TouchInput.attributes.add('yawOrientedPan', {22 type: 'boolean',23 enum: [24 { 'None': false },25 { '(x,z) Top': true },26 ],27 title: "Pan Plane 2D",28 description: "Pan along camera yaw oriented 2D plane?",29 default: false30});31TouchInput.attributes.add('reverseControlScheme', {32 type: 'boolean',33 default: false,34 title: 'Reverse Control Scheme'35});36TouchInput.attributes.add('domId', {37 type: 'string'38});39TouchInput.hackedTouch = false;40// initialize code called once per entity41TouchInput.prototype.initialize = function() {42 this.orbitCamera = this.entity.script.orbitCamera;43 this.fromWorldPoint = new pc.Vec3();44 this.toWorldPoint = new pc.Vec3();45 this.worldDiff = new pc.Vec3();46 this.calcMatrix = new pc.Mat4();47 this.dualTouched = false;48 // Store the position of the touch so we can calculate the distance moved49 this.lastTouchPoint = new pc.Vec2();50 this.lastPinchMidPoint = new pc.Vec2();51 this.lastPinchDistanceX = 0;52 this.lastPinchDistanceY = 0;53 this.lastPinchDistance = 0;54 //this.lastAxial = new pc.Vec2();55 //this.curAxial = new pc.Vec2();56 this.lastRotation = 0;57 this.touchDevice = this.app.touch;58 this.originalDistanceSensitivity = this.distanceSensitivity;59 // NOTE: this is a hack, assume fullscreen yea...so it's simplified60 if (!TouchInput.hackTouched) {61 pc.getTouchTargetCoords = function (touch) {62 return {63 x: touch.pageX,64 y: touch.pageY65 };66 };67 TouchInput.hackTouched = true;68 }69};70TouchInput.prototype.postInitialize = function() {71 if (this.orbitCamera && this.app.touch) {72 if (this.domId) {73 var elem = document.getElementById(this.domId);74 if (elem) {75 this.touchDevice = new pc.TouchDevice(elem);76 console.log("Switching to element id for touch:"+this.domId);77 }78 else {79 console.warn("could not find document by element id:"+this.domId);80 }81 }82 // Use the same callback for the touchStart, touchEnd and touchCancel events as they83 // all do the same thing which is to deal the possible multiple touches to the screen84 this.initListeners();85 this.on("enable", function() {86 this.initListeners();87 }, this);88 this.on("disable", function() {89 this.disableListeners();90 }, this);91 this.on('destroy', function() {92 this.disableListeners();93 }, this);94 }95};96TouchInput.prototype.initListeners = function() {97 this.touchDevice.on(pc.EVENT_TOUCHSTART, this.onTouchStartEndCancel, this);98 this.touchDevice.on(pc.EVENT_TOUCHEND, this.onTouchStartEndCancel, this);99 this.touchDevice.on(pc.EVENT_TOUCHCANCEL, this.onTouchStartEndCancel, this);100 this.touchDevice.on(pc.EVENT_TOUCHMOVE, this.onTouchMove, this);101};102TouchInput.prototype.disableListeners = function() {103 this.touchDevice.off(pc.EVENT_TOUCHSTART, this.onTouchStartEndCancel, this);104 this.touchDevice.off(pc.EVENT_TOUCHEND, this.onTouchStartEndCancel, this);105 this.touchDevice.off(pc.EVENT_TOUCHCANCEL, this.onTouchStartEndCancel, this);106 this.touchDevice.off(pc.EVENT_TOUCHMOVE, this.onTouchMove, this);107};108TouchInput.prototype.getPinchDistance = function (pointA, pointB) {109 // Return the distance between the two points110 var dx = pointA.x - pointB.x;111 var dy = pointA.y - pointB.y;112 return Math.sqrt((dx * dx) + (dy * dy));113};114TouchInput.prototype.getPinchDistanceX = function (pointA, pointB) {115 // Return the distance between the two points116 return Math.abs(pointA.x - pointB.x);117};118TouchInput.prototype.getPinchDistanceY = function (pointA, pointB) {119 // Return the distance between the two points120 return Math.abs(pointB.y - pointA.y);121};122TouchInput.prototype.calcMidPoint = function (pointA, pointB, result) {123 result.set(pointB.x - pointA.x, pointB.y - pointA.y);124 result.scale(0.5);125 result.x += pointA.x;126 result.y += pointA.y;127};128TouchInput.prototype.onTouchStartEndCancel = function(event) {129 // We only care about the first touch for camera rotation. As the user touches the screen,130 // we stored the current touch position131 var touches = event.touches;132 var wasDualTouched = this.dualTouched;133 this.dualTouched = false;134 if (touches.length === 1) {135 this.lastTouchPoint.set(touches[0].x, touches[0].y);136 this.lastPinchMidPoint.set(touches[0].x, touches[0].y);137 } else if (touches.length === 2) {138 this.dualTouched = true;139 wasDualTouched = true;140 // If there are 2 touches on the screen, then set the pinch distance141 /*142 this.lastPinchDistanceX = this.getPinchDistanceX(touches[0], touches[1]);143 this.lastPinchDistanceY = this.getPinchDistanceY(touches[0], touches[1]);144 this.lastPinchDistance = Math.sqrt(this.lastPinchDistanceX*this.lastPinchDistanceX + this.lastPinchDistanceY*this.lastPinchDistanceY);145 */146 this.lastPinchDistance = this.getPinchDistance(touches[0], touches[1]);147 this.calcMidPoint(touches[0], touches[1], this.lastPinchMidPoint);148 this.lastTouchPoint.set(touches[0].x, touches[0].y);149 // this.lastAxial.x = touches[0].x - this.lastPinchMidPoint.x;150 // this.lastAxial.y = touches[0].y - this.lastPinchMidPoint.y;151 // this.lastAxial.normalize();152 this.lastRotation = Math.atan2(touches[0].y - this.lastPinchMidPoint.y, touches[0].x - this.lastPinchMidPoint.x);153 }154 if (event.event.type === pc.EVENT_TOUCHSTART ) {155 this.orbitCamera.inputDetectMask |= TouchInput.MASK_VALUE;156 if (wasDualTouched) {157 this.orbitCamera.fire("panRelease");158 }159 }160 else {161 this.orbitCamera.inputDetectMask &= ~TouchInput.MASK_VALUE;162 if (wasDualTouched) {163 this.orbitCamera.fire("panRelease");164 }165 }166};167TouchInput.prototype.pan = function(midPoint) {168 var fromWorldPoint = this.fromWorldPoint;169 var toWorldPoint = this.toWorldPoint;170 var worldDiff = this.worldDiff;171 // For panning to work at any zoom level, we use screen point to world projection172 // to work out how far we need to pan the pivotEntity in world space173 var camera = this.entity.camera;174 var distance = this.orbitCamera.distance;175 if (!this.yawOrientedPan) {176 camera.screenToWorld(midPoint.x, midPoint.y, distance, fromWorldPoint);177 camera.screenToWorld(this.lastPinchMidPoint.x, this.lastPinchMidPoint.y, distance, toWorldPoint);178 worldDiff.sub2(toWorldPoint, fromWorldPoint);179 }180 else {181 if (this.entity.camera.myFakeOrtho) this.entity.camera.data.camera._projection = pc.PROJECTION_ORTHOGRAPHIC;182 camera.screenToWorld(midPoint.x, midPoint.y, distance, fromWorldPoint);183 camera.screenToWorld(this.lastPinchMidPoint.x, this.lastPinchMidPoint.y, distance, toWorldPoint);184 worldDiff.sub2(toWorldPoint, fromWorldPoint);185 if (this.entity.camera.myFakeOrtho) this.entity.camera.data.camera._projection = pc.PROJECTION_PERSPECTIVE;186 ///*187 if (!this.entity.camera.myFakeOrtho && this.entity.camera.projection === pc.PROJECTION_PERSPECTIVE) {188 var scale = worldDiff.length();189 var dx = this.lastPinchMidPoint.x - midPoint.x;190 var dy = this.lastPinchMidPoint.y - midPoint.y;191 var d = dx*dx+dy*dy;192 if (d === 0 ) return;193 d = Math.sqrt(d);194 d = 1/d;195 dx *=d;196 dy *=d;197 dx *= scale;198 dy *= scale;199 worldDiff.x = dx;200 worldDiff.y = 0;201 worldDiff.z = dy;202 this.calcMatrix.setFromEulerAngles(0, this.orbitCamera._targetYaw, 0);203 this.calcMatrix.transformVector(worldDiff, worldDiff);204 }205 }206 this.orbitCamera.panByAmount(worldDiff);207};208TouchInput.pinchMidPoint = new pc.Vec2();209TouchInput.prototype.onTouchMove = function(event) {210 var pinchMidPoint = TouchInput.pinchMidPoint;211 // We only care about the first touch for camera rotation. Work out the difference moved since the last event212 // and use that to update the camera target position213 var touches = event.touches;214 this.dualTouched = false;215 if ( touches.length === 1 ) {216 var touch = touches[0];217 if (!this.reverseControlScheme) {218 this.orbitCamera.pitch -= (touch.y - this.lastTouchPoint.y) * this.orbitSensitivity;219 this.orbitCamera.yaw -= (touch.x - this.lastTouchPoint.x) * this.orbitSensitivity;220 }221 else {222 pinchMidPoint.x = touch.x;223 pinchMidPoint.y = touch.y;224 this.pan(pinchMidPoint);225 }226 this.lastPinchMidPoint.set(touch.x, touch.y);227 this.lastTouchPoint.set(touch.x, touch.y);228 } else if ( touches.length === 2 ) {229 this.dualTouched = true;230 // Calculate the difference in pinch distance since the last event231 //var currentPinchDistanceX = this.getPinchDistanceX(touches[0], touches[1]);232 //var currentPinchDistanceY = this.getPinchDistanceY(touches[0], touches[1]);233 var currentPinchDistance = this.getPinchDistance(touches[0], touches[1]);//Math.sqrt(currentPinchDistanceX*currentPinchDistanceX + currentPinchDistanceY*currentPinchDistanceY);234 //var diffInPinchDistanceX = currentPinchDistanceX - this.lastPinchDistanceX;235 //var diffInPinchDistanceY = currentPinchDistanceY - this.lastPinchDistanceY;236 var diffInPinchDistance = currentPinchDistance - this.lastPinchDistance;237 // this.lastPinchDistanceX = currentPinchDistanceX;238 // this.lastPinchDistanceY = currentPinchDistanceY;239 this.lastPinchDistance = currentPinchDistance;240 if (!this.entity.camera.myFakeOrtho && this.entity.camera.projection === pc.PROJECTION_PERSPECTIVE) {241 if (!this.orbitCamera.fovZooming) {242 this.orbitCamera.distance -= (diffInPinchDistance * this.distanceSensitivity * 0.1) * (this.orbitCamera.distance * 0.1);243 }244 else {245 var curFOV = this.entity.camera.fov;246 var fov;247 fov = curFOV - diffInPinchDistance * this.distanceSensitivity * 0.1;248 if (fov < this.orbitCamera.minFOV) fov = this.orbitCamera.minFOV;249 if (fov > this.orbitCamera.maxFOV) fov = this.orbitCamera.maxFOV;250 this.entity.camera.fov = fov;251 if (this.entity.originalCameraFOV) {252 var fovVal = this.entity.camera.fov * pc.math.DEG_TO_RAD * 0.5;253 var fovVal2 = this.entity.originalCameraFOV * pc.math.DEG_TO_RAD * 0.5;254 //r focalLength = 1 / Math.tan(fovVal);255 var relativeRatio = Math.tan(fovVal) / Math.tan(fovVal2);256 this.distanceSensitivity = this.originalDistanceSensitivity * relativeRatio;257 }258 }259 }260 else if (this.orbitCamera.allowOrthoZoom) {261 this.orbitCamera.orthoDistance -= (diffInPinchDistance * this.distanceSensitivity * 0.1) * (this.orbitCamera.orthoDistance * 0.1);262 this.orbitCamera.fire("orthoHeightChange");263 }264 // Calculate pan difference265 this.calcMidPoint(touches[0], touches[1], pinchMidPoint);266 if (!this.reverseControlScheme) {267 if (this.panEnabled) {268 this.pan(pinchMidPoint);269 }270 }271 else {272 this.orbitCamera.pitch -= (pinchMidPoint.y - this.lastPinchMidPoint.y) * this.orbitSensitivity;273 // todo: this rotate yaw needs to be tested.274 // this.curAxial.x = touches[0].x - this.pinchMidPoint.x;275 // this.curAxial.y = touches[0].y - this.pinchMidPoint.y;276 //this.curAxial.normalize();277 var curRotation = Math.atan2(touches[0].y - pinchMidPoint.y, touches[0].x - pinchMidPoint.x);278 this.orbitCamera.yaw += (curRotation - this.lastRotation) * pc.math.RAD_TO_DEG;279 //Math.acos(this.curAxial.x*this.lastAxial.x + this.curAxial.y*this.lastAxial.y) * pc.math.RAD_TO_DEG;280 //(pinchMidPoint.x - this.lastPinchMidPoint.x) * this.orbitSensitivity;281 this.lastRotation = curRotation;282 }283 //this.lastAxial.x = touches[0].x - this.lastPinchMidPoint.x;284 // this.lastAxial.y = touches[0].y - this.lastPinchMidPoint.y;285 this.lastPinchMidPoint.copy(pinchMidPoint);286 }287};...
PinchRecognizer.js
Source:PinchRecognizer.js
1/*2 * Copyright 2003-2006, 2009, 2017, United States Government, as represented by the Administrator of the3 * National Aeronautics and Space Administration. All rights reserved.4 *5 * The NASAWorldWind/WebWorldWind platform is licensed under the Apache License, Version 2.0 (the "License");6 * you may not use this file except in compliance with the License.7 * You may obtain a copy of the License at8 *9 * http://www.apache.org/licenses/LICENSE-2.010 *11 * Unless required by applicable law or agreed to in writing, software12 * distributed under the License is distributed on an "AS IS" BASIS,13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14 * See the License for the specific language governing permissions and15 * limitations under the License.16 */17/**18 * @exports PinchRecognizer19 */20define(['../gesture/GestureRecognizer'],21 function (GestureRecognizer) {22 "use strict";23 /**24 * Constructs a pinch gesture recognizer.25 * @alias PinchRecognizer26 * @constructor27 * @augments GestureRecognizer28 * @classdesc A concrete gesture recognizer subclass that looks for two finger pinch gestures.29 * @param {EventTarget} target The document element this gesture recognizer observes for mouse and touch events.30 * @param {Function} callback An optional function to call when this gesture is recognized. If non-null, the31 * function is called when this gesture is recognized, and is passed a single argument: this gesture recognizer,32 * e.g., <code>gestureCallback(recognizer)</code>.33 * @throws {ArgumentError} If the specified target is null or undefined.34 */35 var PinchRecognizer = function (target, callback) {36 GestureRecognizer.call(this, target, callback);37 // Intentionally not documented.38 this._scale = 1;39 // Intentionally not documented.40 this._offsetScale = 1;41 // Intentionally not documented.42 this.referenceDistance = 0;43 // Intentionally not documented.44 this.interpretThreshold = 20;45 // Intentionally not documented.46 this.weight = 0.4;47 // Intentionally not documented.48 this.pinchTouches = [];49 };50 PinchRecognizer.prototype = Object.create(GestureRecognizer.prototype);51 Object.defineProperties(PinchRecognizer.prototype, {52 scale: {53 get: function () {54 return this._scale * this._offsetScale;55 }56 }57 });58 // Documented in superclass.59 PinchRecognizer.prototype.reset = function () {60 GestureRecognizer.prototype.reset.call(this);61 this._scale = 1;62 this._offsetScale = 1;63 this.referenceDistance = 0;64 this.pinchTouches = [];65 };66 // Documented in superclass.67 PinchRecognizer.prototype.mouseDown = function (event) {68 if (this.state == WorldWind.POSSIBLE) {69 this.state = WorldWind.FAILED; // touch gestures fail upon receiving a mouse event70 }71 };72 // Documented in superclass.73 PinchRecognizer.prototype.touchStart = function (touch) {74 if (this.pinchTouches.length < 2) {75 if (this.pinchTouches.push(touch) == 2) {76 this.referenceDistance = this.currentPinchDistance();77 this._offsetScale *= this._scale;78 this._scale = 1;79 }80 }81 };82 // Documented in superclass.83 PinchRecognizer.prototype.touchMove = function (touch) {84 if (this.pinchTouches.length == 2) {85 if (this.state == WorldWind.POSSIBLE) {86 if (this.shouldRecognize()) {87 this.state = WorldWind.BEGAN;88 }89 } else if (this.state == WorldWind.BEGAN || this.state == WorldWind.CHANGED) {90 var distance = this.currentPinchDistance(),91 newScale = Math.abs(distance / this.referenceDistance),92 w = this.weight;93 this._scale = this._scale * (1 - w) + newScale * w;94 this.state = WorldWind.CHANGED;95 }96 }97 };98 // Documented in superclass.99 PinchRecognizer.prototype.touchEnd = function (touch) {100 var index = this.pinchTouches.indexOf(touch);101 if (index != -1) {102 this.pinchTouches.splice(index, 1);103 }104 // Transition to the ended state if this was the last touch.105 if (this.touchCount == 0) { // last touch ended106 if (this.state == WorldWind.POSSIBLE) {107 this.state = WorldWind.FAILED;108 } else if (this.state == WorldWind.BEGAN || this.state == WorldWind.CHANGED) {109 this.state = WorldWind.ENDED;110 }111 }112 };113 // Documented in superclass.114 PinchRecognizer.prototype.touchCancel = function (touch) {115 var index = this.pinchTouches.indexOf(touch);116 if (index != -1) {117 this.pinchTouches.splice(index, 1);118 }119 // Transition to the cancelled state if this was the last touch.120 if (this.touchCount == 0) {121 if (this.state == WorldWind.POSSIBLE) {122 this.state = WorldWind.FAILED;123 } else if (this.state == WorldWind.BEGAN || this.state == WorldWind.CHANGED) {124 this.state = WorldWind.CANCELLED;125 }126 }127 };128 // Documented in superclass.129 PinchRecognizer.prototype.prepareToRecognize = function () {130 this.referenceDistance = this.currentPinchDistance();131 this._scale = 1;132 };133 // Intentionally not documented.134 PinchRecognizer.prototype.shouldRecognize = function () {135 var distance = this.currentPinchDistance();136 return Math.abs(distance - this.referenceDistance) > this.interpretThreshold137 };138 // Intentionally not documented.139 PinchRecognizer.prototype.currentPinchDistance = function () {140 var touch0 = this.pinchTouches[0],141 touch1 = this.pinchTouches[1],142 dx = touch0.clientX - touch1.clientX,143 dy = touch0.clientY - touch1.clientY;144 return Math.sqrt(dx * dx + dy * dy);145 };146 return PinchRecognizer;...
pinchers.js
Source:pinchers.js
1export default {2 models: 'hands',3 enabled: true,4 tags: ['core'],5 // Index of fingertips6 fingertipIndex: [8, 12, 16, 20],7 // Number of frames the current element is the same as the last8 // [left, right]9 // [index, middle, ring, pinky]10 numFramesFocused: [[0, 0, 0, 0,], [0, 0, 0, 0]],11 // Whether the fingers are touching12 thresholdMet: [[0, 0, 0, 0,], [0, 0, 0, 0]],13 framesSinceLastGrab: [[0, 0, 0, 0,], [0, 0, 0, 0]],14 // The original grab point for each finger15 origPinch: [16 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}],17 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}]18 ],19 curPinch: [20 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}],21 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}]22 ],23 // Just downel24 pinchDowned: [25 [0, 0, 0, 0],26 [0, 0, 0, 0]27 ],28 pinchDown: [29 [false, false, false, false],30 [false, false, false, false]31 ],32 pinchUp: [33 [false, false, false, false],34 [false, false, false, false]35 ],36 // The tweened scrollTop, used to smoothen out scroll37 // [[leftHand], [rightHand]]38 tween: [39 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}],40 [{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}]41 ],42 // Number of frames that has passed since the last grab43 numFramesFocused: [[0, 0, 0, 0,], [0, 0, 0, 0]],44 // Number of frames mouse has been downed45 mouseDowned: 0,46 // Is the mouse up?47 mouseUp: false,48 // Whether one of the morph confidences have been met49 mouseThresholdMet: false,50 config: {51 // Number of frames over the same element before activating that element52 framesToFocus: 10,53 // Number of pixels the middle and thumb tips must be near each other to drag54 threshold: 50,55 // Number of frames where a hold is not registered before releasing a drag56 numThresholdErrorFrames: 5,57 maxMouseDownedFrames: 158 },59 onUse () {60 this.$target = window61 },62 /**63 * Scroll the page when the cursor goes above/below the threshold64 */65 onFrame ({hands}) {66 if (!hands.multiHandLandmarks) return67 const height = this.handsfree.debug.$canvas.hands.height68 const leftVisible = hands.multiHandedness.some(hand => hand.label === 'Right')69 const rightVisible = hands.multiHandedness.some(hand => hand.label === 'Left')70 71 // Detect if the threshold for clicking is met with specific morphs72 for (let n = 0; n < hands.multiHandLandmarks.length; n++) {73 // Set the hand index74 let hand = hands.multiHandedness[n].label === 'Right' ? 0 : 175 76 for (let finger = 0; finger < 4; finger++) {77 // Check if fingers are touching78 const a = hands.multiHandLandmarks[n][4].x - hands.multiHandLandmarks[n][this.fingertipIndex[finger]].x79 const b = hands.multiHandLandmarks[n][4].y - hands.multiHandLandmarks[n][this.fingertipIndex[finger]].y80 const c = Math.sqrt(a*a + b*b) * height81 const thresholdMet = this.thresholdMet[hand][finger] = c < this.config.threshold82 if (thresholdMet) {83 // Set the current pinch84 this.curPinch[hand][finger] = hands.multiHandLandmarks[n][4]85 86 // Store the original pinch87 if (this.framesSinceLastGrab[hand][finger] > this.config.numThresholdErrorFrames) {88 this.origPinch[hand][finger] = hands.multiHandLandmarks[n][4]89 this.handsfree.TweenMax.killTweensOf(this.tween[hand][finger])90 }91 this.framesSinceLastGrab[hand][finger] = 092 }93 ++this.framesSinceLastGrab[hand][finger]94 }95 }96 // Update the hands object97 hands.origPinch = this.origPinch98 hands.curPinch = this.curPinch99 this.handsfree.data.hands = this.getPinchStates(hands, leftVisible, rightVisible)100 },101 /**102 * Check if we are "mouse clicking"103 */104 getPinchStates (hands, leftVisible, rightVisible) {105 const visible = [leftVisible, rightVisible]106 // Make sure states are available107 hands.pinchState = [108 ['', '', '', ''],109 ['', '', '', '']110 ]111 112 // Loop through every hand and finger113 for (let hand = 0; hand < 2; hand++) {114 for (let finger = 0; finger < 4; finger++) {115 // Click116 if (visible[hand] && this.thresholdMet[hand][finger]) {117 this.pinchDowned[hand][finger]++118 document.body.classList.add(`handsfree-finger-pinched-${hand}-${finger}`, `handsfree-finger-pinched-${finger}`)119 } else {120 this.pinchUp[hand][finger] = this.pinchDowned[hand][finger]121 this.pinchDowned[hand][finger] = 0122 document.body.classList.remove(`handsfree-finger-pinched-${hand}-${finger}`, `handsfree-finger-pinched-${finger}`)123 }124 125 // Set the state126 if (this.pinchDowned[hand][finger] > 0 && this.pinchDowned[hand][finger] <= this.config.maxMouseDownedFrames) {127 hands.pinchState[hand][finger] = 'start'128 } else if (this.pinchDowned[hand][finger] > this.config.maxMouseDownedFrames) {129 hands.pinchState[hand][finger] = 'held'130 } else if (this.pinchUp[hand][finger]) {131 hands.pinchState[hand][finger] = 'released'132 } else {133 hands.pinchState[hand][finger] = ''134 }135 // Emit an event136 if (hands.pinchState[hand][finger]) {137 // Specific hand138 this.handsfree.emit(`finger-pinched-${hand}-${finger}`, {139 event: hands.pinchState[hand][finger],140 origPinch: hands.origPinch[hand][finger],141 curPinch: hands.curPinch[hand][finger]142 })143 this.handsfree.emit(`finger-pinched-${hands.pinchState[hand][finger]}-${hand}-${finger}`, {144 event: hands.pinchState[hand][finger],145 origPinch: hands.origPinch[hand][finger],146 curPinch: hands.curPinch[hand][finger]147 })148 // Any hand149 this.handsfree.emit(`finger-pinched-${finger}`, {150 event: hands.pinchState[hand][finger],151 origPinch: hands.origPinch[hand][finger],152 curPinch: hands.curPinch[hand][finger]153 })154 this.handsfree.emit(`finger-pinched-${hands.pinchState[hand][finger]}-${finger}`, {155 event: hands.pinchState[hand][finger],156 origPinch: hands.origPinch[hand][finger],157 curPinch: hands.curPinch[hand][finger]158 })159 }160 }161 }162 return hands163 }...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!