Vlad Otrocol
Vlad Otrocol

Reputation: 3190

How do I Improve my canvas animation speed?

Basically I have some code which generates an imagedata and puts it in the canvas.

However, when I scale up the window, the rendering is slowed considerably.

Is there anyway to optimize this to run smoothly in fullscreen? (naive I know)

What is the best approach at optimizing it?

Here is the code running: http://jsfiddle.net/AMwNc/3/

Here is my code:

HTML:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">

  <title>_#Example</title>
  <meta name="description" content="_#Example">
  <meta name="author" content="SitePoint">
  <link rel="stylesheet" href="css/main.css?v=1.0">

  <!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
</head>

<body>
  <script src="js/main.js"></script>
  <div id="containingDiv">
    <canvas class = "board" id = "mainBoard">Your browser version is not supported</canvas>
  </div>
</body>
</html>

CSS:

#containingDiv { 
  overflow: hidden;
}
#mainBoard {
  position: absolute; 
  top: 0px;
  left: 0px;
} 

JS:

var canvas, ctx, frame;

function initAll(){
    canvas = document.getElementById('mainBoard');
    buffer = document.createElement('canvas');
    ctx = canvas.getContext('2d');
    frame = ctx.createImageData(ctx.canvas.height,ctx.canvas.width);
};

function resizeCanvas() {
    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
};

function draw(){
    frame = ctx.createImageData(ctx.canvas.width, ctx.canvas.height);
    for(var i=0;i<ctx.canvas.height; i++){
        for(var j=0; j<ctx.canvas.width; j++){
          var index  = ((ctx.canvas.width * i) + j) * 4;
          frame.data[index]= 255*Math.random();
          frame.data[index + 1]=255*Math.random();
          frame.data[index + 2]=255*Math.random();
          frame.data[index + 3]=255;
        }
    }
    ctx.putImageData(frame, 0, 0 );
};

window.requestAnimFrame = (function(callback) {
        return window.requestAnimationFrame ||
         window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame ||
           window.oRequestAnimationFrame || 
           window.msRequestAnimationFrame ||
        function(callback) {
          window.setTimeout(callback, 2000);
        };
      })();

function animate() {
    draw();
    requestAnimFrame(function() {
        animate();
    });
};

function viewDidLoad(){
    initAll();
    resizeCanvas();
    animate();
};


window.onload = viewDidLoad;
window.onresize = resizeCanvas;

Upvotes: 1

Views: 1045

Answers (2)

LogPi
LogPi

Reputation: 706

I saw that you call

 frame = ctx.createImageData(ctx.canvas.height,ctx.canvas.width);

2 times in initAll(), and draw(). You create imageData before you resize canvas. And i dont know in animate() what you handle to draw canvas.

My suggestion :You should remove that call in initAll(). Hope it help

Upvotes: 0

Philipp
Philipp

Reputation: 69773

Most HTML5 canvas implementations really benefit a lot from using GPU hardware-acceleration for the high-level manipulation functions like drawImage or stroking paths. Unfortunately any operations on raw image-data aren't hardware-accelerated. Your algorithm for generating random pixel data is executed on the CPU, not on the GPU, so it's quite slow.

When you want to go down to large-scale pixel level manipulations and still keep it performant, you might want to take a look at WebGL and pixel shaders. This will allow you to implement pixel-level algorithms on the GPU which can be several magnitudes faster.

Upvotes: 3

Related Questions