<canvas>
Institutional investment management is serious business
DrunkenFist.com and the freshly launched Java+++
The <canvas>
element and associated API started life as an Apple extension to HTML. From there it blossomed into one of the early stars of the HTML5 era.
The <canvas>
element provides a scriptable interface for drawing two-dimensional images in the browser. Think... dynamic PNGs. Even without full browser support on the desktop, developers have embraced canvas fully.
It’s been used for everything from high traffic visualizations to game engines, a system for delivering custom fonts, and a port of the Processing programming language into JavaScript.
It's an extremely low level API. This means you often have to do a bit of work but you have complete, pixel level control over the image.
Full control and a low level API sometimes you have to do things that are just silly.
The simplest part of working with canvas is the <canvas>
element itself. A <canvas>
element operates much like any other replaced element like <video>
or <img>
. The big difference is that it lacks a src
attribute. The “src” of the canvas image is provided by JavaScript.
The JavaScript is just series of commands that will manipulate the canvas in different ways. It begins with a context
which is a reference to canvas. the context provides methods to interact with the canvas and properties about the canvas.
<canvas id="circle" width="800" height="300"></canvas>
var ctx = document.getElementById( "circle" ).getContext( "2d" );
ctx.beginPath();
ctx.arc( 400, 150, 75, 0, Math.PI*2, true );
ctx.fillStyle = "#fe57a1";
ctx.closePath();
ctx.fill();
arc
is all you need to draw a circle when you have Math.PI*2
ctx.arc( 400, 150, 75, 0, Math.PI*2, true );
It's not the friendliest API. The arguments map to "center x", "center y", "radius", "start angle, in radians", "end angle, in radians" and "clockwise, as a Boolean"
Canvas is great for applications and visualization that require intense animation, real-time interaction and/or many "elements." Other common animated elements like SVG elements or DIVs are DOM elements so working with them is kind of scary. Thousands of "elements" in the canvas is still just the one element being manipulated pixel by pixel.
Let's make some stuff with canvas.
This specification defines the 2D Context, Level 2 for the HTML canvas element. The 2D Context provides objects, methods, and properties to draw and manipulate graphics on a canvas drawing surface.
function draw( data ) {
ctx.fillRect( 0, 0, 900, 300 );
var len = data.length,
width = 900/len,
gradient = ctx.createLinearGradient( 0, 0, 0, 300 );
gradient.addColorStop( ".5", "#003366" );
gradient.addColorStop( "1.0", "#ccff00" );
ctx.fillStyle = gradient;
for ( var i=0; i<len; i++ ) {
ctx.fillRect( i, 300, width, -data[i] );
}
}
Cee.js is a small helper library for the Canvas 2d API. The goal is to extend and enhance the basic API while still remaining familiarI'm partially to blame (also, yay @bobholt and @marcneuwirth)
function draw(data) {
ctx.reset();
var len = data.length,
width = 900/len,
fill;
for ( var i=0; i<len; i = i + 10 ) {
var dataLen = data[i];
for ( var j = 0; j < dataLen; j = j+10 ){
fill = "rgb("+j+","+(255-j)+",255)";
ctx.fillCircle({
x : i,
y : 300 - j,
radius : 4,
fillStyle : fill
});
}
}
}
The JavaScript InfoVis Toolkit provides tools for creating Interactive Data Visualizations for the Web.
icicle = new $jit.Icicle({
injectInto : 'infovis',
animate : animate,
offset : 1,
cushion : false,
constrained : true,
levelsToShow : 4,
Tips : {
enable : true,
type : 'Native',
offsetX : 20,
offsetY : 20,
onShow : function(tip, node){
var count = 0;
node.eachSubnode(function(){
count++;
});
tip.innerHTML = "<div class=\"tip-title\"><b>Name:</b> "
+ node.name + "</div><div class=\"tip-text\">" + count
+ " children</div>";
}
},
Events: {
enable : true,
onClick : function( node ){
if ( node ) {
icicle.tips.hide();
icicle.enter( node );
}
},
onRightClick: function(){
icicle.tips.hide();
icicle.out();
}
},
Label: {
type : labelType,
color : '#fff',
style : 'bold',
size : 12
},
onCreateLabel: function(domElement, node){
domElement.innerHTML = node.name;
var style = domElement.style;
style.fontSize = '0.9em';
style.display = '';
style.cursor = 'pointer';
style.color = '#fff';
style.overflow = 'hidden';
},
onPlaceLabel: function(domElement, node){
var style = domElement.style,
width = node.getData( 'width' ),
height = node.getData( 'height' );
if ( width < 7 || height < 7 ) {
style.display = 'none';
} else {
style.display = '';
style.width = width + 'px';
style.height = height + 'px';
}
}
});
icicle.loadJSON( json );
icicle.refresh();
roblarsen on Github | @robreact on Twitter
blog @ htmlcssjavascript.com