Personal tools
You are here: Home ブログ 井上 animator.jsの使い方
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
Apache2.4のリリース予定は来年(2011年)初め(あくまで予定) inoue 2010-12-23
Herokuの発音 inoue 2010-12-20
雑誌記事「ソフトウェア・テストPRESS Vol.9」の原稿公開 inoue 2010-12-18
IPA未踏のニュース inoue 2010-12-15
労基法とチキンゲーム inoue 2010-12-06
フロントエンドエンジニア inoue 2010-12-03
ASCII.technologies誌にMapReduceの記事を書きました inoue 2010-11-25
技術評論社パーフェクトシリーズ絶賛発売中 inoue 2010-11-24
雑誌連載「Emacsのトラノマキ」の原稿(part8)公開 inoue 2010-11-22
RESTの当惑 inoue 2010-11-22
「プログラマのためのUXチートシート」を作りました inoue 2010-11-19
「ビューティフルコード」を読みました inoue 2010-11-16
Categories
カテゴリなし
 
Document Actions

animator.jsの使い方

最近はアリエルの若きJavaScriptマスターの後を追いかけてばかりです。先日、animator.jsを教えてもらいました。他のJavaScriptライブラリより良くできていると思います。

以前、scriptaculousで須崎メソッドを実装しました(http://dev.ariel-networks.com/Members/inoue/suzaki-method)。結局、scriptaculousをAirOneの配布に含めていないので、須崎メソッドは動いていません。今回、animator.jsで再実装しました。今度は、次のメジャーリリースに入ります。

簡単な例を使ってanimator.jsの使い方を説明します。

次のようなbody要素のHTMLを考えます。id="target"の要素を上下に振動させます。

<body onload="init();">
<div style='position:absolute; top:200px'>---200---</div>  
<div id="target">moving...</div>
</body>

magic numberが多いですが、最も簡単なコードは次のようになります。

var t = $('target');
t.style.position = 'absolute';
t.style.top = '200px';
var anim = new Animator({duration: 4000, interval:40, transition: Animator.tx.linear});
anim.addSubject(function (v) { var h = 200 + Math.round(100 * Math.sin(v * 2*Math.PI)); t.style.top = h + 'px';});
anim.play();

最初に、id="target"の要素のpositionスタイルをabsoluteにします。上下に振動させるためにすべきことは、タイマーでt.style.topの値を変更することです。

duration:4000はアニメの長さです(単位はミリ秒)。interval:40はアニメの間隔です(同じく単位はミリ秒)。つまり、上の設定では40msごとのタイマーイベントが100回起きて、4秒すると止まります。

animator.jsの基本は、タイマーのイベントハンドラに、0から1の間の値を取る数値(以下、カウンタ)が渡ることです。transition:Animator.tx.linearの設定で、カウンタが線形に増えます。つまり、イベント回数が100回なので、0.01ずつカウンタが増えます。イベントハンドラは、0,0.01,0.02,0.03,...,0.98,0.99,1のカウンタを受け取ります(後述するイベントハンドラの引数のvの値)。

addSubject()でイベントハンドラを渡します。振動させるためにsin()を使います。1周期の動きをさせるには、0から2πの値を取ればよいので、"v * 2*Math.PI"をsin()に渡します(カウンタvは0から1の間の値)。100は振幅です。高さ200pxを中心に振動させているので200を足して、最後にt.style.topに値をセットします。以下、このコードを改造していきます。

scriptaculousのコードを見ると、prototype.jsのmakePositioned()を使っています。t.style.position = 'absolute';を置き換えられそうなので、次のようにします(以下、この3行は省略)。

var t = $('target');
t.makePositioned();
t.style.top = '200px';

animator.jsのtransitionはいわばカウンタのgeneratorです。上の例のようにAnimator.tx.linearを使ってカウンタを線形にして、イベントハンドラのみを考えるのもひとつの手です。次のように、カウンタそのものの値の範囲を2πの単位で考えることもできます。

var anim = new Animator({duration: 4000, interval:40, transition: function(n){ return n * 2*Math.PI;}});
anim.addSubject(function (v) { var h = 200 + Math.round(100 * Math.sin(v)); t.style.top = h + 'px'; });
anim.play();

以下、Animator.tx.linearに話を戻します。

sin()に渡す数値の範囲を0から8πにすれば4往復します。更に、線形に1から0まで減少する数値をかけると、減衰する振動になります。コードは次のようになります。

var anim = new Animator({duration: 4000, interval:40, transition: Animator.tx.linear});
anim.addSubject(function (v) { var h = 200 + (1-v) * Math.round(100 * Math.sin(v * 8*Math.PI)); t.style.top = h + 'px';});
anim.play();

基本の動きはできました。微妙に気持ち悪いのがイベントハンドラのt(id="target"要素)への依存です。こういう場合、JavaScriptでは、次のようにクロージャを使うのが定石です。

var anim = new Animator({duration: 4000, interval:40, transition: Animator.tx.linear});
var makefn = function(elm, base) { return function(v) { var h = base + (1-v) * Math.round(100 * Math.sin(v * 8*Math.PI)); elm.style.top = h + 'px';} };
anim.addSubject(makefn(t, parseInt(t.style.top)));
anim.play();

makefnは作ってすぐに使うだけなので、こういう場合、名前をつけずに呼ぶ方がJavaScript風です(以下のコード、単にmakefnを無くしただけです)。

var anim = new Animator({duration: 4000, interval:40, transition: Animator.tx.linear});
anim.addSubject((function(elm, base) { return function(v) { var h = base + (1-v) * Math.round(100 * Math.sin(v * 8*Math.PI)); elm.style.top = h + 'px';} })(t, parseInt(t.style.top)));
anim.play();

振幅の100はハードコードのまま残っています。気持ち悪ければこれも引数にできます。

ここまで来ると、実は次のように1行にもできてしまいます。

(new Animator({duration: 4000, interval:40, transition: Animator.tx.linear})).addSubject((function(elm, base) { return function(v) { var h = base + (1-v) * Math.round(100 * Math.sin(v * 8*Math.PI)); elm.style.top = h + 'px';} })(t, parseInt(t.style.top))).play();

もっとも、これはやりすぎでしょう。可読性の観点からお勧めできません。

animator.jsは実はもっとすごいことができます。次のようなコードを書き足すと、背景色が徐々に変化します。

anim.addSubject(new CSSStyleSubject(t, "background-color:#ff0000", "background-color:#0000ff"));
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/animator-js-usage/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.