I’m experimenting with a script and trying to adopt use for an iOS device. Since there would no way to use an onmousemove event, I want to use something that would simulate touching and dragging. The easiest way I came up with doing this is using a timer to always render the draw effect I have with the current mouse position only if it has been toggled first by using onmousedown, and untoggled by using onmouseup.
I’d expect the timeCount function to be triggered if I just call it outside of any function, but it doesn’t, so first I check if it’s null inside the onmousedown event, and if it is, call timedCount.
timeCount is called, and even though I have the setTimeout defined, it only calls timeCount one additional time, and that’s it. So that’s my first problem.
Secondly, how would I capture my current touch point (assuming the users finger is somewhere else on the screen) without an event? Or do I need an event? Which one?
Code is as follows. It’s an edited example from http://html5demos.com/canvas-grad:
<canvas height="600" width="600"></canvas>
<script>
var canvas = document.getElementsByTagName('canvas')[0],
ctx = null,
grad = null,
body = document.getElementsByTagName('body')[0],
color = 255;
var toggleDraw = 0;
var timer = null;
if (canvas.getContext('2d')) {
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 600, 600);
ctx.save();
// Create radial gradient
grad = ctx.createRadialGradient(0,0,0,0,0,600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, 'rgb(' + color + ', ' + color + ', ' + color + ')');
// assign gradients to fill
ctx.fillStyle = grad;
// draw 600x600 fill
ctx.fillRect(0,0,600,600);
ctx.save();
}
canvas.onmousedown = function (event) {
toggleDraw = 1;
if(timer == null){
timedCount();
}
};
canvas.onmouseup = function (event) {
toggleDraw = 0;
};
function timedCount(){
if(toggleDraw == 1){
alert("yes");
var width = window.innerWidth,
height = window.innerHeight,
x = event.clientX,
y = event.clientY,
rx = 600 * x / width,
ry = 600 * y / height;
var xc = ~~(256 * x / width);
var yc = ~~(256 * y / height);
grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
ctx.fillStyle = grad;
ctx.fillRect(0,0,600,600);
}
timer=setTimeout("timedCount()",50);
}
I’ve also tried an alternative of using setInterval on the canvas mouse events and removing the setTimeout in the timeCount function, but the timeCount function is not called at all:
canvas.onmousedown = function (event) {
toggleDraw = 1;
timer=setInterval("timedCount()",50);
};
canvas.onmouseup = function (event) {
toggleDraw = 0;
clearInterval(timer);
};
Edit: Even with this, I cannot get it to work:
<script>
var canvas = document.getElementsByTagName('canvas')[0],
ctx = null,
grad = null,
body = document.getElementsByTagName('body')[0],
color = 255;
if (canvas.getContext('2d')) {
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 600, 600);
ctx.save();
// Create radial gradient
grad = ctx.createRadialGradient(0,0,0,0,0,600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, 'rgb(' + color + ', ' + color + ', ' + color + ')');
// assign gradients to fill
ctx.fillStyle = grad;
// draw 600x600 fill
ctx.fillRect(0,0,600,600);
ctx.save();
canvas.ontouchmove = function (event) {
event.preventDefault();
var width = window.innerWidth,
height = window.innerHeight,
x = event.clientX,
y = event.clientY,
rx = 600 * x / width,
ry = 600 * y / height;
var xc = ~~(256 * x / width);
var yc = ~~(256 * y / height);
grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
// ctx.restore();
ctx.fillStyle = grad;
ctx.fillRect(0,0,600,600);
// ctx.save();
};
}
</script>
Okay, here is the working script!!
It is vital to use Apples touch API, and keep track of the touch you want to use:
<script>
var canvas = document.getElementsByTagName('canvas')[0],
ctx = null,
grad = null,
body = document.getElementsByTagName('body')[0],
color = 255;
if (canvas.getContext('2d')) {
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 600, 600);
ctx.save();
// Create radial gradient
grad = ctx.createRadialGradient(0,0,0,0,0,600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, 'rgb(' + color + ', ' + color + ', ' + color + ')');
// assign gradients to fill
ctx.fillStyle = grad;
// draw 600x600 fill
ctx.fillRect(0,0,600,600);
ctx.save();
}
canvas.ontouchmove = function (event) {
event.preventDefault();
if(event.touches.length == 1){
var touch = event.touches[0];
}
var width = window.innerWidth,
height = window.innerHeight,
//x = event.clientX,
//y = event.clientY,
x = touch.pageX;
y = touch.pageY;
rx = 600 * x / width,
ry = 600 * y / height;
var xc = ~~(256 * x / width);
var yc = ~~(256 * y / height);
grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
ctx.fillStyle = grad;
ctx.fillRect(0,0,600,600);
};
</script>
On iOS all mouse events fire at once, when the touch is finished. Which probably is not what you want.
Use
ontouchdown,ontouchmoveandontouchupevents instead.Also, in
ontouchmove, you need to prevent the default behavior so the page doesn’t start scrolling.