Adventures with <canvas>

acumen_asset_viewer
Acumen's Asset Viewer

Acumen is at 1.0 beta, and we finally settled on a hybrid image viewer. Google’s excanvas.js is used to fake a canvas in IE (getting it to work in IE8 was the trickiest part) but because excanvas.js runs pretty slowly and doesn’t support text (there are third-party text implementations of text in excanvas, but they’re also slow and don’t use standard fonts) I ended up using canvas just to render images. All main UI elements are implemented in HTML/CSS using jQuery.

Based on my googling, successfully creating a canvas that transparently works in either decent browsers or IE is not common knowledge, so I thought I’d share the method I came up with. I originally wrote this code for the pure canvas asset viewer (which forced IE users to install Chrome Frame); when I decided to reuse the code, I tried to simplify it, and everything I did to make it simpler broke it. I guess the me who wrote the original code wasn’t as big an idiot as the me who borrowed it thinks he was.

var c; // will contain a working canvas when we're done
var d = $('#div_that_will_contain_canvas');
var ie_version = some_expression_that_is_truthy_for_ie();
if( ie_version ){
	c = document.createElement('canvas');
	c.id = viewer_id;
	c.style.width = d.width() + 'px';
	c.style.height = d.height() + 'px';
	d.append( c );
	G_vmlCanvasManager.initElement( c );
} else {
	d.html('<canvas id="' + viewer_id + '" width="' + d.width() + '" height="' + d.height() + '"/>');
	c = document.getElementById( viewer_id );
}

The main takeaway is that creating the canvas using a blob of html does not work for IE (because it doesn’t recognize the canvas element, and thus ignores its attributes) and using the standard DOM methods does not work for proper canvas elements (because using styles to resize a real canvas stretches the canvas).

If you have a cleaner way of achieving the same result please let me know—I’m not proud of this code, it just happens to work.