HTML5 canvas painting fractals

A couple of weeks ago I came across this beautiful piece of Clojure code which paints a fractal using Swing. It is a nice example showing Clojure’s tight Java integration together with its concise┬áLISP syntax (If there is such a thing as a lisp syntax).

To get the hang of the HTML5 canvas tag and it’s corresponding API, I turned this Clojure code into its JavaScript equivalent. If this is not idiomatic JavaScript, I kindly request the sagacious reader to lead me back to the path of virtue.

The fractal renders itself again, if one resizes the browser window. Give it a go. I have tried various browsers and observed dramatic different rendering times. I don’t want to turn this into a canvas benchmark, but if somebody could shed some light here – please let us know. This is how it looks like:

And here’s the code:

function makeCanvas(id, width, height) {
    var canvas = document.createElement("canvas");
    canvas.id = id;
    canvas.width = width;
    canvas.height = height;
    return canvas;
}

function toRadians(angdeg) {
        return angdeg / 180.0 * Math.PI;
    }

function drawTree(context, angle, x, y, length, branchAngle, depth) {
	if(depth > 0){
		var newX = x - ( Math.sin(toRadians(angle)) * length );
		var newY = y - ( Math.cos(toRadians(angle)) * length );
		var newLength = (0.75 + (Math.random() * 0.1)) * length;
		var newAngle = (0.75 + Math.random()) * branchAngle;

		context.moveTo(x, y);
		context.lineTo(newX,newY);

		drawTree(context, ( angle + newAngle), newX , newY, newLength, branchAngle, depth - 1);
		drawTree(context, ( angle - newAngle), newX , newY, newLength, branchAngle, depth - 1);
	}
}

function render() {
	var width = window.innerWidth;
	var height = window.innerHeight;
    var canvas = document.getElementById("canvas");

    canvas.width = width;
    canvas.height = height;

    var context = canvas.getContext("2d");

    context.lineWidth = 1;
    context.strokeStyle = "green";

    context.fillStyle = "black";
    context.fillRect(0,0,width,height);

    var initLength = Math.min(width, height) / 5;
    var branchAngle = 10 * ( width / height );
    var maxDepth = 12;

    drawTree(context, 0.0, (width / 2) , height, initLength, branchAngle, maxDepth);
	context.stroke();
}

function init( ) {
	var canvas = makeCanvas("canvas", window.innerWidth, window.innerHeight);
	document.body.appendChild(canvas);
	render();
}

window.onresize = function(event) {
	render();
};
<html>
<head>
<script src="fractal.js"></script>
</head>
<body onload="init( )">
</html>
Posted in Uncategorized | Tagged | Leave a comment