javascriptgoogle-chromecanvastouch-eventpen

Chrome canvas touchstart with pen is not working properly


I'm trying to create a canvas object which can be used like a mspaint to draw things. I want to be able to use the mouse, as well as the pen (in my case surface pen on a surface4).

Drawing with the mouse is ok with all 4 browsers. The problem is for the pen: it's working properly with IE11, Egde, Firefox, but there is one browser that resists and it's Chrome...

In fact, with Chrome(v63), the pen can draw, but only if the pen is not touching the screen, but is very close to it. Once I touch the screen with the pen, it doesn't draw anymore...

So am I missing something ? Why do I have this difference and who has the right implementation ? How can I fix that to be cross browser ? Please note that I also tried with the PointerEvent (https://developer.mozilla.org/en-US/docs/Web/Events/pointerdown) but it didn't work either....

The code

See and try the code here : https://codepen.io/miam84/pen/aNMryw

And here, a small part of the code with the listeners used :

canvas.addEventListener('touchstart', on_mousedown, false);
canvas.addEventListener('mousedown', on_mousedown, false);

function remove_event_listeners() {
      canvas.removeEventListener('mousemove', on_mousemove, false);
      canvas.removeEventListener('mouseup', on_mouseup, false);
      canvas.removeEventListener('touchmove', on_mousemove, false);
      canvas.removeEventListener('touchend', on_mouseup, false);
      document.body.removeEventListener('mouseup', on_mouseup, false);
      document.body.removeEventListener('touchend', on_mouseup, false);
};

//Event when the mouse is clicked
function on_mousedown(e) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = false;
        //we activate the mouse and touch events
        canvas.addEventListener('mouseup', on_mouseup, false);
        canvas.addEventListener('mousemove', on_mousemove, false);
        canvas.addEventListener('touchend', on_mouseup, false);
        canvas.addEventListener('touchmove', on_mousemove, false);
        document.body.addEventListener('mouseup', on_mouseup, false);
        document.body.addEventListener('touchend', on_mouseup, false);

        var xy = canvas.getCursorCoords(e);
        canvas.ctx.beginPath();
        canvas.pixels.push('moveStart');
        canvas.ctx.moveTo(xy.x, xy.y);
        canvas.pixels.push(xy.x, xy.y);
        canvas.xyLast = xy;
      }
};

Solution

  • Problem was solved using the PointerEvent API and was related to the way we get the pointer position with the offset (if canvas has a margin,...).

    Here is the way it works :

      canvas.removeEventListener('pointerup', on_mouseup, false);
      canvas.removeEventListener('pointermove', on_mousemove, false);
      document.body.removeEventListener('pointerup', on_mouseup, false);
    
    function getMouseOffset (_e, _el) {  
      let xpos, ypos;
      if (typeof _e.offsetX === 'undefined') { // ff hack
        // dans ce cas, jQuery facilite l'appel d'offset
        xpos = _e.pageX - $(_el).offset().left; 
        ypos = _e.pageY - $(_el).offset().top;
      } else {
        xpos = _e.offsetX;
        ypos = _e.offsetY;
      }
      return { x: xpos, y: ypos };
    }