JasonY
JasonY

Reputation: 770

How to stop scrolling only on using pen/stylus and not on finger touch

I'm working on a web app which needs to prevent scrolling on using a stylus but still allow scrolling on swiping the screen with a finger.

The problem I'm running into is that only the pointerstart event can distinguish between a finger touch and stylus pen touch via e.pointerType.

But it seems that it is impossible to stop the scrolling from pointerdown and needs to use touchstart which cannot detect the different between fingers and stylus/pen.

On Google Keep this is achieved by setting css touch-events:none; on the canvas and using pointer events to generate a simulated panning if it is a finger touch but that seems hacky.

Sample code I want to achieve

canvasElement.addEventlistener("pointerdown", function(event){
  if(event.pointerType === "pen"){
    // Disable scroll - This doesn't work
    event.preventDefault();
    event.stopPropagation();
    // Start drawing stuff
    startDrawing(...);
  } else {
    // Is a touch event do nothing, let it scroll naturally
  }
});

Any way this is possible without simulating a scroll?

Upvotes: 3

Views: 1991

Answers (1)

JasonY
JasonY

Reputation: 770

I actually figured out how to do this, one might think a possible way is to set the touch-action: none css attribute conditionally only when pointerdown is a stylus but that doesn't work, setting css when pointerdown is already too late and the scroll will initiate after.

The way I ended up doing this is I have a pointerdown listener to detect the stylus, store that as a variable and then a touchstart listener that fires after it that prevents default only if the last pointerdown was a stylus.

var isPen = false;

document.body.addEventListener("pointerdown", function(e){
  if(e.pointerType === "pen"){
    isPen = true;
    console.log("draw");
  } else {
    isPen = false;
  }
  e.preventDefault();
}, {
  capture: true
});

document.body.addEventListener("touchstart", function(e){
  if(isPen){
     e.preventDefault();
     }
}, {
  passive: false,
  capture: false
});

Try it out here: https://codepen.io/crfounder/pen/GQEXZM

Upvotes: 4

Related Questions