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-gestures
import {
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:dirX
anddir
right
,left
,same
- for
Y-Axis
, available in result:dirY
anddir
up
,down
,same
- for
XY-Axis
, available in result:dir
right-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: number
m inms
how 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
, whentrue
does not executemove
andend
actions while the user makes a multi touchgetOffset: (e: TouchEvent | MouseEvent) => { x: number | undefined, y: number | undefined } | undefined
- allows supplying an offset to
move
andend
calculation - 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: number
number of taps in the sametouchGrid
positiontouches: number
number of active touches, only for multi-touchstartX: number
startY: number
startTime: number
time of thisstart
event in UTC mslastStartTime: number
time of the previousstart
event in UTC mslastEndTime: number
time of the lastend
event in UTC ms
time: number
of event in UTC msduration: number
inms
sincestart
touches: number
number of active touches, only for multi-touchdir
,dirX
,dir
: see above directionsposMovedX: number
, alwayspositive
number of px moved on the X-axisposMovedY: number
, alwayspositive
number of px moved on the Y-axismovedX: number
,negative
orpositive
number of px moved on the X-axismovedY: number
,negative
orpositive
number of px moved on the Y-axisstartX: number
startY: number
lastX: number
lastY: number
lastOffsetX: number
lastOffsetY: number
mPxPerMsY: 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 i
npm run bootstrap && npm run hoist
- Now run either:
npm start
for launching demo app compilation of packagesnpm test
for running testsnpm run tdd
for running tests in watch modenpm run build
for building the demo app and packages
This project is free software distributed under the MIT License.
See: LICENSE.
© 2021 Michael Becker