Mach3.laBlog

細かすぎて伝わらないjQuery拡張 (24) “$.fn.transition” – Advent Calendar 2016

$.fn.transition は、$.fn.animate の様にCSS Transitionを実現する関数です。

$.fn.transition(props, options)

CSS Transition によるアニメーションはJavaScriptによるアニメーションに比べてパフォーマンスが非常によく、綺麗です。 しかし一方で、非対応環境の為に .animate() を使わなければならない事が多いので、 両者で動作するように対応できる関数をしたためてみました。

使い方

// 要素を left: 100 に移動
$(".item").transition({
    left: 100
}, {
    duration: 300, // 所要時間 300ms
    delay: 100, // アニメーション開始までのディレイ 100ms
    easing: "linear" // イージング関数の指定
});

基本的な使い方は .animate() と概ね同じです。

  • 第一引数 : アニメーションするスタイル
  • 第二引数 : オプション

CSS Transition に対応していないレガシーな環境では $.fn.animate で代替しています。 イージング関数名として渡せるのは jQuery.easing の名前ではなく、 CSS Transition で定義されている名前です。(ease | linear | ease-in | ease-out | ease-in-out)

// 要素をアニメーション後、削除
$(".item").transition({
    opacity: 0,
    right: 500
}, {
    done: function(){
        $(this).remove();
    }
});

.animate() 同様に、オプションで done を渡して完了時の処理を実装できます。 .animate() にあるその他多数のオプションは使えません。

また、stop() とかはできません。とまりません。

コード

$.extend($.support, {
    cssTransition: ("transition" in document.createElement("i").style)
});

$.transition = function(props, options){
    var o, transition = [];

    o = $.extend({
        duration: 400,
        delay: 0,
        easing: "ease",
        done: $.noop
    }, options);

    if(! $.support.cssTransition){
        switch(o.easing){
            case "ease": o.easing = "swing";
            case "ease-in": o.easing = "easeInSine";
            case "ease-out": o.easing = "easeOutSine";
            case "ease-in-out": o.easing = "easeInOutSine";
            default: break;
        }
        o.easing = (o.easing in $.easing) ? o.easing : "swing";

        this.stop().delay(o.delay).animate(props, {
            duration: o.duration,
            easing: o.easing,
            done: o.done
        });

        return this;
    }

    $.each(props, function(key, value){
        transition.push(
            [
                key,
                o.duration + "ms",
                o.easing,
                o.delay + "ms"
            ].join(" ")
        );
    });
    transition = transition.join(",");

    this.each(function(){
        var el = $(this),
            done = (function(e){
                o.done.call(this, e);
                $(this).css("transition", "").off("transitionend", done);
            }).bind(this);

        el.css("transition", transition)
        .on("transitionend", done)
        .css(props);

        setTimeout(function(){
            el.trigger("transitionend");
        }, o.duration + 33);
    });

    return this;
};

ベンダープレフィックス無しの “transition” を持たない環境は、使えない物とみなしています。 (面倒だったのもありますが、必要性もあまり感じなかった為)

非対応環境ではイージング関数を jQuery.easing の名前に書き換えています。 といっても、デフォルトで実装されているのは “swing” と “linear” だけなので、 jQuery.easing プラグイン も含めて、近しい物を割り当てています。 こちらも一緒に使う事で表現は豊かになりますが、なければないで、そこらへんが全部 “swing” になるだけです。

完了時の処理に “transitionend” を利用していますが、 これは実際に値が変わってトランジションが発生していないと発火しない代物なので、 時間経過と共に無理やり発火させています。 「アニメーションしないアニメーション」の完了時に何かしたい事なんてないだろうと思いますが、念のため。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*