Here are some steps you can do to increase the performance:
- First get rid of the
save
/restore
- they are very expensive calls and can be replaced with setTransform
- Unwind the loop to do more inside per iteration
- Cache all properties
FIDDLE
Example with loop unwound for 4 iterations:
for(var nObject = 0,
len = objects.length, // cache these
x = coords.x,
y = coords.y; nObject < len; nObject++){
ctx.setTransform(1,0,0,1, x, y); // sets absolute transformation
ctx.rotate(objects[nObject].position*0.01);
ctx.translate(radio,0);
ctx.drawImage(imgToDraw,0,0);
objects[nObject++].position++;
ctx.setTransform(1,0,0,1,x, y);
ctx.rotate(objects[nObject].position*0.01);
ctx.translate(radio,0);
ctx.drawImage(imgToDraw,0,0);
objects[nObject++].position++;
ctx.setTransform(1,0,0,1,x, y);
ctx.rotate(objects[nObject].position*0.01);
ctx.translate(radio,0);
ctx.drawImage(imgToDraw,0,0);
objects[nObject++].position++;
ctx.setTransform(1,0,0,1,x, y);
ctx.rotate(objects[nObject].position*0.01);
ctx.translate(radio,0);
ctx.drawImage(imgToDraw,0,0);
objects[nObject++].position++;
}
ctx.setTransform(1,0,0,1,0,0); // reset transform for rAF loop
(don't expect real-time performance though).
Although, it is perhaps a bit pointless drawing 2000 objects in such a small area. If you are after the effect I would suggest this approach instead:
- Create an off-screen canvas
- Produce 5-8 frames with the method above and store them as images
- Play back those 5-8 images as-is instead of doing all the calculations
If you need more fluid look simply produce more frames. You can store each frame in a single canvas based on cells which you use as a sprite-sheet later. When drawing you must of course take care that current positions are static versus moving when actually animated. Rotation and the resulting position is another factor.