I’m building a drawing app (JS + HTML canvas) which should handle “pan” gestures.
So I have to distinguish a single-finger-touch (for drawing) and a two-fingers-touch (for panning).
And I’ve noticed that, no matter how fast you put two fingers on a screen, there will always be two touchstart
events generated:
the 1st one with a single touch (event.touches.lenght = 1
);
and the 2nd one with two touches (event.touches.lenght = 2
).
Thus, my log output looks like this:
touchstart -> touches.length = 1
touchstart -> touches.length = 2
touchmove -> touches.length = 2
...
touchmove -> touches.length = 2
touchend -> touches.length = 1
touchend -> touches.length = 0
This causes a problem – when a user starts panning, the app draws a single dot instead.
The problem described above was reproduced on Android 13 (Chrome v129).
I’ve also tested this with iPadOS 17 in both Safari and Chrome (v110) and discovered that with iPad it’s possible to get the 1st touchstart
with two touches in case if you put fingers fast enough and these fingers are not too far from each other.
This makes me guess that it’s a hardware thing related to a fact that a human cannot put two fingers on a screen in exactly the same moment of time.
Eventually, I’ve built a solution that accumulates touchstart
and touchmove
events, analyzes the sequence and decides whether it was a multi-touch gesture or not.
But still, I’m wondering if there is any standard / easier way to solve this?
Notes:
changedTouches
don’t help since these let you know what was changed, but not what will be changed;- using
PointerEvent
instead would bring a similar problem since each of the fingers generates its own pointer event.