I\'m doing a little HTML5 game and, while loading my sprites at the beginning of the map, I do some processing with GetImageData() / looping over all the image / PutImageData().
Phrogz has the right idea. You really just want to paint a half-transparent (or ratio-transparent) black over the whole thing with 'source-atop' globalCompositeOperation.
Like this: http://jsfiddle.net/F4cNg/
There was actually a good question on sophisticated darkening like this but the author deleted it which is a real shame. It's certainly possible to make dark-masks on drawn stuff, even with sophisticated shapes. They may not help you, but for the sake of completeness and for anyone searching for "darken canvas" stuff where some parts are kept light (exclusion zones), that can be done with the 'xor' globalCompositeOperation, like this:
http://jsfiddle.net/k6Xwy/1/
Have you seen this performance tip?: http://ajaxian.com/archives/canvas-image-data-optimization-tip
They talk about reducing calls to the DOM to increase performance.
So, based on this tip you might try:
var pixel = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
pixelData=pixel.data; // detach the pixel array from DOM
var length = pixelData.length;
for (var i = 0; i < length; i+= 4) {
pixelData[i] = pixelData[i] * ratio;
pixelData[i + 1] = pixelData[i + 1] * ratio;
pixelData[i + 2] = pixelData[i + 2] * ratio;
}
Your .data calls may be slowing you down.