Creating pretty graphics – or any meaningful graphics at all – in web applications is an important issue. Visual information as well as illustration makes applications more appealing and often more usable and productive as well. Browsers render HTML and can fetch graphics by interpreting the IMG tag and downloading GIF, PNG, JPG files. Alternatively, we can use objects that are rendered by plug-ins, such as SVG – though we will see some native SVG support in the next generation of web-browsers. Simply drawing pictures in JavaScript was not really possible. Or was it? In any case, the relatively new CANVAS tag is about to change the landscape. And will be strong competition in some situations for SVG as ‘drawing technology’.
For a long time I have been trying to find out whether – and how – I could make simple drawings, most likely graphs and charts like pie-chart and line-graph, from JavaScript. I have run into primitive stuff like creating a Bar Chart by stretching table cells (set COLSPAN to any number between 1 and 100 to represent the value). Another rather far-fetched though pretty well worked out example used an image of a diagonal line and stretched in horizontal and vertical direction to get it pointing in any direction and of any length (see Drawing Lines in JavaScript). Of course this only works well for straight lines. The same approach of stretching images as seen above was used to create a Bar Chart: take an image of a rectangle – change its height or width property and you can show bars of varying sizes (see Creating graphs using JavaScript). I was sort of impressed by all the clever work-arounds, but found them basically far fetched and not really workable.
Then I came across something new. The CANVAS element. New in the Web Application 1.0 Specification that describes the successor to HTML4 and XHTML1. A specification that browsers like Firefox, Safari and Opera take their lead from. And perhaps Internet Explorer as well???
Web Application 1.0 Specification
A little citation from the Web App specification:
“HTML, CSS, DOM, and JavaScript provide enough power that Web developers
have managed to base entire businesses on them. What is required are
extensions to these technologies to provide much-needed features such as:
- Native pop-up menus and context menus.
- Inline markup for pop-up windows, for example for dialog boxes or tool
palettes, so that dialogs need not be defined in separate files. - Command updating: applications that have several access points for the
same feature, for instance a menu item and a tool-bar button, would
benefit from having to disable such commands only once, instead of having
to keep each access point synchronized with the feature’s availability at
all times. Similarly menu items or tool-bar buttons that represent a
toggle state could automatically stay synchronized whenever toggled. - Server-sent events: triggering DOM3 Events from the server-side, for
example for tickers or status updates. - Client-server communications methods that do not require page loads,
enabling on-demand data retrieval (where the UA automatically fetches
data from the server as required), remote procedure calls (where script
can invoke code on the server side and get an XML fragment in return),
etc. - More device-independent DOM events: The DOM event set needs
device-independent events, such as events that fire when a button or link
is activated, whether via the mouse or the keyboard.
DOMActivate
is a start, but it lacks equivalent HTML
attributes, and additional events may be needed.
- Sortable and multicolumn tree views and list views with rich
formatting.
- Rich text editing: an underlying architecture upon which
domain-specific editors can be created, including things like control
over the caret position.
- A predefined HTML editor based on the rich text editing architecture.
- Drag and drop APIs.
- Text selection manipulation APIs.
- Clipboard APIs (if the security and privacy concerns can be
addressed).”
So that is what the future of browsers looks like!
The new CANVAS element
<canvas> is a new HTML element which can be used to draw graphics using scripting (usually JavaScript). It can for instance be used to draw graphs, make photo compositions or do simple (and not so simple) animations. <canvas> was first introduced by Apple for the Mac OS X Dashboard and later implemented in Safari. Gecko 1.8-based browsers, such as Firefox 1.5, also support this new element. The <canvas> element is part of the WhatWG Web applications 1.0 specification also known as HTML 5.
The CANVAS element <canvas> creates a fixed size drawing surface that exposes one or more rendering contexts. We can get hold of a rendering context in JavaScript. When we have that context, we can make calls to it that create rectangles, arcs, straight lines etc. We have control over images that are pasted onto the canvas, write text and manipulate colors. We have the same sort transformations as in SVG: translate, scale, rotate. Animation of objects is also supported. Note that the functions and options are very, very similar to the elements and attributes – and script operations – supported in Scalable Vector Graphics (SVG). I have not yet seen whether objects drawn using CANVAS can have event handlers and respond to events.
Here is a very simple example of using the CANVAS element. Its output looks like this:
The function draw() gets hold of the canvas and its rendering-context. It then sets the fillStyle and creates a Rectangle with that fillStyle, changes the fillStyle and creates another rectangle – which is actually a square.
<html> <head> <script type="application/x-javascript"> function draw() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 50, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; ctx.fillRect (30, 30, 50, 50); } </script> </head> <body onload="draw()"> <canvas id="canvas" width="300" height="300"></canvas> </body> </html>
This a screenshot of a live demo of the CANVAS element – the 3D Walker Game. It is CANVAS plus JavaScript. You can walk through the maze, turn around, jump. As games go, it is trivial. As HTML and JavaScript go: it is awesome!
Bonus feature: take clips of the browser window
Mozilla’s canvas is extended with the drawWindow method. This method draws a snapshot of the contents of a DOM window into the canvas. For example,
ctx.drawWindow(window, 0, 0, 100, 200, "rgb(0,0,0)");
would draw the contents of the current window, in the rectangle (0,0,100,200) in pixels relative to the top-left of the viewport, on a black background, into the canvas. With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.
Creating Charts and Graphs using CANVAS
What triggered me into this exploration was the desire to create charts in my HTML pages, programmatically and client side. It was that search that led me to the CANVAS element, through the CanvasGraph.js library. Canvas Graph is a small simple javascript library that allows you to conveniently plot simple line, bar and pie charts using the new HTML Canvas Tag. And it delivers on that promise. Creating charts – in JavaScript, client side – is dead easy using CanvasGraph.js. In combination with AJAX this is an excellent combination for creating Dashboard style pages with various charts. Really the same as you can do using SVG but even easier especially when browser support increases.
One example of a bar chart done using CanvasGraph.js:
CANVAS in Internet Explorer
The CANVAS element is currently not – surprise surprise – supported in Internet Explorer. When official support is going to be available is unknown to me. However, Emil Eklund has created a JavaScript library that makes many of the key CANVAS features available on IE (see Resources for the relevant link). He says about his approach: “IE doesn’t support SVG natively either, it does support something called VML though, and it’s been around since the 5.0 days, if I remember correctly. VML does pretty much the same thing as SVG (as far as basic drawing is concerned). Using VML, in combination with behaviors, it should therefor be possible to emulate a subset of SVG or Canvas in IE. Having spent a few evenings working on such an implementation I’ve managed to create a proof of concept. ”
Resources
Web Applications 1.0 Working Draft — 12 January 2006 This specification represents a new version of HTML4 and XHTML1, along with a new version of the associated DOM2 HTML API. Migration from HTML4 or XHTML1 to the format and APIs described in this specification should in most cases be straightforward, as care has been taken to ensure that backwards-compatibility is retained.
Canvas Element – overview page on Mozilla Developer Center
Drawing Graphics with Canvas – Introduction of the new HTML 1.5 CANVAS element
CanvasGraph.js : Graphing in Javascript – A simple, small and highly effective JavaScript library, leveraging the CANVAS tag in for example FireFox 1.5, Safari 2.0 and Opera 9.0 (preview), to allow for extremely simple creation of pretty mature charts: LinePlot, PieChart and barChart.
Canvas in IE – JavaScript Library that adds the CANVAS capabilities to Internet Explorer (by Emil A Eklund)
Canvas Tutorial on Mozilla Developer Center
3D Walker game – demonstration of the SCAPE element in a sort of Maze Game (requires Firefox 1.5)
There’s also some work I did on SVG/VML drawing at xdraw.org, along with my OSCON 2006 slides on various browser graphics techniques.
I did overlook another library that attempts drawing in JavaScript, cross browser, no SVG plugin required and even support in fairly old browsers.
It is called High Performance JavaScript Vector Graphics Library.
Developed by Walter Zorn and to be found at
http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm.
It works by painting pixels as DIVs with a colored background. For heavy duty graphics stuff, it will be very slow. But for simple things like a line, a circle or even a simple graph it will do the job.