Skip to main content

Gestures

Overview#

Ionic Gestures is a utility that allows developers to build custom gestures and interactions for their application in a platform agnostic manner. Developers do not need to be using a particular framework such as React or Angular, nor do they even need to be building an Ionic app! As long as developers have access to v5.0 or greater of Ionic Framework, they will have access to all of Ionic Animations.

Building complex gestures can be time consuming. Other libraries that provide custom gestures are often times too heavy handed and end up capturing mouse or touch events and not letting them propagate. This can result in other elements no longer being scrollable or clickable.

Installation#

Developers using Ionic Core and JavaScript should install the latest version of @ionic/core.

import { createGesture } from 'https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/esm/index.mjs';
...
const gesture = createGesture({
el: elementRef,
threshold: 15,
gestureName: 'my-gesture',
onMove: ev => onMoveHandler(ev)
});

Basic Gestures#

Usage#

let p = document.querySelector('p');
const gesture = createGesture({
el: document.querySelector('.rectangle'),
onMove: (detail) => { onMove(detail); }
})
gesture.enable();
const onMove = (detail) => {
const type = detail.type;
const currentX = detail.currentX;
const deltaX = detail.deltaX;
const velocityX = detail.velocityX;
p.innerHTML = `
<div>Type: ${type}</div>
<div>Current X: ${currentX}</div>
<div>Delta X: ${deltaX}</div>
<div>Velocity X: ${velocityX}</div>
`
}

In this example, our app listens for gestures on the .rectangle element. When a gesture movement is detected, the onMove function is called, and our app logs the current gesture information.

Double Click Gesture#

Usage#

const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
const DOUBLE_CLICK_THRESHOLD = 500;
const rectangle = document.querySelector('.rectangle');
const gesture = createGesture({
el: rectangle,
threshold: 0,
onStart: () => { onStart(); }
});
gesture.enable();
let lastOnStart = 0;
let currentColor = 'rgba(0, 0, 255, 0.5)';
const onStart = () => {
const now = Date.now();
if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
rectangle.style.setProperty('background', getRandomBackground());
lastOnStart = 0;
} else {
lastOnStart = now;
}
}
const getRandomBackground = () => {
const options = backgrounds.filter(bg => bg !== currentColor);
currentColor = options[Math.floor(Math.random() * options.length)];
return currentColor;
}

In the example above, we want to be able to detect double clicks on an element. By setting our threshold to 0, we can ensure our gesture object can detect clicks. Additionally, we define a click threshold so that only 2 clicks that occur in quick succession count as a double click.

Gesture Animations#

See our guide on implementing gesture animations: Gesture Animations with Ionic Animations

Browser Support#

Browser/PlatformSupported Versions
Chrome22+
Safari9+
Firefox32+
IE/Edge11+
Opera30+
iOS9+
Android5+

Types#

NameValue
GestureCallback(detail: GestureDetail) => boolean \| void

Interfaces#

GestureConfig#

PropertyTypeDefaultDescription
elNodeundefinedThe element to listen on for gestures.
disableScrollboolean \| undefinedfalseIf true, scrolling will be disabled on el while the gesture is enabled.
direction'x' \| 'y' \| undefined'x'Limit gesture detection to movements along a certain axis.
gestureNamestringundefinedThe name of the gesture to create.
gesturePrioritynumber \| undefined0Gestures with higher priorities will override gestures with lower priorities. Useful for ensuring the multiple gestures do not collide with one another.
passiveboolean \| undefinedtrueIf true, this will indicate that the gesture will never call preventDefault(). This can be used to improve scrolling performance. See Passive Listeners for more information.
maxAnglenumber \| undefined40The maximum angle to allow when detecting a gesture.
thresholdnumber \| undefined10Defines how much a pointer must move before the gesture starts.
blurOnStartboolean \| undefinedundefinedIf true, the gesture will blur any active selectable element such as an input or a textarea before firing the onStart callback.
canStartGestureCallback \| undefinedundefinedA callback that returns true if a gesture is allowed to start.
onWillStart(detail: GestureDetail) => Promise<void>undefinedA callback that fires when a gesture is about to start. This is fired after canStart but before onStart.
onStartGestureCallback \| undefinedundefinedA callback that fires when a gesture has started.
onMoveGestureCallback \| undefinedundefinedA callback that fires when a gesture movement was detected.
onEndGestureCallback \| undefinedundefinedA callback that fires when a gesture has ended. This is usually when a pointer has been released.
notCapturedGestureCallback \| undefinedundefinedA callback that fires when a gesture has not been captured. This usually happens when there is a conflicting gesture with a higher priority.

GestureDetail#

PropertyTypeDescription
typestringThe type of gesture that was detected.
startXnumberThe starting x coordinate of the gesture.
startYnumberThe starting y coordinate of the gesture.
startTimeStampnumberThe timestamp at which the gesture was started.
currentXnumberThe current x coordinate of the gesture.
currentYnumberThe current y coordinate of the gesture.
velocityXnumberHow fast the gesture is currently moving on the x axis.
velocityYnumberHow fast the gesture is currently moving on the y axis.
deltaXnumberHow much the gesture has moved on the x axis since it started.
deltaYnumberHow much the gesture has moved on the y axis since it started.
timeStampnumberThe current timestamp of the gesture.
eventUIEventThe native event dispatched by the browser. See UIEvent for more information.
dataany \| undefinedAny data specified by the user. This can be set and read in any of the callbacks.

Methods#

enable(enable: boolean = true) => void#

Enable or disable the gesture.

destroy() => void#

Destroy the gesture instance and stop listening on the target element.