javascript - 需要使用 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!
}
解决方案
实际上,它就像监听触摸和鼠标事件一样容易。事件touchstart
是mousedown
, touchmove
themousemove
和 lasttouchend
是mouseup
等价的。
从理论上讲,您可以简单地将相同的回调函数添加到所有这些侦听器。唯一的问题是您不能使用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();
}
推荐阅读
- python-3.x - 如何一次读取多个传感器
- android - 如何在 android studio 中按字母顺序格式化 XML 代码?
- spotfire - 直线计算/预测
- istio - Istio 限速要求
- c# - 水晶报告 asp.net 我必须使用 setdatabaselogon
- node.js - HTTP 错误:401,请求具有无效的身份验证凭据。预期的 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据
- java - 运行我的 Spring Boot 应用程序时 Feign UnsatisfiedDependecyException
- python - 如何在python中使用for循环从可用数据中创建一个函数
- spring - 我可以使用 API 调用通过 Spring Security 对不同的应用程序进行身份验证吗?
- neo4j - 无法将 Neo4j 商店从 3.2.2 升级到 3.5.1