Sunday, September 5, 2010

Animating the Canvas Part 3: Getting Primitive

Before I get to the actual article, I will briefly point out that Dozen Days of Words episode 12: Morse Code has been posted on the site and while I never had the time to get dirty rectangles implemented in it, it does use a primitive layers system. In fact, if you are running it on Internet Explorer using excanvas you can visibly see how dirty rectangles could dramatically improve things. This is not noticeable on browsers that support the canvas tag.

As is often the case, before we can get to the good stuff, we need to build the foundation. As this project is going to require a bunch of classes and JavaScript, at least current implementations of it, is not really designed for such a thing we need to think about the best way of handling classes. Everything in JavaScript is thrown into a global namespace which can lead to problems. Looking at how other JavaScript libraries have handled the problem, I am going to follow the same route and put all my classes into a single object which is essentially equivalent to packages in Java or ActionScript.

This is actually very easy to do and to my surprise, it poses no problems for using the prototype variable in class creation. The one disadvantage to this technique is that you are putting the entire library into the package. Two ways around this is to break the library up into separate files that can be individually included, or to use a utility like Google's closure compiler. Setting up the package is simple:

var BGLayers = new Object();

With the "package" set up, it is time to get some of the primitives out of the way. The obvious most primitive graphic objects are the point and dimension. Both of these classes are essentially just structures but they are handy to have.

BGLayers.Point = function(x,y)
    this.x = x;
    this.y = y;

BGLayers.Dimension = function(w,h)
    this.width = w;
    this.height = h

The next class is a bit more complicated but is important as it is really the heart of this engine. No, not the layers class (we will start on that next week) but the lowly Rectangle. The question is how to handle the construction of the rectangle as I would like support for a valid empty rectangle, a clone constructor that takes a Rectangle as the sole parameter and copies it, and a Rectangle that lets you specify the four parameters.

Java and ActionScript support multiple constructors and functions by basing which function gets called on the parameters used. JavaScript doesn't do this yet. So how does one have multiple constructors for something like the Rectangle class? This is where I get to play around a bit with JavaScript. Researching this subject I discovered that functions have a arguments variable that holds the parameters. While arguments is not technically an Array object, it does have a length and can be accessed like an array. By using the length, the three different constructors can be combined into a single constructor function as follows:

BGLayers.Rectangle = function(x, y, w, h)
    if (arguments.length == 1) { // clone rectangle
        this.x = x.x;
        this.y = x.y;
        this.width = x.width;
        this.height = x.height;
    } else if (arguments.length == 4) { // parametrized rectangle
        this.x = x;
        this.y = y;
        this.width = w;
        this.height = h;
    } else { // default to empty rectangle
        this.x = 0;
        this.y = 0;
        this.width = 0;
        this.height = 0;

I have noticed that I am starting to get a bit code-heavy. I want to focus more on the concepts and less on raw code, so I am thinking that for future posts I will link to the source file and just focus on the most relevant code while having an overview of the additional code. This has the added advantage of get through a lot more material and there is a lot of material that I want to cover here. As the Layers class is rather huge, I suspect that it will require more than one post to cover everything in it. Once we get that out of the way we can get to the animation part.

1 comment:

Marvelan said...

Nice Post.
Thanks for great sharing.