The last few months I have had the great opportunity to work with the javascript Canvas api a lot. I love it. Anyways, I wanted to share my experience and also share the 7 things I found stood out in this experience as they relate to the three things I love most which are coding, music, and design. The three core subjects this site deals with. This is not a tutorial, however if there is any topic you guys would like me to cover please let me know.

1- I love the AMD pattern  (Require.js).
  • I remember one of the first projects I worked in at one of the places I worked at was written using Require.js. I also remember thinking something along the lines of “Ughh this syntax looks like the code is throwing up.” Like everything, however, through more exposure you learn that people chose the technologies they chose for good reason. Playing with AMD a lot more, I now really appreciate it, and love it.  I used it to make various cool Canvas modules that allowed me to add lots of functionality without taxing the browser.
  • I love this pattern because it allows one to create complex applications in which each heavy component is only fetched as it is needed, and once fetched it is cached. If a component depends on other components which have already been fetched, then those will not be fetched again.  Long story short this is awesome for big applications which load lots of unique components, as they wont tax the browser loading stuff they don’t need. A great example of this is the MarvelKids Scavenger Hunt functionality, where mini-games are accessible across 4 Marvelkids websites. These minigames share many of the same components. AMD in a way really is an organized form of script injection with architecture in mind.
  • You can see the awesome Scavenger Hunt at http://www.marvelkids.com/ or the Avengers Recruits which has a feature using this pattern as well.
  • Example of a common setup of the AMD pattern:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    define("mymodule", ["requiresThisOne", "andThisOne", "alsoThisOne"],
      function(dependency1, dependency2, dependency3Class){
       //Modules methods
       function MyModule(){
        //Some code
        return new dependency3Class(dependency1, dependency2);
       }
       return MyModule;
      }
    );
2- There are no DOM elements.
  • First I thought I’d start with the most obvious.  So in canvas you draw pixels, but there are no elements. I don’t often use prototype patterned  javascript, but found it to be the greatest stuff ever for writing these games.  I created my own Elements constructor which stores instance properties for coordinates, scaling, transformation, size and other basic things so I can keep track of where I am drawing `elements`. This enables collision detection and other techniques to allow the elements to interact together. Anyways I thought this to be really cool as you pretty much make the rules you need for whatever you are trying to build.  Your game is your world.
  • Example of how a basic constructor for this purpose could look like:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function ElementClass(){//This could be an AMD module used by every element in your canvas project
      this.init= function(texture,x,y){
        this.texture = texture;
        this.x = x;
        this.y = y;
        //the properties your engine tracks is up to you. Think of this similarly to the properties the DOM tracks for HTML elements
      }
    }
    //Now in some module hopefully in a separate file we import the ElementClass
    var myCharacter = new("a.png",10,10);

    //There are so many ways to set this up
3- Prototypes rule
  • I have always appreciated adding methods to the prototype for the sake of memory, however, I really used mostly a variation of the module pattern known as the “Prototype revealing module pattern”.  For making these games the prototype inheritance just allowed excellent extensibility.
  • Example:
    1
    Particle.context = this.context; //You can for example share your canvas context with all your components this way.
4- Audio… OMG Audio
  • I got to  to merge my love for audio.  I had to analyze the wav forms to allow extremely light seamless loops. If the crop and fades are not done right you can here clicks each time the track repeats in some browsers.
  • I got to play with my knowledge of sound design.  For example I remember using a multiband exciter to make three versions of the rocket whirling sound in the Rocket minigame for Scavenger Hunt.  The faster motion sound would carry more high frequencies, which in turn would help create the illusion of more speed. The slower lower frequency sounds I added harmonics to, otherwise it was inaudible without good headphones or a subwoofer.
  • Sorry, I think I got nerdy with this stuff.  Blame the new audio API which I hope I get to use a lot.
  • Example of two files, made from the same file. The second file has more harmonics and a more aggressive sound
5- Good architecture really matters
  • I always care about architecture, but when you are generating lots of particle effects and creating pools with complex objects, you will really notice if you have bad architecture.
  • Did I mention pools. Yes, you really have to manage your use of memory.  Usually thought of an annoyance in this scenario it is awesome, and makes you feel in control of the engine you are building.
6- Blending modes
  • In CSS there are many times designs are made with things like glows around a path, or shadows using the multiply blending mode in photoshop.  Where in CSS you can get a similar effect, with canvas you are the master of the pixels and can get 100% exactly the same effect. You can use one of the predefined blending modes or write your own.  Multiply blending mode for example is available as a predefined globalCompositeOperation but if it wasn’t you could simply multiply the rgb values of the two colors, and achieve the same result. All the blending modes are simply algorithms. With canvas making you the master of the pixels, you can create any blending mode you need.
  • This article shows a lot of the available by default globalCompositeOperations https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
7- Its responsive
  • Not really, but the canvas is an image and so it scales just like one.  Only thing is your pointer events have to be made in such a way that the values are not absolute to a specific size.
  • Example:
    1
    2
    3
    4
    canvas {//Do keep in mind you want your canvas width and height properties to be only as high as you need it. More pixels means more things to be processed and thus a bigger performance hit.
      max-width: 100%;
      height: auto;
    }
Share this:

Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter
If you enjoyed this post, make sure you subscribe to my RSS feed!

Comment now!
















Trackbacks