How to use pinch method in Appium

Best JavaScript code snippet using appium

jquery.pinchzoomer.js

Source:jquery.pinchzoomer.js Github

copy

Full Screen

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	...

Full Screen

Full Screen

touch-input.js

Source:touch-input.js Github

copy

Full Screen

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};...

Full Screen

Full Screen

PinchRecognizer.js

Source:PinchRecognizer.js Github

copy

Full Screen

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;...

Full Screen

Full Screen

pinchers.js

Source:pinchers.js Github

copy

Full Screen

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  }...

Full Screen

Full Screen

ThreeTouchControls.js

Source:ThreeTouchControls.js Github

copy

Full Screen

1/* @flow */2// React3import React, {4  Component5} from 'react';6// THREE7import * as THREE from 'three';8// constants9import { ZOOM_IN, ZOOM_OUT, PINCH_END, PINCH_START} from '../constants/application';10// ONLY SUPPORTS 2 FINGER PINCH11export default class ThreeTouchControls extends Component {12  state = {13    pinchDistanceFromCenter: 0,14    pinchVectors: new THREE.Vector2(),15  }16  touchControlRef: Object;17  width: number;18  height: number;19  baseClassName = 'three-touch-listener ';20  constructor(props: Object) {21    super(props);22    (this: any).handleTouch = this.handleTouch.bind(this);23    (this: any).handleTouchMove = this.handleTouchMove.bind(this);24    (this: any).handlePinch = this.handlePinch.bind(this);25    (this: any).handlePinchMove = this.handlePinchMove.bind(this);26    (this: any)._preparePinchCallback = this._preparePinchCallback.bind(this);27    (this: any)._preparePinchMoveCallback = this._preparePinchMoveCallback.bind(this);28    (this: any).pinchDistance = this.pinchDistance.bind(this);29    (this: any).normalizedPinchDistance = this.normalizedPinchDistance.bind(this);30    (this: any).pinchCenter = this.pinchCenter.bind(this);31    (this: any).distanceFromCenter = this.distanceFromCenter.bind(this);32    (this: any).setPinchVectors = this.setPinchVectors.bind(this);33    (this: any).toVec2Array = this.toVec2Array.bind(this);34  }35  componentDidMount(): void {36    this.width = this.touchControlRef.clientWidth;37    this.height = this.touchControlRef.clientHeight;38  }39  handleTouch(event: SyntheticEvent): void {40    let touches = event.nativeEvent.touches;41    event.preventDefault();42    event.stopPropagation();43    switch (event.type) {44      case 'touchstart':45        if (touches.length > 1) {46          this.handlePinch(touches, PINCH_START);47        } else {48          this.props.onTouchStartCallback(touches[0], event.type);49        }50        break;51      case 'touchend':52        this.props.onPinchEndCallback(touches, PINCH_END);53        this.props.onTouchEndCallback(touches, event.type);54        break;55      default:56        break;57    }58  }59  handleTouchMove(event: SyntheticEvent): void {60    event.preventDefault();61    event.stopPropagation();62    let touches = event.nativeEvent.touches;63    if (touches.length > 1) {64      this.handlePinchMove(touches);65    } else {66      this.props.onTouchMoveCallback(touches[0]);67    }68  }69  handlePinch(touches: TouchList, type: string): void {70    this.setPinchVectors(touches, this._preparePinchCallback);71  }72  _preparePinchCallback(vecs: Array<THREE.Vector2>, touches: TouchList): void {73    let distance = this.pinchDistance();74    let normalizedDistance = this.normalizedPinchDistance();75    let pinchCenter = this.pinchCenter();76    let distanceFromCenter = this.distanceFromCenter(vecs[0], vecs[1], pinchCenter);77    this.setState({78      pinchDistanceFromCenter: distanceFromCenter,79    }, () => {80      let pinchInfo = {81        distance: distance,82        normalizedDistance: normalizedDistance,83        clientCenter: pinchCenter,84        nativeTouches: touches,85      }86      this.props.onPinchStartCallback(pinchInfo, PINCH_START);87    });88  }89  handlePinchMove(touches: TouchList): void {90    this.setPinchVectors(touches, this._preparePinchMoveCallback);91  }92  _preparePinchMoveCallback(vecs: Array<THREE.Vector2>, touches: TouchList): void {93    let pinchDistance = this.pinchDistance();94    let normalizedDistance = this.normalizedPinchDistance();95    let pinchCenter = this.pinchCenter();96    let distanceFromCenter = this.distanceFromCenter(vecs[0], vecs[1], pinchCenter);97    let zoomAction = (distanceFromCenter > this.state.pinchDistanceFromCenter) ?98      ZOOM_OUT : ZOOM_IN;99    let pinchDelta = this.state.pinchDistanceFromCenter - distanceFromCenter;100    this.setState({101      pinchDistanceFromCenter: distanceFromCenter,102    }, () => {103      this.props.onPinchMoveCallback({104        distance: pinchDistance,105        normalizedDistance: normalizedDistance,106        pinchDelta: pinchDelta,107        clientCenter: this.pinchCenter(...touches),108        nativeTouches: touches,109        zoomAction: zoomAction,110      });111    });112  }113  // distance from touches in pixels114  pinchDistance(): number {115    let [vec1, vec2] = this.state.pinchVectors;116    return vec1.distanceTo(vec2);117  }118  // distance from touches in normalized screen coords119  normalizedPinchDistance(): number {120    let [vec1, vec2] = this.state.pinchVectors.map((vec) => {121      return new THREE.Vector2(vec.x / this.width, vec.y / this.height);122    });123    return vec1.distanceTo(vec2);124  }125  pinchCenter(): THREE.Vector2 {126    let [vec1, vec2] = this.state.pinchVectors;127    return vec1.add(vec2).divideScalar(2);128  }129  distanceFromCenter(vec1: THREE.Vector2, vec2: THREE.Vector2, center: THREE.Vector2): number {130    return Math.max(vec1.distanceTo(center), vec2.distanceTo(center));131  }132  setPinchVectors(touches: TouchList, callback: (vecs: Array<THREE.Vector2>, nativeTouches: TouchList) => void): void {133    this.setState({134      pinchVectors: this.toVec2Array(...touches),135    }, () => {136      if (callback) callback(this.state.pinchVectors, touches);137    });138  }139  toVec2Array(touch1: Touch, touch2: Touch): Array<THREE.Vector2> {140    return [141      new THREE.Vector2(touch1.clientX, touch2.clientY),142      new THREE.Vector2(touch2.clientX, touch2.clientY)143    ]144  }145  render() {146    const { className, children } = this.props;147    return(148      <span className={this.baseClassName += className ? className : ''}149        ref={(ref) => this.touchControlRef = ref}150        onTouchStart={this.handleTouch}151        onTouchEnd={this.handleTouch}152        onTouchMove={this.handleTouchMove}>153        {children}154      </span>155    );156  }...

Full Screen

Full Screen

PinchZoom.js

Source:PinchZoom.js Github

copy

Full Screen

1/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for2 * full list of contributors). Published under the 2-clause BSD license.3 * See license.txt in the OpenLayers distribution or repository for the4 * full text of the license. */5/**6 * @requires OpenLayers/Handler/Pinch.js7 */8/**9 * Class: OpenLayers.Control.PinchZoom10 *11 * Inherits:12 *  - <OpenLayers.Control>13 */14OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {15    /** 16     * Property: type17     * {OpenLayers.Control.TYPES}18     */19    type: OpenLayers.Control.TYPE_TOOL,20    /**21     * Property: pinchOrigin22     * {Object} Cached object representing the pinch start (in pixels).23     */24    pinchOrigin: null,    25    26    /**27     * Property: currentCenter28     * {Object} Cached object representing the latest pinch center (in pixels).29     */30    currentCenter: null,    31    /**32     * APIProperty: autoActivate33     * {Boolean} Activate the control when it is added to a map.  Default is34     *     true.35     */36    autoActivate: true,37    /**38     * APIProperty: preserveCenter39     * {Boolean} Set this to true if you don't want the map center to change40     *     while pinching. For example you may want to set preserveCenter to41     *     true when the user location is being watched and you want to preserve42     *     the user location at the center of the map even if he zooms in or43     *     out using pinch. This property's value can be changed any time on an44     *     existing instance. Default is false.45     */46    preserveCenter: false,47    48    /**49     * APIProperty: handlerOptions50     * {Object} Used to set non-default properties on the pinch handler51     */52    /**53     * Constructor: OpenLayers.Control.PinchZoom54     * Create a control for zooming with pinch gestures.  This works on devices55     *     with multi-touch support.56     *57     * Parameters:58     * options - {Object} An optional object whose properties will be set on59     *                    the control60     */61    initialize: function(options) {62        OpenLayers.Control.prototype.initialize.apply(this, arguments);63        this.handler = new OpenLayers.Handler.Pinch(this, {64            start: this.pinchStart,65            move: this.pinchMove,66            done: this.pinchDone67        }, this.handlerOptions);68    },69    70    /**71     * Method: pinchStart72     *73     * Parameters:74     * evt - {Event}75     * pinchData - {Object} pinch data object related to the current touchmove76     *     of the pinch gesture. This give us the current scale of the pinch.77     */78    pinchStart: function(evt, pinchData) {79        var xy = (this.preserveCenter) ?80            this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;81        this.pinchOrigin = xy;82        this.currentCenter = xy;83    },84    85    /**86     * Method: pinchMove87     *88     * Parameters:89     * evt - {Event}90     * pinchData - {Object} pinch data object related to the current touchmove91     *     of the pinch gesture. This give us the current scale of the pinch.92     */93    pinchMove: function(evt, pinchData) {94        var scale = pinchData.scale;95        var containerOrigin = this.map.layerContainerOriginPx;96        var pinchOrigin = this.pinchOrigin;97        var current = (this.preserveCenter) ?98            this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;99        var dx = Math.round((containerOrigin.x + current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));100        var dy = Math.round((containerOrigin.y + current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));101        this.map.applyTransform(dx, dy, scale);102        this.currentCenter = current;103    },104    /**105     * Method: pinchDone106     *107     * Parameters:108     * evt - {Event}109     * start - {Object} pinch data object related to the touchstart event that110     *     started the pinch gesture.111     * last - {Object} pinch data object related to the last touchmove event112     *     of the pinch gesture. This give us the final scale of the pinch.113     */114    pinchDone: function(evt, start, last) {115        this.map.applyTransform();116        var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);117        if (zoom !== this.map.getZoom() || !this.currentCenter.equals(this.pinchOrigin)) {118            var resolution = this.map.getResolutionForZoom(zoom);119            var location = this.map.getLonLatFromPixel(this.pinchOrigin);120            var zoomPixel = this.currentCenter;        121            var size = this.map.getSize();122            location.lon += resolution * ((size.w / 2) - zoomPixel.x);123            location.lat -= resolution * ((size.h / 2) - zoomPixel.y);124            // Force a reflow before calling setCenter. This is to work125            // around an issue occuring in iOS.126            //127            // See https://github.com/openlayers/openlayers/pull/351.128            //129            // Without a reflow setting the layer container div's top left130            // style properties to "0px" - as done in Map.moveTo when zoom131            // is changed - won't actually correctly reposition the layer132            // container div.133            //134            // Also, we need to use a statement that the Google Closure135            // compiler won't optimize away.136            this.map.div.clientWidth = this.map.div.clientWidth;137            this.map.setCenter(location, zoom);138        }139    },140    CLASS_NAME: "OpenLayers.Control.PinchZoom"...

Full Screen

Full Screen

pinch_test.js

Source:pinch_test.js Github

copy

Full Screen

1suite('lib/pinch', function() {2  'use strict';3  suiteSetup(function(done) {4    var self = this;5    requirejs([6      'lib/pinch'7    ], function(Pinch) {8      self.Pinch = Pinch;9      done();10    });11  });12  setup(function() {13    this.el = {14      addEventListener: sinon.spy(),15      removeEventListener: sinon.spy()16    };17    this.pinch = new this.Pinch(this.el);18    this.pinch.emit = sinon.spy();19  });20  suite('Pinch()', function() {21    test('Should attach to specified element', function() {22      assert.isTrue(this.el.addEventListener.called);23    });24  });25  suite('Pinch#attach()', function() {26    test('Should attach touchstart to specified element', function() {27      this.pinch.attach(this.el);28      assert.isTrue(this.el.addEventListener.calledWith('touchstart',29        this.pinch.onTouchStart));30    });31  });32  suite('Pinch#detach()', function() {33    test('Should detach touchstart from specified element', function() {34      this.pinch.detach(this.el);35      assert.isTrue(this.el.removeEventListener.calledWith('touchstart',36        this.pinch.onTouchStart));37    });38  });39  suite('Pinch#onTouchStart()', function() {40    setup(function() {41      this.pinch.isPinching = false;42    });43    test('Should NOT emit `started` for one touch', function() {44      this.pinch.onTouchStart({45        touches: [{}]46      });47      assert.isFalse(this.pinch.emit.calledWith('started'));48    });49    test('Should emit `started` for two touches', function() {50      this.pinch.onTouchStart({51        touches: [{}]52      });53      this.pinch.onTouchStart({54        touches: [{}, {}]55      });56      assert.isTrue(this.pinch.isPinching);57      assert.isTrue(this.pinch.emit.calledWith('started'));58    });59    test('Should remember last two touches for two touches', function() {60      var touchA = { identifier: 0 };61      var touchB = { identifier: 1 };62      this.pinch.onTouchStart({63        touches: [touchA, touchB]64      });65      assert.equal(this.pinch.lastTouchA, touchA);66      assert.equal(this.pinch.lastTouchB, touchB);67    });68  });69  suite('Pinch#onTouchMove()', function() {70    setup(function() {71      this.pinch.isPinching = false;72    });73    test('Should NOT emit `change` for one touch', function() {74      this.pinch.onTouchStart({75        touches: [{}]76      });77      this.pinch.onTouchMove({78        touches: [{}]79      });80      assert.isFalse(this.pinch.emit.calledWith('changed'));81    });82    test('Should emit `change` for two touches', function() {83      this.pinch.onTouchStart({84        touches: [{}]85      });86      this.pinch.onTouchStart({87        touches: [{}, {}]88      });89      this.pinch.onTouchMove({90        touches: [{}, {}]91      });92      assert.isTrue(this.pinch.emit.calledWith('changed'));93    });94    test('Should track touch "A" for two touches', function() {95      var touchA1 = { identifier: 0 };96      var touchA2 = { identifier: 0 };97      this.pinch.onTouchStart({98        touches: [touchA1, {}]99      });100      assert.equal(this.pinch.lastTouchA, touchA1);101      this.pinch.onTouchMove({102        touches: [touchA2, {}]103      });104      assert.equal(this.pinch.lastTouchA, touchA2);105    });106    test('Should track touch "B" for two touches', function() {107      var touchB1 = { identifier: 1 };108      var touchB2 = { identifier: 1 };109      this.pinch.onTouchStart({110        touches: [{}, touchB1]111      });112      assert.equal(this.pinch.lastTouchB, touchB1);113      this.pinch.onTouchMove({114        touches: [{}, touchB2]115      });116      assert.equal(this.pinch.lastTouchB, touchB2);117    });118    test('Should calculate delta for two touches', function() {119      var touchA1 = { identifier: 0, pageX: -1, pageY: -1 };120      var touchA2 = { identifier: 0, pageX: -2, pageY: -2 };121      var touchB1 = { identifier: 1, pageX:  1, pageY:  1 };122      var touchB2 = { identifier: 1, pageX:  2, pageY:  2 };123      this.pinch.onTouchStart({124        touches: [touchA1, touchB1]125      });126      this.pinch.onTouchMove({127        touches: [touchA2, touchB2]128      });129      assert.equal(this.pinch.emit.args[1][1].toFixed(4), '2.8284');130    });131  });132  suite('Pinch#onTouchEnd()', function() {133    setup(function() {134      this.pinch.isPinching = false;135    });136    test('Should NOT emit `ended` for one touch', function() {137      this.pinch.onTouchStart({138        touches: [{}]139      });140      this.pinch.onTouchEnd({141        touches: []142      });143      assert.isFalse(this.pinch.emit.calledWith('ended'));144    });145    test('Should emit `ended` for two touches', function() {146      this.pinch.onTouchStart({147        touches: [{}, {}]148      });149      this.pinch.onTouchEnd({150        touches: [{}]151      });152      assert.isFalse(this.pinch.isPinching);153      assert.isTrue(this.pinch.emit.calledWith('ended'));154    });155  });...

Full Screen

Full Screen

GestureMgr.js

Source:GestureMgr.js Github

copy

Full Screen

1/**2 * Only implements needed gestures for mobile.3 */4define(function(require) {5    'use strict';6    var eventUtil = require('./event');7    var GestureMgr = function () {8        /**9         * @private10         * @type {Array.<Object>}11         */12        this._track = [];13    };14    GestureMgr.prototype = {15        constructor: GestureMgr,16        recognize: function (event, target, root) {17            this._doTrack(event, target, root);18            return this._recognize(event);19        },20        clear: function () {21            this._track.length = 0;22            return this;23        },24        _doTrack: function (event, target, root) {25            var touches = event.touches;26            if (!touches) {27                return;28            }29            var trackItem = {30                points: [],31                touches: [],32                target: target,33                event: event34            };35            for (var i = 0, len = touches.length; i < len; i++) {36                var touch = touches[i];37                var pos = eventUtil.clientToLocal(root, touch);38                trackItem.points.push([pos.zrX, pos.zrY]);39                trackItem.touches.push(touch);40            }41            this._track.push(trackItem);42        },43        _recognize: function (event) {44            for (var eventName in recognizers) {45                if (recognizers.hasOwnProperty(eventName)) {46                    var gestureInfo = recognizers[eventName](this._track, event);47                    if (gestureInfo) {48                        return gestureInfo;49                    }50                }51            }52        }53    };54    function dist(pointPair) {55        var dx = pointPair[1][0] - pointPair[0][0];56        var dy = pointPair[1][1] - pointPair[0][1];57        return Math.sqrt(dx * dx + dy * dy);58    }59    function center(pointPair) {60        return [61            (pointPair[0][0] + pointPair[1][0]) / 2,62            (pointPair[0][1] + pointPair[1][1]) / 263        ];64    }65    var recognizers = {66        pinch: function (track, event) {67            var trackLen = track.length;68            if (!trackLen) {69                return;70            }71            var pinchEnd = (track[trackLen - 1] || {}).points;72            var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;73            if (pinchPre74                && pinchPre.length > 175                && pinchEnd76                && pinchEnd.length > 177            ) {78                var pinchScale = dist(pinchEnd) / dist(pinchPre);79                !isFinite(pinchScale) && (pinchScale = 1);80                event.pinchScale = pinchScale;81                var pinchCenter = center(pinchEnd);82                event.pinchX = pinchCenter[0];83                event.pinchY = pinchCenter[1];84                return {85                    type: 'pinch',86                    target: track[0].target,87                    event: event88                };89            }90        }91        // Only pinch currently.92    };93    return GestureMgr;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriverio = require('webdriverio');2var options = {3    desiredCapabilities: {4    }5};6    .remote(options)7    .init()8    .getTitle().then(function(title) {9        console.log('Title was: ' + title);10    })11    .end();12var webdriverio = require('webdriverio');13var options = {14    desiredCapabilities: {15    }16};17    .remote(options)18    .init()19    .getTitle().then(function(title) {20        console.log('Title was: ' + title);21    })22    .end();23var webdriverio = require('webdriverio');24var options = {25    desiredCapabilities: {26    }27};28    .remote(options)29    .init()30    .getTitle().then(function(title) {31        console.log('Title was: ' + title);32    })33    .end();34var webdriverio = require('webdriverio');35var options = {36    desiredCapabilities: {37    }38};39    .remote(options)40    .init()41    .getTitle().then(function(title) {42        console.log('Title was: ' + title);43    })44    .end();45var webdriverio = require('webdriverio');46var options = {47    desiredCapabilities: {48    }49};50    .remote(options)51    .init()52    .getTitle().then(function(title) {53        console.log('Title was: ' + title);54    })55    .end();56var webdriverio = require('webdriverio');57var options = {58    desiredCapabilities: {59    }60};61    .remote(options)62    .init()63    .getTitle().then(function(title) {64        console.log('Title was: ' + title

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriver = require('selenium-webdriver'),2    until = webdriver.until;3var driver = new webdriver.Builder()4    .forBrowser('chrome')5    .build();6driver.findElement(By.name('q')).sendKeys('webdriver');7driver.findElement(By.name('btnG')).click();8driver.wait(until.titleIs('webdriver - Google Search'), 1000);9driver.quit();10TouchAction action = new TouchAction(driver);11action.press(pinchPoint1).moveTo(pinchPoint2).release().perform();12action = TouchAction(driver)13action.press(pinchPoint1).moveTo(pinchPoint2).release().perform()14action = TouchAction.new(driver)15action.press(pinchPoint1).moveTo(pinchPoint2).release().perform()16TouchAction action = new TouchAction(driver);17action.Press(pinchPoint1).MoveTo(pinchPoint2).Release().Perform();18$actions = new WebDriverActions($driver);19$actions->press($pinchPoint1)->move($pinchPoint2)->release()->perform();20var actions = driver.actions({bridge: true});21  .press({x: 100, y: 200})22  .move({x: 100, y: 0})23  .release()24  .perform();

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriver = require('selenium-webdriver');2var By = webdriver.By;3var until = webdriver.until;4var driver = new webdriver.Builder()5  .forBrowser('chrome')6  .build();7driver.findElement(By.name('q')).sendKeys('webdriver');8driver.findElement(By.name('btnG')).click();9driver.wait(until.titleIs('webdriver - Google Search'), 1000);10driver.quit();11driver.quit()12driver.quit()13driver.quit()14driver.quit()15driver.quit()

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriver = require('selenium-webdriver');2var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();3driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');4driver.findElement(webdriver.By.name('btnG')).click();5driver.sleep(2000).then(function() {6driver.actions().mouseMove(driver.findElement(webdriver.By.name('btnG'))).mouseDown().mouseMove({x: 0, y: 100}).mouseUp().perform();7});8driver.sleep(2000).then(function() {9driver.quit();10});

Full Screen

Using AI Code Generation

copy

Full Screen

1driver.pinch(element);2driver.zoom(element);3driver.swipe(100, 100, 200, 200, 1000);4driver.scroll(element, 100, 100);5driver.tap(1, element, 100, 100);6driver.tap(1, 100, 100, 1000);7driver.doubleTap(element);8driver.doubleTap(100, 100, 1000);9driver.touchLongClick(element);10driver.touchLongClick(100, 100, 1000);11driver.touchAndHold(100, 100, 1000);12driver.touchAndHold(element, 1000);13driver.touchDown(100, 100);14driver.touchDown(element);15driver.touchUp(100, 100);16driver.touchUp(element);17driver.touchMove(100, 100);18driver.touchMove(element);19driver.touchScroll(100, 100);20driver.touchScroll(element, 100, 100);21driver.dragAndDrop(element, element);22driver.dragAndDrop(100, 100, 100, 100);23driver.hideKeyboard();24driver.hideKeyboard("Done");25driver.hideKeyboard("Done", "search");

Full Screen

Using AI Code Generation

copy

Full Screen

1driver.pinch(element, 100, 100, 100, 1000);2driver.zoom(element, 100, 100, 100, 1000);3driver.swipe(100, 100, 100, 100, 1000);4driver.tap(1, element, 100, 100);5driver.doubleTap(element, 100, 100);6driver.longPress(element, 100, 100, 1000);7driver.touchDown(element, 100, 100);8driver.touchUp(element, 100, 100);9driver.touchMove(element, 100, 100);10driver.touchScroll(element, 100, 100);11driver.touchLongClick(element, 100, 100, 1000);12driver.touchFlick(element, 100, 100, 100, 1000);13driver.execute('mobile: scroll', {direction: 'down'});14driver.execute('mobile: scroll', {direction: 'up'});15driver.execute('mobile: scroll', {direction: 'left'});16driver.execute('mobile: scroll', {direction: 'right'});17driver.execute('mobile:

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful