Skip to content

Very small gesture recognizer for JavaScript. Swipe, pan, tap, doubletap, longpress, pinch, and rotate.

License

Notifications You must be signed in to change notification settings

sciactive/tinygesture

Repository files navigation

TinyGesture.js

Very small gesture recognizer for JavaScript. Swipe, pan, tap, doubletap, longpress, pinch, and rotate.

Installation

npm install --save tinygesture
  • If you're upgrading from v2, the diagonalLimit option has changed meaning and there are new events for pinch and rotate. Also TS now exports ES2020 instead of ES6.
  • If you're upgrading from v1, the location of the file has changed. It's now in a "dist" folder, hence the major version change.

Usage

Constructor and Options

importTinyGesturefrom'tinygesture';// Options object is optional. These are the defaults.constoptions={// Used to calculate the threshold to consider a movement a swipe. it is// passed type of 'x' or 'y'.threshold: (type,self)=>Math.max(25,Math.floor(0.15*(type==='x' ? window.innerWidth||document.body.clientWidth : window.innerHeight||document.body.clientHeight),),),// Minimum velocity the gesture must be moving when the gesture ends to be// considered a swipe.velocityThreshold: 10,// Used to calculate the distance threshold to ignore the gestures velocity// and always consider it a swipe.disregardVelocityThreshold: (type,self)=>Math.floor(0.5*(type==='x' ? self.element.clientWidth : self.element.clientHeight)),// Point at which the pointer moved too much to consider it a tap or longpress// gesture.pressThreshold: 8,// If true, swiping in a diagonal direction will fire both a horizontal and a// vertical swipe.// If false, whichever direction the pointer moved more will be the only swipe// fired.diagonalSwipes: false,// The degree limit to consider a diagonal swipe when diagonalSwipes is true.// It's calculated as 45deg±diagonalLimit.diagonalLimit: 15,// Listen to mouse events in addition to touch events. (For desktop support.)mouseSupport: true,};consttarget=document.getElementById('target');constgesture=newTinyGesture(target,options);

Listening to Gesture Events

gesture.on('panstart',(event)=>{// Always the original mouse or touch event.// This service uses passive listeners, so you can't call// event.preventDefault() on any of the events.event;// The (screen) x coordinate of the start of the gesture.gesture.touchStartX;// The (screen) y coordinate of the start of the gesture.gesture.touchStartY;});gesture.on('panmove',(event)=>{// Everything from panstart, and...// The amount the gesture has moved in the x direction.gesture.touchMoveX;// The amount the gesture has moved in the y direction.gesture.touchMoveY;// The instantaneous velocity in the x direction.gesture.velocityX;// The instantaneous velocity in the y direction.gesture.velocityY;// Boolean, whether the gesture has passed the swiping threshold in the x// direction.gesture.swipingHorizontal;// Boolean, whether the gesture has passed the swiping threshold in the y// direction.gesture.swipingVertical;// Which direction the gesture has moved most. Prefixed with 'pre-' if the// gesture hasn't passed the corresponding threshold.// One of: ['horizontal', 'vertical', 'pre-horizontal', 'pre-vertical']gesture.swipingDirection;// To tell if the gesture is a left swipe, you can do something like this:if(gesture.swipingDirection==='horizontal'&&gesture.touchMoveX<0){alert('You are currently swiping left.');}});gesture.on('panend',(event)=>{// Everything from panstart and panmove, and...// The (screen) x coordinate of the end of the gesture.gesture.touchEndX;// The (screen) y coordinate of the end of the gesture.gesture.touchEndY;// Swipe events are fired depending on the touch end coordinates, so// properties like swipingDirection may be incorrect at this point, since// they're based on the last touch move coordinates.});gesture.on('swiperight',(event)=>{// The gesture was a right swipe.// This will always be true for a right swipe.gesture.swipedHorizontal;// This will be true if diagonalSwipes is on and the gesture was diagonal// enough to also be a vertical swipe.gesture.swipedVertical;});gesture.on('swipeleft',(event)=>{// The gesture was a left swipe.// This will always be true for a left swipe.gesture.swipedHorizontal;// This will be true if diagonalSwipes is on and the gesture was diagonal// enough to also be a vertical swipe.gesture.swipedVertical;});gesture.on('swipeup',(event)=>{// The gesture was an upward swipe.// This will be true if diagonalSwipes is on and the gesture was diagonal// enough to also be a horizontal swipe.gesture.swipedHorizontal;// This will always be true for an upward swipe.gesture.swipedVertical;});gesture.on('swipedown',(event)=>{// The gesture was a downward swipe.// This will be true if diagonalSwipes is on and the gesture was diagonal// enough to also be a horizontal swipe.gesture.swipedHorizontal;// This will always be true for a downward swipe.gesture.swipedVertical;});gesture.on('tap',(event)=>{// The gesture was a tap. Keep in mind, it may have also been a long press.});gesture.on('doubletap',(event)=>{// The gesture was a double tap. The 'tap' event will also have been fired on// the first tap.});gesture.on('longpress',(event)=>{// The gesture is currently ongoing, and is now a long press.});gesture.on('pinch',(event)=>{// The gesture is an ongoing pinch.// This is the current scale of the pinch. <1 means the user is zooming out.// >1 means the user is zooming in.gesture.scale;});gesture.on('pinchend',(event)=>{// The pinch gesture is completed.});gesture.on('rotate',(event)=>{// The gesture is an ongoing rotate.// This is the current angle of the rotation, in degrees.gesture.rotation;});gesture.on('rotateend',(event)=>{// The rotate gesture is completed.});

Long Press without Tap

If you want to listen for both long press and tap, and distinguish between them, this is how to do it.

letpressed=false;// Note: don't use the 'tap' event to detect when the user has finished a long// press, because it doesn't always fire.gesture.on('tap',()=>{// If the user long pressed, don't run the tap handler. This event fires after// the user lifts their finger.if(pressed){return;}// ... Your tap handling code here.});gesture.on('longpress',()=>{// Indicate that this is a long press. This event fires before the user lifts// their finger.pressed=true;// ... Your long press ongoing handling code here.});gesture.on('panend',()=>{// This is how you would detect when the user has finished a long press,// because 'panend' will always fire, even if the user has moved their finger// a little after 'longpress' has fired.if(pressed){// ... Your long press finished handling code here.// Make sure to reset pressed after the current event loop.setTimeout(()=>{pressed=false;},0);}});

Un-listening to Gesture Events

// There are two ways to un-listen:constcallback=(event)=>{};constlistener=gesture.on('tap',callback);// First way.listener.cancel();// Second way.gesture.off('tap',callback);

Firing Events

// If, for some reason, you want to programmatically fire all the listeners for// some event:gesture.fire('tap',eventObj);

Destruction

// When you're done, you can remove event listeners with:gesture.destroy();

Credits

A lot of the initial ideas and code came from:

https://gist.github.com/SleepWalker/da5636b1abcbaff48c4d

and

https://github.com/uxitten/xwiper

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •