Recent projects 2012-2013

Here are 3 recent projects. The first 2 are purely front-end development work. They have no CMS backend and run on PHP and the Smarty template framework for easier content and template management.

1. La Jolla Playhouse WOW Festival

Twitter Bootstrap is the main framework used. Instead of using the default LESS source files from bootstrap, I used the Bootstrap SASS library instead and modified it. This site is responsive, meaning that visual elements transform to fit the screens in mobile, tablet or desktop.

2. Blend

This site is done using JQuery Mobile. The site runs like a web app without the need for page refresh in supported browsers.

3. On the rocs lounge

The last project is the re-launch of the On the Rocs lounge site. Though the rest of the site is great, I am only responsible for the a splash animation. There is a door in the restaurant where their restaurant’s initials were gunshot on.  With the relaunch, they wanted to recreate how this happened online, hence my part in this project. First, I obtained a couple of frames of a single gunshot. Then, I coded the sequence in Flash using ActionScript. After the client approved and some more polishing, I exported the full sequence into an animation strip which then I used JavaScript to animate to synchronize with the audio.

Reading “Pro JavaScript Design Patterns”

I am reading “Pro JavaScript Design Patterns” by Harmes and Diaz. This book is very good for intermediate to expert level JavaScript programmers, especially for tech leads. The book covers enterprise-level (Java) programming practices in JavaScript. There are many techniques worth knowing in JavaScript. If you are a seasoned web front-end developer, you may know a lot of these technique already.

Things I like about this book:

  • not written for specific JS framework (jQuery, prototype..etc).
  • explains some of the essential concepts in JavaScript clearly
  • goes over different design patterns one by one
  • examples are easy to follow

That’s all for now. 🙂

Trick JavaScript Interview questions

We were asked some tricky JavaScript questions that Alex(the lead) used in interviews for the internship position. Here are some of them:

Question 1:

//What is i?
var i=0;
var add = function(){
 ++i;
    return function(){
        i++;
        return function(){
            i++;
            add();
        }
    }
};
add()()();

Question 2:

//What is the value and data type of result?
var result = !!String("false");

Question 3:

//What is result?
var result = "1"+2+4;

Question 4:

//What is 'result' and why?
var result = (function foo(bar){
 return !bar;
}(false)? false: true);

Answers:
1) 4
2) true, boolean
3) 124
4) false

Just for fun – Add Konami Command (secret code) for your site.

Wrote something extremely stupid – a Konami secret code handler.  You can try it on my site. http://www.jonycmusic.com/ (Up-Up-Down-Down-Left-Right-Left-Right-B-A)

Code source: http://jsfiddle.net/jonyc/8XSaS/4/

/*
*  
*  AUTHOR: Jonathan Cheung
*  KonamiCodeTrigger.js
*
*/
var KonamiCodeTrigger = (function() {
    // Saves the returned API
    var self;
    // Key History
    var keyCodeHistory = [];
    // All the triggers are stored in an Array;
    var __triggers = [];
    // Constants
    var Key = {
        UP: 38,
        DOWN: 40,
        LEFT: 37,
        RIGHT: 39,
        ESCAPE: 27,
        a: 97,
        b: 98,
        A: 65,
        B: 66
    };

    // Here we store the winning Combinations..
    // The default is Up-Up-Down-Down-Left-Right-Left-Right-B-A / Up-Up-Down-Down-Left-Right-Left-Right-b-a
    var winningCombos = [
        String("" + Key.UP + Key.UP + Key.DOWN + Key.DOWN + Key.LEFT + Key.RIGHT + Key.LEFT + Key.RIGHT + Key.b + Key.a),
        String("" + Key.UP + Key.UP + Key.DOWN + Key.DOWN + Key.LEFT + Key.RIGHT + Key.LEFT + Key.RIGHT + Key.B + Key.A)
        ];

    //Let's save the original
    var originalKeyPress;
    if (document && document.onkeypress) {
        originalKeyPress = document.onkeypress;
    }

    document.onkeypress = function(evt) {
        var keyCode = Number(evt.keyCode);
        var charCode = Number(evt.charCode);
        
        //Process keyCode
        switch (keyCode) {
        case 0:
            break;
        case Key.ESCAPE:
            //Reset the history if ESC is pressed
            keyCodeHistory = [];
            window.scrollTo(0, 0);
            break;
        default:
            keyCodeHistory.push(Number(evt.keyCode));
            break;
        }
        //Process charCode
        switch (charCode) {
        case 0:
            break;
        default:
            keyCodeHistory.push(charCode);
            // Here's where we find out if the Konami code existed
            if (winningCombos.indexOf(keyCodeHistory.join("")) != -1) {
                __triggers.forEach(function(item, index) {
                    (typeof(item) == 'function') && item();
                });
            }
            break;
        }
        //Call our original keypress if it was there
        originalKeyPress && originalKeyPress(arguments);
    };
    
    return self={
        /*
         *  addTrigger()
         *  Adds a function to the callback stack.
         *  @callback {function} - The callback function you want to add
        */
        addTrigger: function(callback) {
            __triggers.push(callback);
        },
        /*
         *  removeTrigger()
         *  Removes a function from the callback stack.
         *  @callback {function} - The callback function you want to remove
        */
        removeTrigger: function(callback) {
            __triggers = __triggers.filter(function(item, index) {
                return item != callback;
            });
        },
        /*
         *   clearCombo()
         *   Clears the combo being used.
         *   @no prarameteres
         */
        clearCombo: function() {
            winningCombos = [];
        },
        /*
         *   addCombo()
         *   Adds a combo into the trigger. We can have multiple key combo to trigger the callback functions.
         *   @combo {string} - The string you want to use e.g. KonamiCodeTrigger.Key.A + KonamiCodeTrigger.Key.B
         */
        addCombo: function(combo) {
            winningCombos.push(String("" + combo));
        },
        /*
         *   removeCombo()
         *   Removes a combo.
         *   @combo {string} - The string you want to remove e.g. KonamiCodeTrigger.Key.A + KonamiCodeTrigger.Key.B
          */
        removeCombo: function(combo) {
            winningCombos = winningCombos.filter(function(item, index) {
                return item != String("" + combo);
            });
        },
        /*
         *   Key {}
         *   These are key constants.. You can add more to the Key costants above. Right now, only UP, DOWN, LEFT,RIGHT,A,B,a,b are in the constants as they are in the *original* Konami combo.
        */
        Key:Key
    }
})();

You can add more callback functions like this:

/* Put this guy in your onload */
KonamiCodeTrigger.addTrigger(function() {
    alert("BINGO! Now we do something interesting!");
});

And you can clear the original combo and add your own combo this way. (You need to assign the ‘Key’ object has the keyboard key mappings you want.)

//KonamiCodeTrigger.clearCombo();
KonamiCodeTrigger.addCombo("" + KonamiCodeTrigger.Key.A + KonamiCodeTrigger.Key.B);