需要使用 HTML Canvas 将鼠标事件转换为移动设备的触摸事件
Need to convert Mouse events to Touch Events for mobile using HTML Canvas
基本上我希望上面的鼠标事件通过使用 touchevents 在移动设备上工作。那里也有一些代码可以在每次点击时更改颜色。我希望它就像将 touchevents 绑定到 mousevents 一样简单,但在我的反复试验中,我仍然无法让它工作。
任何帮助都会很棒!
这是我正在使用的代码:
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!
}
实际上 就像监听触摸和鼠标事件一样简单。
touchstart
事件是 mousedown
,touchmove
是 mousemove
,最后 touchend
是 mouseup
等价物。
理论上,您可以简单地向所有这些侦听器添加相同的回调函数。唯一的问题是你不能直接在回调函数中使用 event.clientX
属性 查询 'mouse' 的位置。那是因为可以有多个触摸,而总是只有一个鼠标事件。为了跟踪触摸,这些触摸存储在 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();
}
基本上我希望上面的鼠标事件通过使用 touchevents 在移动设备上工作。那里也有一些代码可以在每次点击时更改颜色。我希望它就像将 touchevents 绑定到 mousevents 一样简单,但在我的反复试验中,我仍然无法让它工作。
任何帮助都会很棒!
这是我正在使用的代码:
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!
}
实际上 就像监听触摸和鼠标事件一样简单。
touchstart
事件是 mousedown
,touchmove
是 mousemove
,最后 touchend
是 mouseup
等价物。
理论上,您可以简单地向所有这些侦听器添加相同的回调函数。唯一的问题是你不能直接在回调函数中使用 event.clientX
属性 查询 'mouse' 的位置。那是因为可以有多个触摸,而总是只有一个鼠标事件。为了跟踪触摸,这些触摸存储在 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();
}