Pacerier
Pacerier

Reputation: 89603

isn't canvas supposed to be faster than dom manipulation when we have a lot of animation?

I'm wondering what is wrong with my code (why is the animation so jerky):

<html>
<head>

</head>
<body style="background:black;margin:0;padding:0;">
<canvas id="canvas" style="background:white;width:100%;height:100%;"/>
<script>
var img=new Image();
img.onload=function(){
  var c=document.getElementById('canvas');
  var ctx = c.getContext('2d');
  var left,top;
  left=top=0;
  ctx.drawImage(img,left,top,20,20);
  var f=function(){
    left+=1;
    top+=1;
    c.width=c.width;
    ctx.drawImage(img,left,top,20,20);
  };
  setInterval(f,20);
};
img.src="http://a.wearehugh.com/dih5/aoc-h.png";
</script>
</body>
</html>

From what I know canvas is supposed to be good at doing these kinda stuff? But if instead I used an element and manipulate its left and top it ended up being faster (less jerky)..

Is there something wrong with my script? or is this the best canvas can do?

Upvotes: 2

Views: 1386

Answers (1)

bjornd
bjornd

Reputation: 22943

  1. There is no need to clear the whole canvas on each iteration. It's possible to use clearRect method.

  2. Every time to draw image it's necessary to scale image. To avoid this you can draw on invisible canvas only once and then draw this canvas on visible one.

Your code with improved readability and performance:

<html>
<head>
</head>
<body style="background:black;margin:0;padding:0;">
    <canvas id="canvas" style="background:white;width:100%;height:100%;"/>
    <script>
        var img=new Image()
            buf = document.createElement('canvas');

        img.onload=function(){
            var c = document.getElementById('canvas'),
                ctx = c.getContext('2d'),
                left = 0, top = 0,
                width = 20, height = 20;

            buf.width = width;
            buf.height = height;
            buf.getContext('2d').drawImage(img, 0, 0, width, height);

            var f=function(){
                ctx.clearRect(left-1, top-1, width + 1, height + 1)
                left+=1;
                top+=1;
                ctx.drawImage(buf, left, top, width, height);
            };
            setInterval(f,20);
        };
        img.src="http://a.wearehugh.com/dih5/aoc-h.png";
    </script>
</body>
</html>

Upvotes: 4

Related Questions