Hawaiian Earring Development Notes

In this post I’ll be describing my thoughts and methods when developing the Hawaiian Earring experiment which uses HTML5 canvas.

If you don’t want to read about all the technical mumbo jumbo you can use the link below to go straight to the good stuff. The post mortem continues below.

View the Hawaiian Earring Experiment.

Background and inspiration

I’m a big fan of recursion and procedural content generation. Recursive routines can produce remarkable results from minuscule pieces of code. When not completely debugged, these small ingenious routines can crash spectacularly if the termination case hasn’t been handled correctly.

Wikipedia defines recursion as:

Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem. The approach can be applied to many types of problems, and is one of the central ideas of computer science.

Wikipedia Quote Source

Google manages to slip in a nerdy joke if you search for recursion. The “did you mean” feature, which is normally used for spelling mistake suggestions, will say “Did you mean: recursion” and links back to itself. As the image below illustrates.

Google search results for
Google search results for “recursion”

Recursive techniques have often been used in graphical demonstrations. They are the ideal choice when a small executable size is necessary. The “Hello World!” equivalent of recursive graphical demonstrations is the Mandelbrot set fractal. This is named after the mathematician Benoît Mandelbrot, who studied and popularized it. Other common recursion graphic demonstrations are the Menger Sponge, the Sierpinski Carpet and the Koch Snowflake.

Menger Sponge
The Menger Sponge shown here to the fourth iteration.

I don’t think that humans are naturally conditioned to search for recursive solutions to problems. It requires a different approach than how we usually break a task down into separate steps. Recursive decomposition is usually the hard part, that is determining where the self similarity lies. The next step is to break the the problem into a smaller form which if reused can solve the overall problem. Once you have the plan of how to make the initial task smaller and simpler, following it through to it’s logical conclusion is usually easy.

Hawaiian Earring wireframeWhile browsing Wikipedia, I came across the Hawaiian Earring page. The text there is very dry but what I did find striking was a small wire frame image of the Hawaiian Earring.

To my eye, this looked like something that could easily be calculated with recursion. Each of the inner circles could be generated from known information about it’s parent. The recursion should terminate when the radius of the circle becomes too small.

Knowing when to stop or when enough is enough

The development would quick and painless because I was already familiar with the concepts and I had some thoughts how I could make it more interesting than plain wireframes. Before starting I decided to make a short list of things that I wanted to achieve with this experiment.

  1. Interactive

    The user should be able to interact with the experiment.

  2. Fast

    It should run as fast as the browser allows and respond quickly to user input.

  3. Try something new

    To keep me interested in the development and to motivate me to blog about it.

With these goals in mind, I began the development of the Hawaiian Earring. In the next section I’ll briefly go over points of interest in the source code.

requestAnimationFrame

If you’ve ever tried to do smooth animation in the browser, there’s a good chance that you’ve used the setTimeOut() or the setInterval() methods in JavaScript. These are used to trigger your update function every few milliseconds.

Now if you want your animations to run as fast as possible, there’s a better way to do things with requestAnimationFrame. The code below shows how it’s initialised. This is called at the end of the update() function when so that the browser will schedule the next update as soon as possible.


if ( !window.requestAnimationFrame ) {

	window.requestAnimationFrame = ( function() {

		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame || // comment out if FF4 is slow (it caps framerate at ~30fps: https://bugzilla.mozilla.org/show_bug.cgi?id=630127)
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

			window.setTimeout( callback, 1000 / 60 );

		};

	} )();

}

For more detailed information on requestAnimationFrame, take a look at Paul Irish’s blog post.

addEventListener

This experiment uses event listeners to change parameters of the Hawaiian Earring. One event listener is used to detect when the mouse is moved over the canvas area. Another event listener is used to process mouse clicks in the canvas area. Below is a cross browser method that will register an event listener.

addListener: function (type, target, fn)
{
	if(window.addEventListener)
	{
		target.addEventListener(type, fn, false);
	}
	else
	{
		target.attachEvent(
			"on" + type,
			function (e)
			{
				fn.apply(target, [e]);
			}
		);
	}
},

Clearing the canvas

In this experiment there are two different drawing modes used, wireframe and filled. The wireframe mode requires a clean canvas each frame. The easiest way to do this is by changing the canvas dimensions to a different value and then back again. This will flood fill the canvas with it’s background colour. This can be done with these two lines of JavaScript.

this.canvas.width = 1;
this.canvas.width = this.canvasSize;

For the filled drawing mode, I wanted a motion blur type effect with softer edges. I achieved this by retaining the canvas image from the previous frame and making it darker. This was done by setting the globalCompositeOperation mode to “darker” and then drawing a transparent rectangle over the whole canvas area. This can be done with the three lines of JavaScript below.

ctx.globalCompositeOperation = "darker";
ctx.fillStyle="rgba(0, 0, 0, 0.382)";
ctx.fillRect(0, 0, this.canvasSize, this.canvasSize);

The good…

The end result was reached quickly. The experiment runs smoothly and responds quickly to user interaction. There’s a good contrast between the wireframe and the filled drawing modes. The angle tweak in the alternative mode makes the motion interesting.

The bad…

There’s no recursion function calls in this final version. What?! Who’s to blame for this? Heads will roll! In my quest for higher frame rates I optimised out the recursion and obtain the same result using iteration instead. This tiny increase in speed isn’t noticeable in this experiment because so few circles are drawn. I couldn’t think of a good reason to revert back to the recursion version, other than that was the original plan.

The ugly…

When profiling this experiment it was obvious that the main bottleneck was in the canvas drawing. Rather than in the calculation of all the circle mid points and radii. So I fixed the size of the canvas to 256 pixels by 256 pixels to ensure a decent frame rate on all display sizes.

With more time I would have liked to include functionality to dynamically set the canvas size. This would determine the largest resolution possible that the user’s browser could handle smoothly. With this added functionality in place it would be easy to resize the canvas when the user’s browser window size changes.

Closing comments

Hawaiian Earring ExperimentOverall I’m pleased with how this first blogged experiment has turned out. Even if the final result was achieved using different methods than I originally intended.

Earlier in this post I’ve only touched on a few sections of the source code that may be of general interest. If you want to see how the user interaction is processed or how the Hawaiian Earring is constructed, the complete source for this experiment is available on github.

View the Hawaiian Earring experiment

Download the Hawaiian Earring source code from github

Posted in Development | Tagged , , , , , , , , , , , , , | Leave a comment

Smarter, faster, stronger, better. Now with added HTML5

Welcome to the all new http://www.gameboar.com. I thought it was time to clean off the cobwebs and update the site design with the latest features of HTML5, CSS3 and JavaScript.

With so much power available in modern browsers it is very easy to overload the User Experience (UX) with eye popping effects. Unfortunately, this approach to new technology often degrades the user experience, instead of enhancing it as it should.

I knew that to see real improvements to this site, I wouldn’t be able to simply patch the functionality. I would have to start with a blank page and build up from the core UX principles. So that’s what I did.

Oh, let’s go back to the start…

Browsers and the internet are both very different now compared to when this site first launched in 2006. At that time, Internet Explorer v6 was the browser of choice for most people. MySpace.com was still surging to new heights of popularity and jQuery was made available under the MIT License and released version 1.0.

The Present

Back to the present and Internet Explorer v6 is becoming less relevant by the day. Facebook and twitter are the hottest social platforms. jQuery is still powering ahead and now conquering mobile platforms too.

During this time, browsers have got ever more powerful and are now capable of delivering much richer, dynamic experiences than ever before. Users are now consuming internet content in many more ways than in the past. Desktops, laptops, netbooks, video game consoles, tablets and smartphones are now all being used to view content. Users expect a first class experience on all of them. Advances such as Media Queries (try rescaling your browser window) make this possible.

The Future

But one thing which hasn’t changed, is my thirst for information and exploring new technologies which I hope to cover on this blog. I’ll be writing about Front End Web Development, Indie Game Development and be announcing games that I’ve written in JavaScript to play in HTML5 supporting browsers. I’ll probably throw in the odd post about WordPress and Video Games too.

“New roads; new ruts”

Older browsers such as IE6, IE7 or IE8 each have their own unique issues which are well documented. On this site, I want to explore new technologies, not patch old ones. So for this reason I will not be spending any development time on these older browsers. If you’re viewing this site using an old browser, I apologise for the inconvenience but you really should upgrade. This is progress.

Posted in News | Tagged , , , , , , , , | Leave a comment