GithubHelp home page GithubHelp logo

sciactive / tinygesture Goto Github PK

View Code? Open in Web Editor NEW
175.0 10.0 17.0 176 KB

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

Home Page: https://sciactive.github.io/tinygesture/

License: Apache License 2.0

JavaScript 38.16% HTML 14.24% Shell 0.18% TypeScript 47.42%
events gesture javascript swipe touch double-tap gesture-recognition gesture-recognizer long-press pan

tinygesture's Introduction

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

import TinyGesture from 'tinygesture';

// Options object is optional. These are the defaults.
const options = {
  // 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,
};

const target = document.getElementById('target');
const gesture = new TinyGesture(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.

let pressed = 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:
const callback = (event) => {};
const listener = 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

tinygesture's People

Contributors

hperrin avatar nickantx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinygesture's Issues

Disable gesture events in scrollable content

Hello
Thanks for the great library.
I have one small question:
Is it possible to disable gesture events inside scollable container?
Something like this:
I can swipe down this white element like in mobile apps, but i have scrollable content, which must disable swipe.
image

No swipe events with `diagonalSwipes: true`

I apologize in advance for a short and blunt bug report.

I spent a while debugging why tinygesture wasn't firing swipe events at all. It didn't matter how I swiped. Turned out to be due to diagonalSwipes being set to true.

I don't have a repro, it's late and I probably forget about this tomorrow with all the corona fuss, so that will be all.

Doubletap without Tap?

You showed how to implement a long press without Tap.

Is there a similar thing for a double tap without tap?

Thanks!

Detect number of touch points used

Hi,

Thanks for a great library. Already we are using it in production in a PWA with great results.

I would now like to support some more gestures to enrich what our users can do, specifically a two finger horizontal swipe. Is there any way to tell from the fired event the number of touchpoints used?

Thanks,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.