A Day in the Life

JavaScript での easing 関数を使ったトィーンアニメーションの基礎

JavaScript での easing 関数を使ったトィーンアニメーションの基礎

のエントリーを読んで、JS で特定時間の間隔でモーション・アニメーションしたい場合の easing 関数の基礎の話をちょっと。Flash などの Web のアニメーションでは、Penner さんが考えた easing 関数が広く使われていて、解説や実装が公開されている。

easing 関数はざっくりというと

  • 動き始めてから何秒たったか
  • 最初の値
  • 変動する値
  • 完了までの秒数

を引数として与えれば、その時間に応じた値を返してくれる、という関数。追記・c は最後の値ではなく変動値でした。すいません…。tsukkeeさんありがとうございますコードに落とすとこんな感じ

// 0 =< t =< d のとき
function(t, b, c, d) {};
t = 現在秒 (現在
b = 最初の値
c = 変動する値
d = 何秒かけて動くか

で、例えば直線的な動きは

function(t, b, c, d) { 
  return c * t / d + b; 
}

な関数で表現できる。これのパターン関数がたくさんあり、自前で実装することもできるし、penner さんが作った関数を元に利用するのも良いし、誰かが公開しているのを利用するのも良い。

この easing 関数を利用するためのコードだけど、理解してればすぐスクラッチで書ける。

var easing = function(t, b, c, d) { 
  return c * t / d + b; 
};

var now = ((new Date()) * 1);
var b = 0; // 最初の値
var c = 100; // 変動する値
var d = 3; // 何秒かけてアニメーションするか
var wait = 100;
var motion = (function() {
  var t = (((new Date()) * 1) - now) / 1000;
  var value = easing(t, b, c, d);
  document.body.style.fontSize = '' + Math.round(value) + 'px';
  if (value < c) return setTimeout(arguments.callee, wait); 
})();

ブックマークレット化したのが以下。google の検索結果などのページで実行すると効果が解ると思う。

javascript:(function(){var%20easing=function(t,b,c,d){return%20c*t/d+b;};var%20now=((new%20Date())*1);var%20b=0;var%20c=100;var%20d=3;var%20wait=100;var%20motion=(function(){var%20t=(((new%20Date())*1)-now)/1000;var%20value=easing(t,b,c,d);document.body.style.fontSize=''+Math.round(value)+'px';if(valueで、この easing 関数を差し替えると、モーションに変化を与えることができる// OutBounce
var easing = function(t, b, c, d) {
    if((t/=d) <(1/2.75)) {
        return c*(7.5625*t*t) + b;
    } else if(t <(2/2.75)) {
        return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if(t <(2.5/2.75)) {
        return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
};
この easing 関数で作ったブックマークレットが以下。IE だと文字数的に動かないかも。javascript:(function(){var%20easing=function(t,b,c,d){if((t/=d)<(1/2.75)){return%20c*(7.5625*t*t)+b;}else%20if(t<(2/2.75)){return%20c*(7.5625*(t-=(1.5/2.75))*t+.75)+b;}else%20if(t<(2.5/2.75)){return%20c*(7.5625*(t-=(2.25/2.75))*t+.9375)+b;}else{return%20c*(7.5625*(t-=(2.625/2.75))*t+.984375)+b;}};var%20now=((new%20Date())*1);var%20b=0;var%20c=100;var%20d=3;var%20wait=100;var%20motion=(function(){var%20t=(((new%20Date())*1)-now)/1000;var%20value=easing(t,b,c,d);document.body.style.fontSize=''+Math.round(value)+'px';if(valueeasing 関数を差し替えられるコードにしておくと、様々な easing 関数を利用できたり、広く知られている easing 関数を使うため汎用性が増す。で、JS でこの easing 関数を使ったライブラリとしては os0x さん作の
  http://d.hatena.ne.jp/os0x/20080929/1222685721http://gist.github.com/13572
 を使うと、20行程度のコードですむので、自分の作っている物に組み込むのには便利。また JSTweener という Tweener (as3 のモーショントィーンライブラリ) 互換のライブラリを使うと、標準で様々な easing 関数が利用できたり、タイマーが一つなので、数百, 数千オブジェクトをモーションさせるときにはだいぶ高速になる。
  http://coderepos.org/share/wiki/JSTweener
 また JSTweener のコードには、Tweener から JavaScript へと移植した easing 関数が含まれているので、コピペ利用に便利。
  そうだ最初は piro たんのエントリー読んで、xpcom の API で、どれだけ負荷がかかっているか調べられる API ってないのかなー、と思ってエントリー書いたつもりがなぜか easing 関数の話になってしまったのでした…。Firefox 拡張で wait を挟みたい処理の場合、クライアントの処理速度にあわせたいけど、そういう指針となる物ないのかなぁ、と思っていた物で
記事の一覧 >