Brick.js updated!

 先日紹介したBackbone.Viewのクローンであるところの"Brick.js"ですが、コツコツと機能拡張を続け、ひとまず今の形でバージョン0.1としてgithubにアップしました。
 → GitHub - taiyoh/Brick.js: ported from Backbone.View
 改めてBrick.jsについて説明。

目的

 JavaScriptのアプリケーション設計のキモはビューの分離にあり、と感じたので(モデル層書けることは前提ね)、backbone.jsで使われていたBackbone.Viewを取り出してフルスクラッチで実装、独自拡張しました。

機能1(Backbone.Viewと同じところ)
  • コンストラクタ実行時に、elパラメータにHTMLElementを作成して格納する
  • eventsパラメータにて、クラスメソッドをelパラメータ以下の要素の特定のイベント発火にルーティング
機能2(Backbone.Viewと違うところ)
  • configパラメータの削除
    • イマイチ意義を見出せなかったため。使いどころが分かれば実装するかも。
  • jQueryをはじめ、各種ライブラリに対する依存度の抑制
    • このライブラリを動かすのに、CSS SelectorのためにjQueryを使用している以外、jQueryやunderscore.jsの必要な箇所はありません。
  • シンプルなAOP機能
    • 親クラスで定義したメソッドを、子クラスでは、親クラスの実装を変更することなく拡張することができます。下記サンプル参照
  • Brick.create関数により生成したクラスにはextendメソッドを定義
    • 作成したクラスからさらに継承させることができます。下記サンプル参照
  • パラメータのキーの頭に"+"を付けることで、親クラスのパラメータを継承して子クラスで値を上書きできる
    • 下記サンプル参照
  • buildOnInitializeというパラメータを追加。これがfalseの時、自前メソッドによってthis.elのHTMLElementが生成される
サンプル

 主な追加機能を組み合わせると、以下のようなことが可能になります。

// ベースとなるBlockクラスの作成
var Block = Brick.create({
    className : 'block',
    // 表示位置のみ指定
    style: {
        top: '20px',
        left: '50px'
    },
    moving: false,
    events : {
        mouseenter: 'brbr'//this.elで指定した要素のmouseenter発火時、brbrメソッドが実行される
    },
    brbr: function() {
        var self = this;
        if (self.moving) return;
        self.moving = true;
        var el = $(self.el);
        var top = parseInt(el.css('top'), 10);
        var way = [1, -1, 1, -1];
        var scalar = 5;
        (function() {
            var func = arguments.callee;
            setTimeout(function(){
                if (way.length > 0) {
                    var p = way.shift() * scalar;
                    el.css('top', (top + p) + 'px');
                    func();
                }
                else {
                    self.moving = false;
                    el.css('top', top + 'px');
                }
            }, 25);
        })();
    }
});

// Blockクラスを継承したRedBlockクラスを定義
var RedBlock = Block.extend({
    // Blockクラスのstyle情報を引き継いだまま、新たなパラメータを追加
    "+style" : {
        backgroundColor: '#ff0000'
    },
    // 親クラスのメソッドをオーバーライドすることなく、メソッドの機能を拡張
    aspects: {
        // Blockクラスで定義したbrbrメソッドを覆うメソッドを再定義
        "around: brbr": function(orig) {
            var self = this;
            var color = self.el.style.backgroundColor;
            self.el.style.backgroundColor = '#000000';
            orig.apply(self);// 親クラスのbrbrメソッドはここで実行
            setTimeout(function() {
                self.el.style.backgroundColor = color;
            }, 100);
        }
    }
});

$(function() {
    var block = new RedBlock;
    $('body').append(block.el);
});

 これを動作させると、以下のリンクのようになります。
 → http://jsdo.it/ttaiyoh/mWuS
 ものすごい数のパーティクルに適用するのはさすがに厳しいけど、ある程度現実的な個数のオブジェクトを操作するのであれば、これ使うとかなり可読性が増すんじゃないかなぁ。。。