简体   繁体   中英

Javascript Canvas touch events

Hey I have an issue with my canvas and how it handles touch events, currently it's working fine with mouse events and drawing as intended however when I try to incorporate touch events it does somewhat work but when I touch on the canvas the output is fixed in the top left corner, leading me to believe the offset is way off and honestly I'm really not sure where to go from here so any help would be hugely appriciated.

$( document ).ready(function() {

  var container = document.getElementById('canvas');
  init(container, 200, 200, '#ddd');


  function init(container, width, height, fillColor) {
    var canvas = createCanvas(container, width, height);
    var ctx = canvas.getContext('2d');


    var mouse = {x: 0, y: 0};
    var touch = {x: 0, y: 0};
    var last_mouse = {x: 0, y: 0};
    var last_touch = {x: 0, y: 0};


    canvas.addEventListener('mousemove', function(e) {
      last_mouse.x = mouse.x;
      last_mouse.y = mouse.y;


      if (e.offsetX) {
        mouse.x = e.offsetX;
        mouse.y = e.offsetY;
      }
    });    

    canvas.addEventListener('touchmove', function(e) {
      var touch = e.touches[0];
      last_touch.x = e.pageX - touch.offsetLeft;
      last_touch.y = e.pageY - touch.offsetTop;


      if (e.offsetX) {
        touch.x = e.offsetX;
        touch.y = e.offsetY;
      }
    });  

    canvas.onmousemove = function(e) {

      var x = e.pageX - this.offsetLeft;
      var y = e.pageY - this.offsetTop;
    };

    canvas.addEventListener('touchstart', function(e) {
      canvas.addEventListener('touchmove', onTouchPaint, false);
    }, false);

    canvas.addEventListener('mousedown', function(e) {
      canvas.addEventListener('mousemove', onPaint, false);
    }, false);
    canvas.addEventListener('mouseup', function() {
      canvas.removeEventListener('mousemove', onPaint, false);
    });

    var onPaint = function() {
      ctx.beginPath();
      ctx.moveTo(last_mouse.x, last_mouse.y);
      ctx.lineTo(mouse.x, mouse.y);
      ctx.closePath();
      ctx.stroke();

      ctx.lineWidth = 15 ;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = 'black';
    };

    var onTouchPaint = function() {
      ctx.beginPath();
      ctx.moveTo(last_touch.x, last_touch.y);
      ctx.lineTo(touch.x, touch.y);
      ctx.closePath();
      ctx.stroke();

      ctx.lineWidth = 15 ;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = 'black';
    };
  } 
});

It's either onTouchPaint or touchmove and it's killing me. Any help is appriciated.

The following should get the proper touch or click location from the event. I did fight with this quite a bit myself, and this finally did the trick. It is basically a merged snipped from other answers here on stackoverflow. The trick should be to properly consider the canvas' getBoundingClientRect .

function getInteractionLocation(event) {
    let pos = { x: event.clientX, y: event.clientY };
    if (event.touches) {
        pos = { x: event.touches[0].clientX, y: event.touches[0].clientY };
    }
    const rect = event.target.getBoundingClientRect();
    const x_rel = pos.x - rect.left;
    const y_rel = pos.y - rect.top;
    const x = Math.round((x_rel * event.target.width) / rect.width);
    const y = Math.round((y_rel * event.target.height) / rect.height);
    return [x, y];
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM