Better canvas motion blur

Dagg Nabbit picture Dagg Nabbit · May 22, 2012 · Viewed 8.1k times · Source

It's been asked before, but the accepted solution doesn't work for me (literally, nothing is blurring for me in the linked demo), and it's a bit of a kludge involving two canvas elements.

I'm currently using the "poor man's" motion blur technique, which basically involves blitting the source image to the canvas over and over, and dropping a semi-transparent rectangle the same color as the background on top after each iteration.

Here's a demo: http://jsfiddle.net/YmABP/

As you can see, it works nicely for the edges of the image, but the inner parts of the image don't end up blurring at all, and it looks terrible with images that have partial transparency.

Is there a better technique for motion blur? Ideally, I'd like to be able to do something like context.drawImage and pass an opacity parameter in, but AFAIK nothing like that exists. Some of the images may be hosted on third-party domains, so I won't have access to the individual pixel data. If it comes down to it, we can pull the images onto our server and then I could iterate over each pixel and draw it as a semi-transparent tiny rectangle, but this seems like overkill.

Does anyone know of a better motion blur solution, preferably one that I can use with remote images?

I doubt this matters, but for my current purposes, things only move upwards.

Answer

Phrogz picture Phrogz · May 22, 2012

Just set the globalAlpha property of the context before drawing your image repeatedly:

Demo: http://jsfiddle.net/qfEUt/

var img = new Image,
    ctx = document.querySelector('canvas').getContext('2d');
    ctx.globalAlpha = 0.1;

img.onload=function(){
  for (var y=0;y<10;++y) ctx.drawImage(img,0,y);
}
img.src = 'http://phrogz.net/tmp/gkhead-small.png';​