Rq :
- avoid leaking global and declare x,y as vars in myDraw.
The suggestions :
- cache canvas.width and canvas.height to avoid DOM access,
- cache pos.x and pos.y
- trade (% 255) for (& 0xFF)
- cache Math.abs
- just create ONE imageData that you keep on modifying (relieves the g.c.).
- draw on requestAnimationFrame (otherwise you might have to wait for a frame to draw).
- cache the bounding rect of the canvas (and its top/left values).
jsbin is here :
you can switch old/new with 2 buttons.
looks like
var staticCanvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
function myDraw2(pos) {
canvasData = staticCanvasData;
var binaryData = canvasData.data;
var cw = canvas.width,
ch = canvas.height;
var posX = pos.x,
posY = pos.y;
var idx = 0;
var abs = Math.abs;
for (var y = 0; y < ch; y++) {
var yDiff = abs(posY - y) ;
for (var x = 0; x < cw; x++) {
//Red
binaryData[idx++] = x & 0xFF;
//Green : add a little animation on the green channel
//var dist = Math.sqrt( (pos.x - x) * (pos.x - x) + (pos.y - y) * (pos.y - y));
var dist = abs(posX - x) + yDiff;
var g = 255 - dist;
// if (g < 0) g = 0; // useless array is clamped
binaryData[idx++] = g;
//Blue
binaryData[idx++] = y & 0xFF;
//Alpha
binaryData[idx++] = 255;
}
}
ctx.putImageData(canvasData, 0, 0);
}
The results are quite good, FF takes half time (10 vs 20ms) time, Chrome 15 ms less (116 (!) to 100), and safari takes 7 instead of 20 !! (mac OS)
i did not investigate a lot, but it seem the fact alone not to create/copy a imageData on each redraw accounts for more than 60% of the gains.