Hook to listen for simple touch and/or mouse gestures on components.
Easily detect the direction during and at the end of touch or mouse/drag-movement, use the result to determine your action and then re-render. This hook works stateless to improve performance.
Demo to flick 'n swipe, here is the demo code.
The hook useSimpleGestures creates event handlers your can just spread to your component, add your handlers with addListener.
npm i --save react-simple-gesturesimport {
useSimpleGestures,
SimpleGesturesResult,
SimpleGesturesResultStart,
} from 'react-simple-gestures'
const SomeComponent = () => {
const {
// default handler for usage with touch gestures
handler,
// mouse handler to listen for non-touch events
handlerMouse,
// use this to add your listeners to any event
addListener,
// for usage in other event handlers, get the current internal state
getState,
} = useSimpleGestures({
// only count it as `left/right/up/down` after a change of px on an axis
minMovementX: 50,
minMovementY: 50,
})
React.useEffect(() => {
// register listeners on `start`, `move` and `end` events
const unsubStart = addListener('start', (evt: SimpleGesturesResultStart, e: TouchEvent | MouseEvent) => {
})
const unsubMove = addListener('move', (evt: SimpleGesturesResult, e: TouchEvent | MouseEvent) => {
if(evt.dir === 'left' && evt.posMovedX > 150 && evt.mPxPerMsX > 200) {
// "flicked" from left to right
// adding own "must have moved min px" is easy in the own handlers
}
})
const unsubEnd = addListener('end', (evt: SimpleGesturesResult, e: TouchEvent | MouseEvent) => {
if(evt.dir === 'left' && evt.posMovedX > 150 && evt.mPxPerMsX > 200) {
// same check, but after finishing the drag or touch-slide event
}
})
// don't forget to unsubscribe them on unmount:
return () => {
unsubStart()
unsubMove()
unsubEnd()
}
}, [addListener])
return <div
style={{
width: 500,
height: 500,
}}
// spread the handler on to the element, they are just `onMouseDown`, `onTouchStart` etc.
// use those wanted, either both or just one `handler` = `touch`, `handlerMouse` = `mouse`
{...handler}
{...handlerMouse}
/>
}Directions are collected in three variants, they describe the movement direction relatively to the start point:
- for
X-Axis, available in result:dirXanddirright,left,same
- for
Y-Axis, available in result:dirYanddirup,down,same
- for
XY-Axis, available in result:dirright-top,left-top,right-bottom,left-bottom,point
The XY-axis is built using the other two.
touchGrid: number, grid in which to count taps as the same then previoustouchAsSameTap: numberm inmshow long taps after another, in the same grid spot, are counted as the same tapminMovementX: number, min. movement in px, for the X-axis, before counting it as direction-changeminMovementY: number, min. movement in px, for the Y-axis, before counting it as direction-changenoMultiTouch: boolean, defaults tofalse, whentruedoes not executemoveandendactions while the user makes a multi touchgetOffset: (e: TouchEvent | MouseEvent) => { x: number | undefined, y: number | undefined } | undefined- allows supplying an offset to
moveandendcalculation - e.g. calculate the movement relatively to start
- e.g. allows scrolling to not mess up the pointer direction
- e.g. invalid directions where the pane moved, but the cursor kept the same position on the pane
- allows supplying an offset to
taps: numbernumber of taps in the sametouchGridpositiontouches: numbernumber of active touches, only for multi-touchstartX: numberstartY: numberstartTime: numbertime of thisstartevent in UTC mslastStartTime: numbertime of the previousstartevent in UTC mslastEndTime: numbertime of the lastendevent in UTC ms
time: numberof event in UTC msduration: numberinmssincestarttouches: numbernumber of active touches, only for multi-touchdir,dirX,dir: see above directionsposMovedX: number, alwayspositivenumber of px moved on the X-axisposMovedY: number, alwayspositivenumber of px moved on the Y-axismovedX: number,negativeorpositivenumber of px moved on the X-axismovedY: number,negativeorpositivenumber of px moved on the Y-axisstartX: numberstartY: numberlastX: numberlastY: numberlastOffsetX: numberlastOffsetY: numbermPxPerMsY: number, milli px per milli second velocity for Y-axismPxPerMsX: number, milli px per milli second velocity for X-axis
Checkout packages/simple-gestures/src/SimpleGestures.ts for further infos and the most important interfaces.
If you get errors related to TouchEvent or MouseEvent typings, it's important to use the ones exported by react:
import { TouchEvent, MouseEvent } from 'react'This project adheres to semver, until 1.0.0 and beginning with 0.1.0: all 0.x.0 releases are like MAJOR releases and all 0.0.x like MINOR or PATCH, modules below 0.1.0 should be considered experimental.
- Clone/fork repository
npm inpm run bootstrap && npm run hoist- Now run either:
npm startfor launching demo app compilation of packagesnpm testfor running testsnpm run tddfor running tests in watch modenpm run buildfor building the demo app and packages
This project is free software distributed under the MIT License.
See: LICENSE.
© 2021 Michael Becker