<X />C{}JS();

A First Look at Canvas with Object Oriented JavaScript - Part 1


GridFader Render

The landscape of web development is extremely volatile, changing not only from year to year, but sometimes even day to day. The existence of tools such as http://caniuse.com/ should be enough to prove that.

With everyday life, I don't always get the opportunity to play with emergent technologies. However, that does not mean I never get to.

After being curious about the HTML5 canvas element for some time, I finally thought of a simple project to learn some of the basics. It also gave me the opportunity to make a demo for several of my peers who are studying object-oriented JavaScript and find the syntax and language slow to be understood. For a language invented in only 10 days , that's not entirely surprising.


After some consideration, I imagined a grid with optional borders containing translucent cells fading in and out. I assumed that canvas would have a simple way of supporting alpha transparency and drawing rectangles, at least. I wasn't too far off.

The final result can be viewed at http://xcjs.github.io/gridfader.js/ with source code and documentation available at https://github.com/xcjs/gridfader.js.

The final project is admittedly fairly useless, but if the proper animation speed and colors are chosen, it can create a mildly captivating display. I am using it currently as a background animation to the site, a testament to what can be accomplished by object oriented JavaScript and the way I express the knowledge I gather on various programming and technology paradigms. The entire project is object oriented and should remain flexible to adaptations.

Surprises Along the Way

Having never worked with a drawing API before, I wasn't exactly sure of what to expect. My hope was that canvas could be picked up easily since most web technologies appear to aim for simplicity. (Admittedly whether they actually succeed or not can be debated.)

For the most part this is true, however I did come across a few concepts that I originally had not considered but do make sense.

The Default Canvas Background is Transparent

This made sense once I noticed it, and it made the process of providing a way to change the background color a lot easier - instead of being a property of the JavaScript object, it can now be a property of the page the canvas is featured on. It would be trivial for someone to use an image, gradient, solid color, or other content. I quickly decided to make the default cell and grid colors translucent as well to leverage the default state of the canvas element.

The Canvas Size and the Size of the Drawable Canvas Can Be Different

Setting a canvas's size through the height and width attributes sets the size of the drawing area, however the canvas can be resized arbitrarily through CSS. This can have the effect of a blurry zoom or stretching out the drawing if the aspect ratio is not preserved.

Setting the Canvas Size Clears the Canvas

This is well documented and a nice shortcut to wipe your canvas state if you need to.

Drawing to a Canvas Does not Replace Previous Content

This also makes sense, but I had to get accustomed to the concept that anything I wanted to replace required a call to context.clearRect() (for my specific uses), especially since everything I drew was translucent by default. Before I realized this, the gridfader cells would fade in too opaquely.

Canvas Does Not Natively Support the Concept of Layers...

...nor can you use multiple contexts per canvas. If you want more than one context, you require more than one canvas. While layers are not natively supported, one could emulate the concept of layers in their own code through ordered drawing and tracking object state or layer canvas elements utilizing CSS.

Canvas Does Not Provide New Timing APIs

My naive hope was that HTML5 canvas would provide better timing methods to create animations. Unfortunately, window.setTimeout() and window.setInterval() are all that still exist.

Tracking Canvas State Using Objects

In Part 2 of this article, I will explain how I worked around these issues and how I took advantage of JavaScript scoping to encapsulate gridfader.js.