Touch delay is a thing of the past, but accidental zooming is here to ruin your day. Ever tapped a button quickly on iOS and experienced a zoom instead of two taps? You're in the right place.
Just use this helper function to preventDefault
on double taps, while still
allowing for pinch to zoom and rapid scrolling.
// Ensure touches occur rapidly
const delay = 500
// Sequential touches must be in close vicinity
const minZoomTouchDelta = 10
// Track state of the last touch
let lastTapAt = 0
let lastClientX = 0
let lastClientY = 0
export default function preventDoubleTapZoom(event) {
// Exit early if this involves more than one finger (e.g. pinch to zoom)
if (event.touches.length > 1) {
return
}
const tapAt = new Date().getTime()
const timeDiff = tapAt - lastTapAt
const { clientX, clientY } = event.touches[0]
const xDiff = Math.abs(lastClientX - clientX)
const yDiff = Math.abs(lastClientY - clientY)
if (
xDiff < minZoomTouchDelta &&
yDiff < minZoomTouchDelta &&
event.touches.length === 1 &&
timeDiff < delay
) {
event.preventDefault()
// Trigger a fake click for the tap we just prevented
event.target.click()
}
lastClientX = clientX
lastClientY = clientY
lastTapAt = tapAt
}
const TapAsFastAsYouWantButton = (children, ...rest) =>
<button {...props} onTouchStart={preventDoubleTapZoom}>
{children}
</button>
const Game = () =>
<TapAsFastAsYouWantButton onClick={fireLasers}>
Fire Lasers
</TapAsFastAsYouWantButton>
This answer worked for me!