Web - How to differentiate between finger touch and stylus touch?
Asked Answered
E

1

6

I'm trying to make a drawing web app. I'd like to draw with stylus and move the canvas with my hand. How to distinguish between those two?

I haven't found anything promising in the official MDN docs.

Eu answered 15/4, 2020 at 16:20 Comment(4)
you probably can't... would be cool if you could thoughCatnip
That would be difficult. It might be possible with something like the Apple pencil, but your regular pencil stylus will look exactly the same as a finger. Alternatively, you could do something that only hands can do. You could move with two inputs close together and draw with one just one input.Slipshod
maybe a simple toggle button for draw/move mode? make it configurable for right/left hand artists?Catnip
@Catnip My experiments on an iPhone screen suggest that finger touches are at least twice as fat as stylus touches. Test page here: terrymorse.com/coding/pointerevents/index.htmlSere
S
3

You can tell with fairly high confidence if a touch is by finger or stylus by capturing the PointerEvent and checking its width and height properties, which represent the tip size.

A stylus typically has a smaller width and height than a finger.


Training an App to Recognize Finger vs. Stylus

Since tip size likely varies between screens, fingers, and styluses, a possible strategy would be to have the user train the app to recognize different types of touches:

"This is a finger" command, followed by several finger touches until the app has a good sample of sizes.

"This is a stylus" command, followed by several stylus touches.

MDN on PointerEvent interface.

Demo that shows stylus (or finger) tip size of every screen touch.

This will display the tip size of a touch or click on the screen:

let counter = 0;
// listen for 'pointerdown' events, detect tip size
window.addEventListener('pointerdown', (evt) => {
  const w = Number(evt.width).toFixed(1);
  const h = Number(evt.height).toFixed(1);
  const div = document.getElementById('result');
  counter++;
  div.innerHTML = `${counter}: stylus width: ${w}, height: ${h}`;
});
body {
  background-color: #eee;
  color: black;
}

#result {
  margin: 0.5rem;
  width: 18rem;
  min-height: 2rem;
  padding: 0.5rem;
  border: 1px solid gray;
  color: green;
}
<h4>Test of Pointer Stylus Tip Size</h4>
<p>Touch or click anywhere...</p>
<div id="result"></div>
Sere answered 15/4, 2020 at 17:2 Comment(4)
I imagine this approach can lead to many undesirable bugs for some users depending on browser, stylus, finger size, etc. then the UX is shot. without a proven api, hacks like this should almost always be avoided! your users will suffer for entirely preventable reasonsCatnip
I wouldn't be quite that dismissive. Certainly, it would take some more effort on the development side. The user could be prompted to train the app to differentiate between finger and stylus inputs.Sere
Ooh, that's a great idea. I think you should update your answer to provide that advice. final thought, what if the app is not able to distinguish between the stylus and finger? also, what if inconstitent height/width is on the event? how do you consistently distinguish between the two? what if the there is a chance for the event height/width to collide?Catnip
I'll add that training recommendation to the answer, thanks for the suggestion.Sere

© 2022 - 2024 — McMap. All rights reserved.