何かしらのオブジェクト(例えば写真)を任意の場所に整列させたい時、以下の様なコード(class)で実現出来る。
基準になる座標を一つ決めてそこに整列させている。

var Animated = Class.create({
    initialize: function(elems, line) {
        this.timeId;
        this.elems = elems;
        this.line = line;
        document.observe('dom:loaded', this.move.bindAsEventListener(this));
    },
    
    move: function(event) {
        if (this.timeId) clearInterval(this.timeId);

        var xPos = (event.pointerX() > parseInt(this.elems[0].getStyle('left')))? true : false;
        var yPos = (event.pointerY() > parseInt(this.elems[0].getStyle('top')))? true : false;

        var that = this;
        var currentTop = 0;
        var currentLeft = 0;
        var prevTop;
        var prevLeft;
        var stopped = false;
        
        this.timeId = setInterval(function() {
            var left;
            var top;
            prevTop = currentTop;
            prevLeft = currentLeft;
            for (var i = 0; i < that.elems.length; i++) {
                if (i == 0) {
                    left = event.pointerX();
                    top = event.pointerY();
                } else {
                    if (i % that.line == 0) {
                        left = event.pointerX();
                        top = parseInt(that.elems[i-1].getStyle('top')) + parseInt(that.elems[i-1].getStyle('height')) + 17;
                    } else {
                        left = parseInt(that.elems[i-1].getStyle('left')) + parseInt(that.elems[i-1].getStyle('width')) + 17;
                        top = parseInt(that.elems[i-1].getStyle('top'));
                    }
                }
                left = parseInt(that.elems[i].getStyle('left')) + ((left - parseInt(that.elems[i].getStyle('left'))) / 4);
                top = parseInt(that.elems[i].getStyle('top')) + ((top - parseInt(that.elems[i].getStyle('top'))) / 4);
                that.elems[i].setStyle({
                    left: (xPos? Math.ceil(left) : Math.floor(left)) + 'px',
                    top: (yPos? Math.ceil(top) : Math.floor(top)) + 'px',
                    opacity: Math.random()
                });
                if (i == that.elems.length - 1) {
                    currentTop = top;
                    currentLeft = left;
                }
            }
            if (stopped) {
                clearInterval(that.timeId);
                for (var i = 0; i < that.elems.length; i++) {
                    that.elems[i].setStyle({opacity: 1.0});
                }
            }
            if (currentLeft == prevLeft && currentTop == prevTop) {
                stopped = true;
            }
        }, 15);
    }
});

上のようなクラスを定義した後

Event.observe(window, 'load', function(event) {
    var anim = new Animated($$('img'), 5);
});

等として呼びだせばいい
コンストラクタには引数としてアニメーションさせたいオブジェクトの塊と一列に何枚(写真を)表示させたいかの数値を渡している。
この手のスクリプトはタイマーオブジェクトを使って実現させる事が多いがそのタイマーをクリアさせる為に'currentTop'や'prevTop'という変数の値をチェックしている。
上のコードだとクラスの中で

document.observe('dom:loaded', this.move.bindAsEventListener(this))

としているが、これを消して呼び出し側で

Event.observe(window, 'load', function(event) {
    var anim = new Animated($$('img'), 5);
    document.observe('click', anim.move.bind(anim)); //ここで呼び出す
});

としてもいい。
そうする事でイベントの種類を(例えばクリックなのかマウスオーバーなのか)クラス内のコードを変更せずに呼び出し側で変える事が出来る

実際このページがサンプルになっていて、ドキュメント内の任意の場所をクリックするといきなり写真が何処からともなくやってきて徐々に整列をしていく
その時タイマーがクリアされたのがはっきり分かるように動いている間は写真の透明度がランダムに変化するが動きが止まったら不透明な写真に戻るようになっている。

CIMG1023 CIMG1312 CIMG1397 CIMG2167 CIMG2393 CIMG2683 CIMG3128 CIMG3141 DSCF0002 DSCF0004 DSCF0006 DSCF0010 DSCF0011 DSCF0031 DSCF0039 IMG_0013 IMG_0045 IMG_0051 IMG_0086 IMG_0116 IMG_0148 IMG_0152 IMG_0153 IMG_0230 IMG_0440

カテゴリ:

トラックバック(0)

トラックバックURL: http://blog.beanz-net.jp/beanz_mtos/mt-tb.cgi/73

コメントする