Apple’s <canvas> tag
I’ve started experimenting with Apple’s new HTML extension, the <canvas> tag, which allows access to the Cocoa 2D API from JavaScript. With the <canvas> tag, you can basically execute code to generate graphics primitives on the client using JavaScript. The most interesting aspect of this is the ability to render sophisticated graphics in response to JavaScript events like mouse clicks, mouse drags, or key presses. This is something which JavaScript alone has never before been capable of, since it lacks a common 2D API.
Safari 1.3 and later supports the <canvas> tag, and the Mozilla guys have already announced support to be implemented in the next version of Firefox. A pre-release alpha version called Deer Park is now available with solid <canvas> support.
So here’s a little <canvas> tag drag-and-drop example that works in Safari 1.3 or later and Firefox Deer Park alpha 2 or later. It’s very similar to a lot of more traditional JavaScript drag-and-drop exercise except that rather than literally dragging a <div> element across the page, here we’re recording mouse drag events and redrawing a primitive rectangle graphic using the 2D API exposed by the <canvas> tag.
<canvas> tag drag-and-drop example
Of particular interest… notice how much faster the Safari implementation is than Firefox on Mac. Safari JavaScript performance blows Firefox away.
Here’s the relevant JavaScript code:
var dragging;
var x = 10;
var y = 10;
var width = 100;
var height = 100;
var deltaX;
var deltaY;
var offsetX;
var offsetY;
var evtX;
var evtY;
var context;
function main() {
var canvas = document.getElementById("my-canvas");
offsetX = getOffsetX(canvas);
offsetY = getOffsetY(canvas);
context = canvas.getContext("2d");
context.fillStyle = "#900";
paint();
}
function paint() {
context.clearRect(0,0,400,400);
context.fillRect(x,y,width,height);
}
function canvasPressed(evt) {
translateEventCoords(evt);
if (clickedInRect()) {
dragging = true;
deltaX = evtX - x;
deltaY = evtY - y;
}
}
function canvasDragged(evt) {
if (!dragging) return;
translateEventCoords(evt);
x = evtX - deltaX;
y = evtY - deltaY;
paint();
}
function canvasReleased(evt) {
dragging = false;
}
function clickedInRect() {
return evtX > x &&
evtY > y &&
evtX < x + width &&
evtY < y + height;
}
function translateEventCoords(evt) {
evtX = evt.pageX - offsetX;
evtY = evt.pageY - offsetY;
}
function getOffsetX(node) {
var result = node.offsetLeft;
for (var parent = node; parent = parent.offsetParent; parent != null) {
result += parent.offsetLeft;
}
return result;
}
function getOffsetY(node) {
var result = node.offsetTop;
for (var parent = node; parent = parent.offsetParent; parent != null) {
result += parent.offsetTop;
}
return result;
}
About this entry
You’re currently reading “Apple’s <canvas> tag,” an entry on Todd Ditchendorf’s Blog.
- Published:
- 09.05.05 / 3pm
- Category:
- Cocoa, JavaScript/DHTML, Mac OS X
Comments are closed
Comments are currently closed on this entry.