Reputation: 43
Basically I want the mouseevents above to work on mobile through the use of touchevents. There is some code in there to change the color on each click as well. I 'm hoping that it's as easy as binding the touchevents to the mouseevents, but in my trial and error I still can't get it to work.
Any help with this would be amazing!
Here is the code that i'm working with:
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!
}
Upvotes: 4
Views: 5484
Reputation: 12891
Actually it is as easy as listening for both - touch and mouse - events.
The touchstart
event is the mousedown
, the touchmove
the mousemove
and lastly touchend
is the mouseup
equivalent.
Theoretically you could simply add the same callback functions to all of these listeners. The only problem is you can't directly query the 'mouse' position using the event.clientX
property inside the callback function. That's because there can be multiple touches while there is always just a single mouse event. To keep track of the touches, those are stored in a TouchList
- more or less an array - which is the .touches
property of the event.
So we need to make a distinction between a mouse and a touch event inside the callback function:
event.touches[0].clientX
event.clientX
Here's an example based on your code:
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();
}
Upvotes: 7