/** * jGestures: a jQuery plugin for gesture events * Copyright 2010, Neue Digitale / Razorfish GmbH * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This is still a beta version, bugfixes and improvements appreciated. * @copyright Neue Digitale / Razorfish GmbH * @author martin.krause@neue-digitale.de * @version 0.87 * * @requires * jQuery JavaScript Library v1.4.2 - http://jquery.com/ * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ (function(b){b.jGestures={};b.jGestures.defaults={};b.jGestures.defaults.thresholdPinchopen=0.05;b.jGestures.defaults.thresholdPinchmove=0.05;b.jGestures.defaults.thresholdPinch=0.05;b.jGestures.defaults.thresholdPinchclose=0.05;b.jGestures.defaults.thresholdRotatecw=5;b.jGestures.defaults.thresholdRotateccw=5;b.jGestures.defaults.thresholdMove=20;b.jGestures.defaults.thresholdSwipe=100;b.jGestures.data={};b.jGestures.data.capableDevicesInUserAgentString=["iPad","iPhone","iPod","Mobile Safari"];b.jGestures.data.hasGestures=(function(){var j;for(j=0;j0)?+1:((m[0].lastX<0)?-1:0)),lastY:((m[0].lastY>0)?+1:((m[0].lastY<0)?-1:0)),startX:((m[0].startX>0)?+1:((m[0].startX<0)?-1:0)),startY:((m[0].startY>0)?+1:((m[0].startY<0)?-1:0))};m[0].moved=Math.sqrt(Math.pow(Math.abs(m[0].startX),2)+Math.pow(Math.abs(m[0].startY),2))}return{type:j.type||null,originalEvent:j.event||null,delta:m||null,direction:l||{orientation:window.orientation||null,vector:j.vector||null},duration:(j.startMove.timestamp)?k-j.timestamp:null,rotation:j.rotation||null,scale:j.scale||null,description:j.description||[j.type,":",j.touches,":",((m[0].lastX!=0)?((m[0].lastX>0)?"right":"left"):"steady"),":",((m[0].lastY!=0)?((m[0].lastY>0)?"down":"up"):"steady")].join("")}}function a(k){var j=["landscape:clockwise:","portrait:default:","landscape:counterclockwise:","portrait:upsidedown:"];b(window).triggerHandler("orientationchange",{direction:{orientation:window.orientation},description:["orientationchange:",j[((window.orientation/90)+1)],window.orientation].join("")})}function g(k){var j=jQuery(k.currentTarget);j.triggerHandler(b.jGestures.events.touchstart,k);if(b.hasGestures){k.currentTarget.addEventListener("touchmove",f,false);k.currentTarget.addEventListener("touchend",i,false)}else{j.bind("mousemove",f);j.bind("mouseup",i)}var m=j.data("ojQueryGestures");var l=(k.touches)?k.touches[0]:k;var n={};n.oLastSwipemove={screenX:l.screenX,screenY:l.screenY,timestamp:new Date().getTime()};n.oStartTouch={screenX:l.screenX,screenY:l.screenY,timestamp:new Date().getTime()};j.data("ojQueryGestures",b.extend(true,m,n))}function f(s){var u=jQuery(s.currentTarget);var r=u.data("ojQueryGestures");var p=!!s.touches;var k=(p)?s.changedTouches[0].screenX:s.screenX;var j=(p)?s.changedTouches[0].screenY:s.screenY;var q=r.oLastSwipemove;var n=k-q.screenX;var m=j-q.screenY;if(!!r.oLastSwipemove){var t=c({type:"swipemove",touches:(p)?s.touches.length:"1",screenY:j,screenX:k,deltaY:m,deltaX:n,startMove:q,event:s,timestamp:q.timestamp});u.triggerHandler(t.type,t)}var l={};var o=(s.touches)?s.touches[0]:s;l.oLastSwipemove={screenX:o.screenX,screenY:o.screenY,timestamp:new Date().getTime()};u.data("ojQueryGestures",b.extend(true,r,l))}function i(q){var u=jQuery(q.currentTarget);var w=!!q.changedTouches;var t=(w)?q.changedTouches.length:"1";var o=(w)?q.changedTouches[0].screenX:q.screenX;var n=(w)?q.changedTouches[0].screenY:q.screenY;u.triggerHandler(b.jGestures.events.touchendStart,q);if(b.hasGestures){q.currentTarget.removeEventListener("touchmove",f,false);q.currentTarget.removeEventListener("touchend",i,false)}else{u.unbind("mousemove",f);u.unbind("mouseup",i)}var l=u.data("ojQueryGestures");var x=(Math.abs(l.oStartTouch.screenX-o)>b.jGestures.defaults.thresholdMove||Math.abs(l.oStartTouch.screenY-n)>b.jGestures.defaults.thresholdMove)?true:false;var A=(Math.abs(l.oStartTouch.screenX-o)>b.jGestures.defaults.thresholdSwipe||Math.abs(l.oStartTouch.screenY-n)>b.jGestures.defaults.thresholdSwipe)?true:false;var z;for(z in l){var s=l.oStartTouch;var m={};var o=(w)?q.changedTouches[0].screenX:q.screenX;var n=(w)?q.changedTouches[0].screenY:q.screenY;var k=o-s.screenX;var j=n-s.screenY;var p=c({type:"swipe",touches:t,screenY:n,screenX:o,deltaY:j,deltaX:k,startMove:s,event:q,timestamp:s.timestamp});var v=["zero","one","two","three","four"];var r=false;switch(z){case"swipeone":if(w===false&&t==1&&x===false){break}if(w===false||(t==1&&x===true&&A===true)){r=true;p.type=["swipe",v[t]].join("");u.triggerHandler(p.type,p)}break;case"swipetwo":if((w&&t==2&&x===true&&A===true)){r=true;p.type=["swipe",v[t]].join("");u.triggerHandler(p.type,p)}break;case"swipethree":if((w&&t==3&&x===true&&A===true)){r=true;p.type=["swipe",v[t]].join("");u.triggerHandler(p.type,p)}break;case"swipefour":if((w&&t==4&&x===true&&A===true)){r=true;p.type=["swipe",v[t]].join("");u.triggerHandler(p.type,p)}break;case"swipeup":case"swiperightup":case"swiperight":case"swiperightdown":case"swipedown":case"swipeleftdown":case"swipeleft":case"swipeleftup":if(w&&x===true&&A===true){r=true;p.type=["swipe",((p.delta[0].lastX!=0)?((p.delta[0].lastX>0)?"right":"left"):""),((p.delta[0].lastY!=0)?((p.delta[0].lastY>0)?"down":"up"):"")].join("");u.triggerHandler(p.type,p)}break;case"tapone":case"taptwo":case"tapthree":case"tapfour":if((x!==true&&r!==true)&&(v[t]==z.slice(3))){p.description=["tap",v[t]].join("");p.type=["tap",v[t]].join("");u.triggerHandler(p.type,p)}break}var y={};u.data("ojQueryGestures",b.extend(true,l,y));u.data("ojQueryGestures",b.extend(true,l,y))}u.triggerHandler(b.jGestures.events.touchendProcessed,q)}function d(k){var j=jQuery(k.currentTarget);j.triggerHandler(b.jGestures.events.gesturestart,k);var l=j.data("ojQueryGestures");var m={};m.oStartTouch={timestamp:new Date().getTime()};j.data("ojQueryGestures",b.extend(true,l,m))}function e(k){var j=jQuery(k.currentTarget);var o,l,q,n;var p=j.data("ojQueryGestures");var m;for(m in p){switch(m){case"pinch":o=k.scale;if(((o<1)&&(o%1)<(1-b.jGestures.defaults.thresholdPinchclose))||((o>1)&&(o%1)>(b.jGestures.defaults.thresholdPinchopen))){l=(o<1)?-1:+1;n=c({type:"pinch",scale:o,touches:null,startMove:p.oStartTouch,event:k,timestamp:p.oStartTouch.timestamp,vector:l,description:["pinch:",l,":",((o<1)?"close":"open")].join("")});j.triggerHandler(n.type,n)}break;case"rotate":o=k.rotation;if(((o<1)&&(-1*(o)>b.jGestures.defaults.thresholdRotateccw))||((o>1)&&(o>b.jGestures.defaults.thresholdRotatecw))){l=(o<1)?-1:+1;n=c({type:"rotate",rotation:o,touches:null,startMove:p.oStartTouch,event:k,timestamp:p.oStartTouch.timestamp,vector:l,description:["rotate:",l,":",((o<1)?"counterclockwise":"clockwise")].join("")});j.triggerHandler(n.type,n)}break}}}function h(k){var j=jQuery(k.currentTarget);j.triggerHandler(b.jGestures.events.gestureendStart,k);var m;var n=j.data("ojQueryGestures");var l;for(l in n){switch(l){case"pinchclose":m=k.scale;if((m<1)&&(m%1)<(1-b.jGestures.defaults.thresholdPinchclose)){j.triggerHandler("pinchclose",c({type:"pinchclose",scale:m,vector:-1,touches:null,startMove:n.oStartTouch,event:k,timestamp:n.oStartTouch.timestamp,description:"pinch:-1:close"}))}break;case"pinchopen":m=k.scale;if((m>1)&&(m%1)>(b.jGestures.defaults.thresholdPinchopen)){j.triggerHandler("pinchopen",c({type:"pinchopen",scale:m,vector:+1,touches:null,startMove:n.oStartTouch,event:k,timestamp:n.oStartTouch.timestamp,description:"pinch:+1:open"}))}break;case"rotatecw":m=k.rotation;if((m>1)&&(m>b.jGestures.defaults.thresholdRotatecw)){j.triggerHandler("rotatecw",c({type:"rotatecw",rotation:m,vector:+1,touches:null,startMove:n.oStartTouch,event:k,timestamp:n.oStartTouch.timestamp,description:"rotate:+1:clockwise"}))}break;case"rotateccw":m=k.rotation;if((m<1)&&(-1*(m)>b.jGestures.defaults.thresholdRotateccw)){j.triggerHandler("rotateccw",c({type:"rotateccw",rotation:m,vector:-1,touches:null,startMove:n.oStartTouch,event:k,timestamp:n.oStartTouch.timestamp,description:"rotate:-1:counterclockwise"}))}break}}j.triggerHandler(b.jGestures.events.gestureendProcessed,k)}})(jQuery);