首页 > 解决方案 > 需要使用 HTML Canvas 将鼠标事件转换为移动设备的触摸事件

问题描述

基本上我希望上面的鼠标事件通过使用触摸事件在移动设备上工作。那里有一些代码可以在每次点击时更改颜色。我希望它就像将 touchevents 绑定到 mouseevents 一样简单,但在我的反复试验中,我仍然无法让它工作。

对此的任何帮助将是惊人的!

这是我正在使用的代码:

  var canvas = document.createElement('canvas');
document.body.appendChild(canvas);

// some hotfixes... ( ≖_≖)
document.body.style.margin = 0;
canvas.style.position = 'relative';

// get canvas 2D context and set him correct size
var ctx = canvas.getContext('2d');
resize();

// last known position
var pos = { x: 0, y: 0 };

const cvs = document.getElementById("canvas");
cvs.addEventListener('mousedown', getRandomInt);

window.addEventListener('resize', resize);
document.addEventListener('mousemove',  draw);
document.addEventListener('mousedown',  setPosition);
document.addEventListener('mouseenter',  setPosition);


function getRandomInt() {
  window.randInt = Math.floor(Math.random() * Math.floor(3));
}

// new position from mouse event
function setPosition(e) {
  pos.x = e.clientX;
  pos.y = e.clientY;
}

// resize canvas
function resize() {
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;
}

function draw(e) {
  // mouse left button must be pressed
  if (e.buttons !== 1) return;

  var color = '';

  switch (window.randInt) {
    case 1: 
      color = 'green';
      break;
    case 2: 
      color = 'red';
      break;
    case 0:
      color = 'blue';
      break;
  }

  ctx.beginPath(); // begin

  ctx.lineWidth = 3;
  ctx.lineCap = 'round';
  ctx.strokeStyle = color;

  ctx.moveTo(pos.x, pos.y); // from
  setPosition(e);
  ctx.lineTo(pos.x, pos.y); // to

  ctx.stroke(); // draw it!
}

标签: javascripthtml5-canvasmouseeventtouch-event

解决方案


实际上,它就像监听触摸和鼠标事件一样容易。事件touchstartmousedown, touchmovethemousemove和 lasttouchendmouseup等价的。

从理论上讲,您可以简单地将相同的回调函数添加到所有这些侦听器。唯一的问题是您不能使用event.clientX回调函数中的属性直接查询“鼠标”位置。那是因为可以有多次触摸,而总是只有一个鼠标事件。为了跟踪触摸,这些触摸存储在一个TouchList或多或少的数组中,这是.touches事件的属性。

所以我们需要在回调函数内部区分鼠标和触摸事件:

  • 如果是触摸使用event.touches[0].clientX
  • 如果是鼠标事件,请使用event.clientX

这是基于您的代码的示例:

var canvas = document.createElement('canvas');
canvas.id = "canvas";
document.body.appendChild(canvas);

document.body.style.margin = 0;
canvas.style.position = 'relative';

var ctx = canvas.getContext('2d');
resize();

var pos = {
  x: 0,
  y: 0
};
var buttonDown = false;

const cvs = document.getElementById("canvas");
cvs.addEventListener('mousedown', getRandomInt);
cvs.addEventListener('touchstart', getRandomInt);

window.addEventListener('resize', resize);

document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
document.addEventListener('mouseup', released);

document.addEventListener('touchstart', setPosition);
document.addEventListener('touchmove', draw);
document.addEventListener('touchend', released);

function getRandomInt() {
  window.randInt = Math.floor(Math.random() * Math.floor(3));
}

function released(e) {
  buttonDown = false;
}

function setPosition(e) {
  if (e.type == "touchstart" || e.type == "mousedown") {
    buttonDown = true;
  }
  if (e.type == "touchstart" || e.type == "touchmove") {
    pos.x = e.touches[0].clientX;
    pos.y = e.touches[0].clientY;
  } else {
    pos.x = e.clientX;
    pos.y = e.clientY;
  }
}

function resize() {
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;
}

function draw(e) {
  if (!buttonDown) return;

  var color = '';

  switch (window.randInt) {
    case 1:
      color = 'green';
      break;
    case 2:
      color = 'red';
      break;
    case 0:
      color = 'blue';
      break;
  }

  ctx.beginPath();

  ctx.lineWidth = 3;
  ctx.lineCap = 'round';
  ctx.strokeStyle = color;

  ctx.moveTo(pos.x, pos.y);
  setPosition(e);
  ctx.lineTo(pos.x, pos.y);

  ctx.stroke();
}


推荐阅读