Showing posts with label js. Show all posts
Showing posts with label js. Show all posts

Thursday, March 29, 2012

What I learned from THREE.js: calling parent methods

Three.js is awesome, it simplifies working with WebGL, and is a great source for JavaScript ideas. This article presents another idea I came across while working THREE.js source; applying a parent class' constructor to an inheriting class. To do this the parent constructor is invoked using apply or call.

var ClassA = function(){};

//ClassB inherits ClassA
var ClassB = function(){
    ClassA.call(this); //run parent constructor on this object
};
ClassB.prototype = new ClassA(); //inherit parent methods

The example above does call the parent constructor, but doesn't accomplish anything. Instance methods and properties are added to the prototype on the last line of the block. Calling the parent constructor is only useful when there are parameters. A simple example is extending DataModel object that manipulate and hold information pulled from a database.

//assume data has been converted to a javascript object
var DataModel = function(data){
    data = data || {}; //make sure data is a valid object
    this.id = data.id || ""; //stores id on the instance
};

//person inherits from data model
var Person = function(data){
    DataModel.call(this, data); //get a valid id

    data = data || {}; //make sure data is a valid object
    this.firstName = data.firstName || ""; //stores id on the instance
    this.lastName = data.lastName || ""; //stores id on the instance
}
Person.prototype = new DataModel();

Now any class that extends DataModel will have some defined value for id. Similarly an extension of Person would have a defined value for firstName and lastName.

You can take this concept even further. It can be used when overriding inherited methods as well. Note: this will not work as expected if using THREE.js' technique of defining instance methods as explained in the preceding THREE.js article.

In this next block, the DataModel and Person classes implement a toObject function, that returns the instance property values. The DataModel handles the the id property, while the Person handles the first and lastName properties.

//returns the 
DataModel.prototype.toObj = function(){
    var obj;
    obj.id = this.id;
    return obj;
}

//overrides DataModel toObj.
Person.prototype.toObj = function(){
    var obj = DataModel.prototype.call(this); //get object with id
    obj.firstName = this.firstName;
    obj.lastName = this.lastName;
    return obj;
}

In retrospect, this idea seems obvious. After all, this article demonstrates how to use call or apply to implement private methods, and the idea presented in this post simply uses the same concept on parent methods.

Sunday, March 25, 2012

What I learned from THREE.js: new way to encapsulate

Recently I've had the oportunity to work extensively with THREE.js, a WebGL framework primarily authored by Mr. Doob. This library simplifies the use of the powerful WebGL graphics engine. Not only is this library an excellent resource for WebGL, it also introduced me to some new techniques for JavaScript encapsulation and inheritance. This article presents a technique for simplifying method definition syntax.

Restructuring Class Implementation

The common method for adding methods to an object is to add the method names directly to the prototype.

var ClassName = function(){};
ClassName.prototype.methodName = function(){};

This works, but is a little verbose, and requires a lot of find/replace when overriding inherited methods. The clases in THREE.js avoid this repetition by defining instance methods during object construction. It looks like this.

var ClassName = function(){
        this.methodName = function(){};
};

The benefits are twofold. The syntax for method definition and overriding has been simplified. Also, Using the constructor for encapsulation obviates the use of closures to obfuscate private methods (as demonstrated in this previous post), further simplifying syntax.

Consider the following two classes.

/*
Class: ClassA
*/
var ClassA = function () {
        //add functions to object inside of constructor, simpler syntax
        this.foo = function () {
            console.log("parent foo");
            privateFoo.call(this);
        };
        //private methods also defined inside constructor
        function privateFoo() {
            console.log("parent private foo");
        }
    };

/*
Class: classB
inherits from classA.
*/
var ClassB = function () {
        this.foo = function () {
            console.log("child foo");
            ClassB.prototype.foo.call(this); //calling parent method
        };

        this.bar = function () {
            console.log("child bar");
        };
    };
ClassB.prototype = new ClassA();

var b = new ClassB();
b.bar(); //child bar
b.foo(); //child foo, parent foo, parent private foo

This is significantly more concise, and worth investigating further.

Issues

An obvious fault is that to call the parent method you have to access the child's prototype. This is conceptually confusing and a regression from the previously outlined method, where the parent prototype would be accessed (ie. ClassA.foo.call(this) ).

There is also a potential performance issue. It is possible that creating a new definition of instance methods at runtime will have an adverse affect on either memory footprint or speed. This will have to be tested.

Conclusion

It is to early to tell if I will start using this particular encapsulation scheme. The parent method mapping is a little strange, and the performance issue is something I'll have to investigate further. I will post any findings.

Thursday, February 9, 2012

Javascript OOP - NameSpaces

A fundamental issue with any large code project is maintaining unique identifiers, that is making sure that classes or global functions and variables have unique names. This problem can be mitigated with the use of namespaces. Grouping classes into sets is an explicit feature in many languages that support OOP: Java (packages), Python (modules), and C++(namespaces). JavaScript namespaces are not built in, but are possible with the requisite initiative.

This post demonstrates a simple namespace implementation. Two object prototypes named Person are created in two separate namespaces and thereby avoid convolution.

//if namespace exist use it, otherwise use a new object
var ENG = ENG || {};
//add person to the namespace
ENG.Person = function(){};
ENG.Person.prototype.sayHi = function(){
    console.log("Good Day, My name is John");
}

//if namespace exists use it, otherwise use a new object
var GRM = GRM || {};
//add person to the namespace
GRM.Person = function(){};
GRM.Person.prototype.sayHi = function(){
    console.log("Guten Tag, Ich Heiße Johan");
}

//create two people from two different namespaces.
var englishman = new ENG.Person();
var german = new GRM.Person();

englishman.sayHi(); // Good Day, My name is John
german.sayHi();     // Guten Tag, Ich Heiße Johan

Namespace switching isn't built into JavaScript, so it would be advisable to keep the namespace identifiers short, because they will have to be repeated.

Prominent libraries that encapsulate using namespace like structures:
$ - jQuery, Prototype
THREE - Three.js

For a library that offers a rich set of namespace functionality, investigate Namespace.js.

Saturday, January 28, 2012

JavaScript OOP - Protocols


Protocol are essential in life as well as programming. They define expected and required behaviors for different situations, allowing meaningful interaction to take place between unfamiliar entities. This allows common tasks to be completed in the face of new circumstances with minimal improvisation.

This post expands upon prototype inheritance, as outlined here, and demonstrates an implementation of protocols using Javascript objects. The common task in this case if the creation of a Mathematical series, and the protocol defines the series content

Protocol Base Class

This protocol (SeriesDataProvider) will have one required and one optional method. The required method (valueForIndex) generates the value of the member of a series for an index. it is require because an error will be thrown if it is not overridden in the inheriting class. The optional method (initFinished) is a callback that is called after the Series has been created.

/*/*
 * Protocol constructor
 */
var SeriesDataProvider = function(){};

//required method
SeriesDataProvider.prototype.valueForIndex = function(index){
     throw("this should be overridden by the inheriting class");
};

//optional method
//the passed series has finished initialization
SeriesDataProvider.prototype.initFinished = function(series){
     console.log("Series initialized", series);
};

*Series*

This next class uses a series data provider to generate its values. Looping from start to end indices asking the provider what the values are.

/*
/*
 * series implementation
 */
var Series = function(startIndex, endIndex, dataProvider){
     dataProvider.series = this;     

     //get servies values for indices in range
     for(var i=startIndex; i <= endIndex; i++){
          this.push(dataProvider.valueForIndex(i));
     }
     
     dataProvider.initFinished(this);
};
Series.prototype = new Array();

This first implementation overrides both inherited methods, and generates an arithmetic series.

var arith = new SeriesDataProvider();
arith.valueForIndex = function(i){
      return 1+i*3;
};
var arithSeries = new Series(0, 4, arith); //1, 4, 7, 10, 13

The next implementation overrides both inherited methods, creating a geometric series.

var geo = new SeriesDataProvider();
geo.valueForIndex = function(i){
      return 5+Math.pow(3,i);
};
var geoSeries = new Series(0, 4, geo); //6, 8, 14, 32, 86

This demonstrates how two similar, yet distinct, entities can be created with a minimal amount of new code. And while the example above illustrates a trivial case, the concept can be applied to more practical uses. One such case would be a protocol that works with a list of elements, providing elements for the list and determining behavior for different UI events.

EDIT:
Originally this post said that it was about delegates. That was not correct.

See Also:
Protocol in action.
Javascript Prototype inheritance

Sunday, December 11, 2011

Chamber of the Painted Table


Click Here to interact (Works in Chrome, works better in Safari).

This is the second of my "A Song of Ice and Fire" webkit experiments. The first was a simple animation built using a pretty sweet WYSIWYG. This one is a little more complex. I wanted to experiment with manipulating 3d objects, but didn't want to get bogged down with complicated framework. Webkit-3d transforms seemed like the ticket.

I've create a scene inspired by Aegon the Conqueror's Painted Table. There is a map of westeros on a large table with a spinning dice. Each face has the sigil of a major house on it (all of them involved in Aegon's War of Conquest). I attempted to add floors and walls, but the browser just couldn't handle it. It could be possible to reduce the size of the objects and simply create a smaller scene.

Transforms

To create the objects in the scene square divs are rotated and translated into position, adjusting transform origin where necessary. When transforming shapes within other transformed shapes the -webkit-transform-style attribute must be set to 'preserve-3d', otherwise the transforms will be projected onto the 'surface' of the container as 2d objects. Three containers serve as examples for the different attributes used to position the shapes.

#dice{
 -webkit-transform-style: preserve-3d;
 -webkit-transform-origin: 200px 200px;
 -webkit-transform: rotateX(45deg) rotateY(45deg);
}
#dice_tilt{
 -webkit-transform-style: preserve-3d;
 -webkit-transform-origin: 200px 200px;
 -webkit-transform: rotateY(15deg);
}
#dice_wrapper{
-webkit-transform-origin: 200px 200px;
 -webkit-transform: scaleX(0.3) scaleY(0.3) scaleZ(0.3) translateZ(335px);
}

The dice is rotated on is X and Y axis to make it stand on it point. The dice tilt rotates the dice to one side slightly to allow for a wobbly look, and the dice wrapper is moved above the table and is scaled down to 1/3 normal size.

The animation is based on a ~30 hz timer that updates the rotation of the Dice, and the dice tilt, to create the  the wobbling dice look. The dice_tilt has the inner rotation and the dice wrapper has the wobble (half speed rotation speed) applied to it.

Sprite3d and Matrix Transforms

The Sprite3d class allows the rotation, scale and translation of a div to be set; adjust the transform center, and the transform matrix to be recalculated on request. The class uses the sylvester.js http://sylvester.jcoglan.com/ library to combine the transforms before applying them to the -webkit-transform atribute.

View Change

The rest is simply capturing keyboard input and updating the transform values of the objects. I split rotation x, rotation z, and translation divs, the rotation axis are a little strange if all the transformations are applied to the same function.

Thursday, November 24, 2011

JavaScript OOP - Prototyping Encapsulation and Inheritance

JavaScript is a really cool language. Its flexibility allows a clever developer to achieve some incredible things. However, this unbridled freedom comes at a price. It is the responsibility of the programmer to impose order to this chaotic environment. A good first step in this daunting challenge is to implement some useful object oriented concepts. This post demonstrates how to implement encapsulation and inheritance for javascript prototype classes.

Encapsulation

The fundamental goal for encapsulation is to control what variables/functions are available for external access. The mechanism for doing this in JavaScript is a closure. By wrapping the class definition in a closure it is possible to have private functions accesible only this class, since objects outside of the closure won't be in the same scope.

(function(){
 
 //constructor
 window.JSObject = function(){
  this.publicInstanceVar1 = 1
 }; 

 // public function
 JSObject.prototype.foo = function(){
  privateFunction.apply(this); //call private function
 }; 

 //private function
 function bar(){} 

 var privateClassVar1 = "1"

}());

The constructor must be attached to the window, or declared outside of the closure, otherwise it will not be accessible externally. The public method is added to the object prototype. The private method is a function declared inside of the closure and must be called using apply or call to maintain the consistency the this variable.

Inheritance

Inheritance for a prototype object is very simple. Assigning a new parent object to the prototype of the inheriting object will do the trick.

(function(){
 window.Child = function(){};
 Child.prototype = new Parent();
}());

The instance variables and public functions are now available in the child class. The private methods and private class variables will not be inherited.

Click Here to see a demo.

Sunday, February 13, 2011

What 9000!

If this isn't the wackiest piece of code I've ever written, then it is pretty close. There are three components to the page: a randomly generated grid, the changing letter sizes, and the "awesome song" in the background.

Random Grid

The toughest part was generating the random grid. The grid is made up of two types of components. The grid itself, and the blocks. Each the grids and blocks are have a visual and a data component. The visual components is handled by css,

Grid size

The first step is to determine the number of rows and columns that the grid will have. This is done by taking the ceiling of the quotient of the width or height of the container divided by the height or width of the cell. In this case the cells are 50x50 (40px with 10px of padding). I used the ceiling function rather than the floor because I wanted to fill the screen. Also the number of cells is recalculated on window resize.
$(window).resize(function(){
     hcells = Math.ceil($grid.width()/50); //collumns
     vcells = Math.ceil($grid.height()/50); //rows
}).resize();

Representing grid and shapes

Both the grid and the shapes are represented by 2-dimensional boolean matrices. The grid is initialized so that every cell contains a false value (meaning that grid position is not occupied).
for(i = 0; i < hcells; i++){
     grid.push([]);
     for(j = 0; j < vcells; j++){
          grid[i].push(false);                    
     }
}
Likewise, each of the block shapes has a shape array where the positions occupied by the shape are represented by a true value.
//default shape, single square block 
     oneSquare = {
        shape: [ [true] ],
        className: "oneSquare"
    };
    //three wide by one tall 
    threeXOne = {
        className: "threeXone",            
        shape: [ [true], [true], [true] ]
    };

Placing Blocks

After the grid is initialized, each position is looped through and a block shape is chosen at random. Then the shape array of the block is compared the the grid starting at the current position. The block is placed into the grid if all the positions that will be take up by this shape are unoccupied.
function placeBlock(i, j, shape){              
        //loop over space checking for occupation
        for(x = 0; x < shape.length; x++){
            for(y = 0; y < shape[x].length; y++){
                 if (grid[x + i][y + j] || x+i >= grid.length || y+j >= grid[x+i].length) {                             
                      return false;                              
                  }                                          
            }                                      
        }
        //go back and mark spots as taken up
        for (x = 0; x < shape.length; x++) {
            for (y = 0; y < shape[x].length; y++) {
                grid[x + i][y + j] = true;
            }
        }              
        return true;       
    }
If the function returns true then the block is placed absolutely in the grid using the cell size and i,j coordinates. The process of emptying the grid and filling it with random block is set to repeat 10 times a second. This makes the grid a pretty interesting browser benchmark.

Title

To spice up the title a little bit. I use the lettering.js a jQuery plugin to wrap each of the letters in there own div. Then on an interval the letters are looped through and a random size (within bounds) is chosen for each letter, and it is assigned one of 4 colors;
var colors = ["#0099FF", "#800080", "#0FF000", "#FF0000"];
     function logoDance(){
        $logo.children("span").each(function(){
            randy = Math.random();                 
            $(this).css({
                fontSize: Math.round(randy*150)+75,
                color: colors[Math.floor(4 * randy)]
            });
        });
    }

Audio

The music is played through an HTML audio tag.To get the OGG version of the file I used Firefogg.

Summary

That pretty much covers it. Some arrays operations to create and fill the grid, lettering.js to jazz up the title page, and some quick html audio for the background music.