jQueryのプラグインを作る

今さらながらjQueryにハマっている。このライブラリは分かりやすくて、とにかく簡単に使えるのが魅力だが、プラグインも簡単に自作できる。この拡張性も人気の秘訣なのだろう。この人気っぷりにも頷ける。

jQueryにメソッドを追加するには、extendを使う方法と、jQueryオブジェクトに直接関数をセットする方法があるようだ。

//直接拡張
jQuery.fn.hoge = function(config){ window.alert(this); return this };

// extendで拡張
jQuery.fn.extend({ fuga: function(config){ window.alert(this); return this } });

値を取得するためのメソッドでなければ、メソッドチェインのためにthisをreturnするのがjQueryの作法。

ためしに画像に反射効果を加えるreflectメソッドを追加するjQueryプラグインを作ってみた。こんなプラグインは既に誰かが作ってると思うけどサンプルコードなので気にしない。SafariFirefoxしか試していないので、たぶん動かないブラウザもあると思う。

(function() {
  jQuery.fn.reflect = function (setting) {
    var config = jQuery.extend({}, setting);
    var me = this;

    me.each(function(){
        if (this instanceof HTMLImageElement) {
            $(this).load(function() {
                var canvas = document.createElement('canvas');
                canvas.height = this.height / 3;
                canvas.width = this.width;

                var c = canvas.getContext('2d');
                c.save();
                c.translate(0, this.height);
                c.scale(1,-1);
                c.drawImage(this, 0, 0, this.width, this.height);
                c.restore();
            
                var g = c.createLinearGradient(0, 0, 0, this.height / 3);
                g.addColorStop(1, "rgba(0, 0, 0, 1.0)");
                g.addColorStop(0, "rgba(0, 0, 0, 0.2)");
            
                c.fillStyle = g;
                c.globalCompositeOperation = "xor";
                c.fillRect(0, 0, this.width, this.height / 3);
            
                var offset = $(this).offset();
                canvas.style.position = "absolute";
                canvas.style.left = offset.left + "px";
                canvas.style.top = offset.top + this.height - 1 + "px";
                var parent = this.parentNode;
                parent.appendChild(canvas);
            });
        }
    });
    return this;
  };
})(jQuery);
$(function(){ $("img.hoge").reflect() }

実際に使ってみるとこんな感じ

ところでFirefoxCanvasではrgbaによる半透明の指定が使えるのに、CSSで使えないのだな。何か納得できん…。