Creating a useGestures hook
tl;dr
Here is the link to the npm package and to a demo site
My Motivation
Lately I’ve been working on this mobile app using cordova 😥
This is one of the worst projects I’ve been working on. But sometimes you might find a blessing in disguise 🙄. Out of the pain of this project, using the new version of react and with hooks taking their place as a legit pattern, I’ve decided to give it a go and create a custom hook for handling mobile gestures.
Implementation
Mobile gestures are a result of a touch event.
Now react has an event listener to touch events such as onTouchStart
, but I needed to use it in a more generic way and not just put it on a single element.
Thus I’ve used two hooks for the job. useRef
and useEffect
This hook gets a ref object resulted from the react built in hook useRef
.
“
useRef
returns a mutable ref object whose.current
property is initialized to the passed argument (initialValue
). The returned object will persist for the full lifetime of the component” — Hooks API Reference
Using the useEffect
hook, I attach and detach touch event listeners to the referenced element.
The useEffect
Definition is a little longer, so I’ll skip it here and just say that useEffect
runs after every render and it is the way you attach your component to external side effect (hence the name) such as generic touch events.
Translating touch event to gestures
Implementing three gesture types: Pan, Swipe and Pinch.
Pan and swipe are simple touch event with a small difference.
Swipe events have a direction and are triggered only when the touch movement distance is larger than a minimum value.
Pinch events are two finger touch events.
I’ve removed all the code I’ve talked about and some of the code I will talk about later on.
There are two things to notice here
- On each event handler, we need to determine if the touch is a Pinch event (exactly tow touch pointers) or not
- On touch move and on touch end, we need to check if the gestures triggered a swipe event
Helper functions
Here we have four help functions
getDistance
returns the distance between two pointers (touches)
getAngleDeg
returns the angle in degrees between those pointer.
callHandler
Gets an event name and the event object to sand to the event handler listener function and dispatch attached listener function.
getCurrentTouches
Responsible to make sense out of the original touch event and determine our custom event object which we use later on.
An example
This is a simple example of using the useGestures
hook for rotating an image.
You can find this example and some more, on this demo page
That’s it
I hope you find this post helpful and I hope you find my useGestures package helpful 😀