animate() の easing の定義方法
.animate()
で指定する easing 関数は、
アニメーションの開始地点から目的地点までの進み方を定義します。
指定方法は
こちら
に記録したので、ここでは独自に easing 関数を
定義する方法とその注意点を記録しようと思います。
主に jQuery 1.9.1 を使って調べたので、他のバージョンでは 当てはまらないことがあるかもしれませんのでご注意下さい。 長い間変わっていないようですが、 たぶん公式にはドキュメント化されていません。 その点は留意して下さい。
※jQuery Migrate プラグインの方針に沿うように記事を変更しました。
easing 関数の定義方法
easing 関数は以下のように
jQuery.easing
オブジェクトに定義します。
// myEasing という名前の easing 関数を定義
$.easing["myEasing"] = function(p){
// 数値を返す
};
// こっちでもよい
$.extend( $.easing, {
myEasing: function(p){
// 数値を返す
}
});
この時、jQuery.easing
オブジェクトの
プロパティ名が easing 関数の名前になります。
.animate()
で指定する時はこの名前を使います。
// 定義時のプロパティ名を指定する
$( element ).animate({ marginLeft: "+=100px" }, 400, "myEasing");
// または
$( element ).animate({ marginLeft: "+=100px" },
{ easing: "myEasing" } );
リストに戻る
easing 関数への引数
今のところ、easing 関数には5つの引数が渡されていますが、
引数を2つ以上取るようにすると jQuery Migrate プラグインから警告され
"linear"
に変更されてしまうため、引数は第1引数(p)だけにして
第2引数以降は使わないようにした方が無難です。
- p
- アニメーションの進捗状況を表す 0 から 1 の間の数値。 0 が開始時点で 1 が終了時点。
- t
- アニメーション開始時から現在までの経過時間。ミリ秒単位。 1.8 から整数ではなくなった。
- s
- 常に
0
- e
- 常に
1
- d
-
.animate()
で指定した duration の値。
easing 関数の返り値
アニメーションするプロパティの値は easing 関数の返り値をもとに決定されます。そのため、 easing 関数の返り値は数値になるようにします。 その返り値を使って、以下のような式で アニメーションするプロパティの値が決定されています。
now = ( end - start ) * eased + start;
// now ... アニメーションするプロパティの値
// end ... .animate() で指定したプロパティの目的値
// start ... アニメーション開始時のプロパティの値
// eased ... easing 関数の返り値
eased が0
なら now は
start になり、eased が1
なら now は
end になります。
つまり、easing 関数の返り値は、
アニメーション開始時のプロパティの値を0
、
.animate()
で指定したプロパティの値を
1
とした場合の割合の値になります。
マイナスの値や1
以上の値も返すことができます。
例えば、marginLeft
プロパティを100
から
200
ピクセルにアニメーションする場合、
指定した easing 関数がある時点で0.5
を返せば
その時点でのプロパティの値は150
になり、
他の時点で1.5
を返せば250
になり、
また別の時点で-1.5
を返せば
-50
になります。
jQuery 1.7 まではアニメーションの完了時点で easing 関数が
目的値以外の値(つまり1
以外の値)を
返してもプロパティの値に反映されず
.animate()
で指定した目的値が設定されますが、
1.8 以降では完了時点でも
easing 関数の返り値が反映されるようになりました。
step 関数や progress 関数との比較
同じようにアニメーションをカスタマイズできる
.animate()
のオプション、step と
progress(1.8以降) との違いについて記録しておきます。
実行順序
easing 関数 → step 関数 → (プロパティ更新) → progress 関数という実行順序になります。そのため、 easing 関数での変更結果は step 関数や progress 関数で 変更することができます。
リストに戻るプロパティごとに指定可能
easing 関数はプロパティごとに指定できます。step 関数と
progress 関数は.animate()
ごとにしか
指定できません。
あらかじめjQuery.easing
に登録する必要がある
step 関数や progress 関数は.animate()
を呼ぶ時点で
関数オブジェクトを指定することができますが、
easing 関数の場合はあらかじめjQuery.easing
に
登録しておいてから.animate()
でその名前を
文字列で指定します。
また、jQuery.easing
オブジェクトは全ての
.animate()
で共有します。
そのため、
「この.animate()
の呼び出しだけにちょっとした
独自の easing 関数を作って使いたいな」
というような用途には不向きです。(※
easing 関数を関数オブジェクトで指定できるようになる
プラグイン
もあります)
// easing
$( elem ).animate({ top: ["100px", "myEasing"] }); // 名前で指定
// step, progress
$( elem ).animate({ top: "100px" },
{
step: function( now, tween ){
// 関数オブジェクトで指定可能
},
progress: function( anim, percent, remaining ){
// 関数オブジェクトで指定可能
}
});
リストに戻る
実行中の情報は時間のみ
easing 関数は進捗状況(第1引数)と経過時間(第2引数)、
継続時間(duration、第5引数)は引数から知ることができますが、
移動距離(開始値や目的値)や対象要素、対象プロパティなどを
知ることができませんし、jQuery.easing
に
あらかじめ登録して.animate()
で共用するため
クロージャで情報を渡すにも向いていません。
一方、step 関数や progress 関数は それらの情報を取得でき、関数オブジェクトを指定するため クロージャで情報を追加することもできます。
// step, progress は様々な情報にアクセス可能
var info = { otherElem: $( otherElem ) };
$( elem ).animate({ top: "100px" },
{
step: function( now, tween ){
// this は 対象要素
// tween には様々な情報(プロパティ名,
// 開始値, 目的値, 単位 など)が入る
var elem = info.otherElem;
},
progress: function( anim, percent, remaining ){
// this は 対象要素
// anim には様々な情報(tweens プロパティから
// Tween オブジェクトを取得できる)が入る
var elem = info.otherElem;
}
});
リストに戻る
対象プロパティの値以外に干渉できない
上の通り取得できる情報は数値のみのため、 easing 関数の返り値でしかアニメーションに影響を 及ぼすことができません。つまり、対象プロパティの値にしか 干渉できません。step 関数や progress 関数は対象要素に アクセスできるので対象プロパティ以外のプロパティの値を 変更することができます。
リストに戻るまとめ
easing 関数で 時間に対するプロパティの値を割合で返す以外のことを行うのは 難しいでしょう。 つまり、開始地点から目的地点までの進み方についての カスタマイズには適していますが、それ以上の アニメーションの細かい挙動をカスタマイズしたい場合は step 関数や progress 関数を利用するようにした方がいいと思います。