IE9 Includes Hardware Accelerated Canvas

var ctx0, ctx1;
var canvas0, canvas1;
var wave = 1;
var direction = 1;
var timer;
var HEIGHT2 = 100, WIDTH2 = 400;
var count = 0;
var currentX = 0, currentY = 0, lastX = 0, lastY = 0;
var r = Math.floor(Math.random() * 255) + 70;
var g = Math.floor(Math.random() * 255) + 70;
var b = Math.floor(Math.random() * 255) + 70;
window.onload=init;

function init() {
// Check to see if canvas is supported
if (!document.createElement(‘canvas’).getContext) return;

// Set up canvas0
ctx0 = document.getElementById(“canvas0”).getContext(“2d”);
ctxWidth = document.getElementById(“canvas0”).width;
ctxHeight = document.getElementById(“canvas0”).height;

// Set up canvas1
canvas1 = document.getElementById(“canvas1”);
ctx1 = canvas1.getContext(“2d”);
ctx1.lineWidth = 25;
ctx1.lineCap = “round”;

// Add event handlers
if (canvas1.addEventListener) canvas1.addEventListener(“mousemove”, OnMouseMove, false);
else if (canvas1.attachEvent) canvas1.attachEvent(“onmousemove”, OnMouseMove);

// Start the renderLoop
timer = setInterval(renderLoop, 16);

}

function OnMouseMove(e) {

if (typeof e == ‘undefined’) e = canvas1.event;
if (typeof e.offsetX != ‘undefined’ && typeof e.offsetY != ‘undefined’) {
currentX = e.offsetX;
currentY = e.offsetY;
}
else {
var relPos = getRelativePos(e.clientX, e.clientY);
currentX = relPos[0];
currentY = relPos[1];
}
}

// My thanks to QuirksMode.org for the insight here
function getRelativePos(x, y) {
var curleft = curtop = 0;

var obj = document.getElementById(‘canvas1’);
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}

// Webkit isn’t compliant with CSS OM View here; thus, we need to grab scrollTop from body instead of documentElement

if (document.body.scrollLeft > 0) {
var scrollLeft = document.body.scrollLeft;
}
else {
scrollLeft = document.documentElement.scrollLeft;
}

if (document.body.scrollTop > 0) {
var scrollTop = document.body.scrollTop;
}
else {
scrollTop = document.documentElement.scrollTop;
}

return [(x – curleft + scrollLeft), (y – curtop + scrollTop)];
}

function drawLines(ctx, x, y) {
ctx.save();
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.strokeStyle = “rgba(” + r + “,” + g + “,” + b + “, 1)”;
ctx.stroke();
ctx.restore();
}

function clearLines(ctx) {
// Clear first
ctx.fillStyle = “rgba(0,0,0,0.05)”;
ctx.fillRect(0, 0, WIDTH2, HEIGHT2);

// Change up color
if (count++ > 50) {
count = 0;
r = Math.floor(Math.random() * 255) + 70;
g = Math.floor(Math.random() * 255) + 70;
b = Math.floor(Math.random() * 255) + 70;
}
}

function renderLoop() {

// Draw lines
clearLines(ctx1);
drawLines(ctx1, currentX, currentY);
lastX = currentX;
lastY = currentY;
drawSimpleShapes(ctx0);
}

function drawSimpleShapes(ctx) {

// Draw background
if (wave >= 60 || wave <= 0) { direction = -direction; } var gradient1 = ctx.createLinearGradient(0, 15, 0, 70); gradient1.addColorStop(0, "blue"); gradient1.addColorStop(1, "white"); ctx.clearRect(0, 0, 300, 70); ctx.fillStyle = gradient1; ctx.beginPath(); ctx.moveTo(0, 35); ctx.quadraticCurveTo(75, 70 - wave, 150, 35); ctx.quadraticCurveTo(225, 0 + wave, 300, 35); ctx.lineTo(300, 70); ctx.lineTo(0, 70); ctx.fill(); wave = wave + direction / 5; // Draw green rectangle ctx.beginPath(); ctx.fillStyle = "rgba(0, 255,0,.3)"; ctx.rect(10, 10, 50, 50); ctx.fill(); ctx.stroke(); // Draw blue circle ctx.beginPath(); ctx.fillStyle = "rgba(0, 0, 255,.3)"; ctx.arc(105, 35, 25, 0, 2 * Math.PI, true); ctx.fill(); ctx.stroke(); // Draw lines with decreasing widths ctx.strokeStyle = "black"; ctx.lineWidth = 10; ctx.beginPath(); ctx.moveTo(155, 15); ctx.lineTo(205, 15); ctx.stroke(); ctx.lineWidth = 8; ctx.beginPath(); ctx.moveTo(155, 29); ctx.lineTo(205, 29); ctx.stroke(); ctx.lineWidth = 6; ctx.beginPath(); ctx.moveTo(155, 41); ctx.lineTo(205, 41); ctx.stroke(); ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(155, 51); ctx.lineTo(205, 51); ctx.stroke(); ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(155, 59); ctx.lineTo(205, 59); ctx.stroke(); // Draw image var image = document.getElementById("ie-logo"); ctx.drawImage(image, 220, 0, 70, 70); }

With the recent release of the latest IE9 platform preview, we talked about how we’re rebuilding the browser to use the power of your whole PC to browse the web, and to unlock a new class of HTML5 applications. One area that developers are especially excited about is the potential of HTML5 canvas. Like all of the graphics in IE9, canvas is hardware accelerated through Windows and the GPU. In this blog post we discuss some of the details behind canvas and the kinds of things developers can build.

Canvas enables everything from basic shapes to fully interactive graphics

Canvas is a way to program graphics on the web. The <canvas> tag is an immediate mode 2d drawing surface that web developers can use to deliver things like real time graphs, animations or interactive games without requiring any extra downloads.

At the most basic level, canvas enables you to draw primitives like lines, rectangles, arcs, Bezier curves, quadratic curves, images and video like the following:

This image is a simulation of what you’d see in a canvas enabled browser.

Please use the IE9 preview to see these examples running in canvas.

The Canvas Pad demo on the IE test drive site goes into detail on the canvas syntax and enables you to easily experiment with a wide range of examples. Feel free to make changes to any of the samples that are there to see how it works — for example, try changing colors or sizes of things.

Taking things a step further, you can use JavaScript to animate canvas drawings or make interactive experiences. The next example draws lines as you move your mouse (or as you move your finger on touch enabled devices) over the black box. You could also choose to have your canvas experience react to keyboard input, mouse clicks or any browser event.

This image is a simulation of what you’d see in a canvas enabled browser.

With canvas support in IE9, you can move your mouse over the black box and draw lines.

By utilizing the full power of the PC with hardware acceleration for graphics and fast JavaScript for animation, web developers can use IE9 to build deep, graphically rich experiences. Since canvas is an element like other elements in HTML, it participates in the page layout and its API is exposed to JavaScript so it can be fully incorporated into a web page’s design. This makes it possible for sites to include things like live data visualizations, games, splash pages and ads without the need for any extra downloads or plugins.

The IE testdrive site includes several examples that demonstrate the kinds of things that sites are now able to do in an interoperable way.

Shopping

The Amazon Shelf shows what shopping for books could look like when the web site designer is able to use the kind of graphics, animations and smooth transitions that canvas enables.


var vid = document.getElementById(“myvid”);
if(vid && vid.canPlayType && !vid.canPlayType(“video/mp4”).match(/^(probably|maybe)$ /i)) {
vid.parentNode.insertBefore(vid.firstElementChild, vid);
vid.style.display = “none”;
document.getElementById(“image1″).style.display=”none”;
document.getElementById(“div1″).style.width=”377px”;
}
/*script to hide the play image if in IE8 */
if (vid && vid.canPlayType==null) {
document.getElementById(“image1″).style.display=”none”;
document.getElementById(“div1″).style.width=”377px”;
}

Demo of Amazon shelf in canvas

Immersive game experiences:

The following demos showcase some gaming concepts like physics, character animation, collision detection and mouse interaction coupled with hardware accelerated graphics. In these demos, you’ll notice that not all browsers can update the screen with the same frequency (FPS or frames per second). IE is able to maintain a high FPS by using Windows technologies to make use of your GPU – your computer’s hardware that’s optimized for rendering graphics.

FishIE Tank

This demo makes use of sprites to animate the fish and basic collision logic to redirect the fish when they hit the edges of the tank. It’s also good for measuring graphics performance because you can change the number of fish to increase or decrease the graphics load.

var vid = document.getElementById(“myvid2”);
if(vid && vid.canPlayType && !vid.canPlayType(“video/mp4”).match(/^(probably|maybe)$ /i)) {
vid.parentNode.insertBefore(vid.firstElementChild, vid);
vid.style.display = “none”;
document.getElementById(“image2″).style.display=”none”;
document.getElementById(“div2″).style.width=”377px”;
}
/*script to hide the play image if in IE8 */
if (vid && vid.canPlayType==null) {
document.getElementById(“image2″).style.display=”none”;
document.getElementById(“div2″).style.width=”377px”;
}

Asteroid Belt

The asteroid in the demo follows your mouse, scales and rotates. It’s an example of direct interactivity that you might find in a game.

Demo of asteroid belt in canvas

Mr. Potato Gun

A physics engine in this demo defines how the different parts of Mr. Potato head are launched from the gun and then how they react when they bounce off the ground. Many games use some form of physics engine like this to manage particle movement and their response.

Demo of potato gun in canvas

Canvas Zoom

This demo enables you to start with a very wide angle on an image like this mountain range and then zoom in very close image like people at a picnic. For games, it’s an interesting example of scaling and smooth transitions.

Demo of a mountain range than you can zoom into

Demos from around the web:

There are some pretty amazing demos floating around the web and I’d like to share a couple of our favorites — there are many more. An important part of implementing canvas is that we do it in an interoperable way so that developers can use the same markup. To help achieve this goal, we’re always looking for examples that work and those that don’t. A future canvas blog post will go into detail about how we work to be interoperable and what we do when there’s an issue reported.

I hope you enjoy some of these canvas examples from people around the web.

Cloth Simulation

This demo is interactive and the cloth is responsive to movement and gravity.

An interactive cloth simulation with gravity

Zwibbler

The shapes in this drawing app are preserved so you can select and then move, resize, or change their styling.

demo of a drawing tool named Zwibbler

Liquid Particles

The particles in this demo are drawn to or repelled from the mouse.

demo of particles

Kaleidoscope

This one does a nice job of drawing you in – it’s engaging and interesting to watch the patterns as they evolve.

demo of a kaleidoscope

Nebula Visualization

The alpha blending used by this demo are really well done. The result is a cloudy atmospheric look. It’s graphics intensive and it’s still very fast and smooth in IE9.

Nebula visualization using alpha blending

Animated Reflection

The author of this demo says, “The script is currently using 80% of my cpu so it’s not really practical. Hopefully we will be getting JIT’d javascript sometime soon.” Well, now JavaScript is compiled in IE9. It generally uses about 1% of my CPU.

animated image reflection

Asteroids in Canvas

This is a full game with nice graphics, collision detection, keyboard interactivity, score keeping and… green lasers.

asteroids in canvas

Particle Animation

See your name in lights. This is another demo that includes a particle system. You can run this with 300 or 1500 sprites. Go ahead and bump it up to 1500.

Particle animation showing letters

We’re looking forward to seeing the kinds visual experiences web developers will be able to build with a fully hardware accelerated browser.

Give it a try yourself. Watch the videos, get the latest platfrom preview, try out the canvas demos and build some examples of your own. If you find a bug in how canvas works or where the same markup behaves differently, please report bugs on Connect.

– Thanks, Paul Cutsinger and Jatinder Mann


IEBlog