如何使用touchmove使mousemove事件适用于触摸屏?

问题描述 投票:0回答:2

我正在开发一个画布 JavaScript,通过 mousemove 事件你可以擦除背景......

现在我正在尝试在触摸屏(移动设备)上获得相同的体验。 如何同时为我的代码提供 mousemove 和 touchmove 事件?

(function() {
  // Creates a new canvas element and appends it as a child
  // to the parent element, and returns the reference to
  // the newly created canvas element


  function createCanvas(parent, width, height) {
    var canvas = {};
    canvas.node = document.createElement('canvas');
    canvas.context = canvas.node.getContext('2d');
    canvas.node.width = width || 100;
    canvas.node.height = height || 100;
    parent.appendChild(canvas.node);
    return canvas;
  }



  function init(container, width, height, fillColor) {
    var canvas = createCanvas(container, width, height);
    var ctx = canvas.context;
    // define a custom fillCircle method
    ctx.fillCircle = function(x, y, radius, fillColor) {
      /*this.fillStyle = fillColor;
      this.beginPath();
      this.moveTo(x, y);
      this.arc(x, y, radius, 0, Math.PI * 2, false);
      this.fill();*/
      var radgrad = ctx.createRadialGradient(x, y, 0, x, y, radius);
      radgrad.addColorStop(0, 'rgba(255,0,0,1)');
      radgrad.addColorStop(0.8, 'rgba(255,0,0,.9)');
      radgrad.addColorStop(1, 'rgba(255,0,0,0)');

      // draw shape
      ctx.fillStyle = radgrad;
      ctx.fillRect(x - radius, y - radius, x + radius, y + radius);
    };
    ctx.clearTo = function(fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fillRect(0, 1, width, height);
    };
    ctx.clearTo(fillColor || "#ddd");

    // bind mouse events
    canvas.node.onmousemove = function(e) {
      if (!canvas.isDrawing) {
        return;
      }
      var x = e.pageX - this.offsetLeft;
      var y = e.pageY - this.offsetTop;
      var radius = 100; // or whatever
      var fillColor = '#ff0000';
      ctx.globalCompositeOperation = 'destination-out';
      ctx.fillCircle(x, y, radius, fillColor);
    };
    canvas.node.onmouseenter = function(e) {
      canvas.isDrawing = true;
    };

  }


  var container = document.getElementById('canvas');
  init(container, 5000, 3000, '#f8fa58');

})();
body {
  margin-left: -10vw;
  margin-top: -30vh;
  background: url(https://i-d-images.vice.com/images/articles/meta/2014/10/21/untitled-article-1413860640.jpg?crop=1xw:0.44513137557959814xh;0xw,0.14219474497681608xh&resize=2000:*&output-format=image/jpeg&output-quality=75) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

#canvas {
  z-index: -1;
  top: 2vh;
  left: -10vw;
  width: 110vw;
  height: 130vh;
  overflow: hidden;
}
<div id="back"></div>
<div id="canvas"></div>

javascript jquery canvas mouseevent touch-event
2个回答
5
投票

您可以使用相同的事件处理程序,但在内部,您必须以不同的方式处理事件,因为

clientX
事件上没有
clientY
touch[XXX]
属性。

触摸事件可以是 multi 触摸,因此它们确实保存具有这些坐标属性的

touches
数组。

IMO 更简洁的方法是将事件处理程序分为两个不同的阶段: 一个用于提取事件的坐标,一个用于对这些坐标执行某些操作。

(function() {
  
  // a little verbose but...
  function handleMousemove(event){
    var x = event.clientX;
    var y = event.clientY;
    draw(x, y);
    }
  function handleTouchmove(event){
    event.preventDefault(); // we don't want to scroll
    var touch = event.touches[0];
    var x = touch.clientX;
    var y = touch.clientY;
    draw(x, y);
    }
  // this one can be shared by both touch and move events
  function activateDrawing(event){
    event.preventDefault();
    canvas.isDrawing = true;
    }
  function draw(eventX, eventY){
    var x = eventX - canvas.node.offsetLeft;
    var y = eventY - canvas.node.offsetTop;
    if (!canvas.isDrawing) {
        return;
      }
    var radius = 100; // or whatever
    var fillColor = '#ff0000';
    ctx.globalCompositeOperation = 'destination-out';
    ctx.fillCircle(x, y, radius, fillColor);
    }

  function createCanvas(parent, width, height) {
    var canvas = {};
    canvas.node = document.createElement('canvas');
    canvas.context = canvas.node.getContext('2d');
    canvas.node.width = width || 100;
    canvas.node.height = height || 100;
    parent.appendChild(canvas.node);
    return canvas;
  }

  var canvas, ctx;  // got it out to avoid nesting too deeply my handlers;

  function init(container, width, height, fillColor) {
    canvas = createCanvas(container, width, height);
    ctx = canvas.context;
    // define a custom fillCircle method
    ctx.fillCircle = function(x, y, radius, fillColor) {
      var radgrad = ctx.createRadialGradient(x, y, 0, x, y, radius);
      radgrad.addColorStop(0, 'rgba(255,0,0,1)');
      radgrad.addColorStop(0.8, 'rgba(255,0,0,.9)');
      radgrad.addColorStop(1, 'rgba(255,0,0,0)');

      // draw shape
      ctx.fillStyle = radgrad;
      ctx.fillRect(x - radius, y - radius, x + radius, y + radius);
    };
    ctx.clearTo = function(fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fillRect(0, 1, width, height);
    };
    ctx.clearTo(fillColor || "#ddd");

    // bind mouse events
    canvas.node.onmousemove = throttle(handleMousemove);
    canvas.node.ontouchmove = throttle(handleTouchmove);
    canvas.node.onmouseenter = 
    canvas.node.ontouchstart = throttle(activateDrawing);

  }

  var container = document.getElementById('canvas');
  init(container, 5000, 3000, '#f8fa58');

/* Bonus : throttle these events so they don't fire too often */
function throttle(callback) {
  var active = false; // a simple flag
  var evt; // to keep track of the last event
  var handler = function(){ // fired only when screen has refreshed
    active = false; // release our flag 
    callback(evt);
    }
  return function handleEvent(e) { // the actual event handler
    evt = e; // save our event at each call
    if (!active) { // only if we weren't already doing it
      active = true; // raise the flag
      requestAnimationFrame(handler); // wait for next screen refresh
    };
  }
}

})();
body {
  margin-left: -10vw;
  margin-top: -30vh;
  background: url(https://i-d-images.vice.com/images/articles/meta/2014/10/21/untitled-article-1413860640.jpg?crop=1xw:0.44513137557959814xh;0xw,0.14219474497681608xh&resize=2000:*&output-format=image/jpeg&output-quality=75) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

#canvas {
  z-index: -1;
  top: 2vh;
  left: -10vw;
  width: 110vw;
  height: 130vh;
  overflow: hidden;
}
<div id="back"></div>
<div id="canvas"></div>


0
投票

如果您在 2024 年或之后找到此页面,您可能只需要指针事件:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events

用pointerdown替换mousedown等

指针事件是为指针设备触发的 DOM 事件。 它们旨在创建单个 DOM 事件模型来处理 指向输入设备,例如鼠标、笔/手写笔或触摸(例如 一根或多根手指)。

© www.soinside.com 2019 - 2024. All rights reserved.