JavascriptアニメーションライブラリTween.jsの紹介
お久しぶりです。
マークアップエンジニアの、だってぃです。
すっかり秋ですね・・・というかもうなんか冬っぽさ出てきてますね。
過ごしやすい季節なんて、あっという間に過ぎ去っていきますね。
僕も35年ほど生きてますから、四季の罠には気付いてますよ、ええ。
春・夏・秋・冬が3か月均等になんてなってないって事にね。
4月中旬~5月中旬 :過ごしやすい。春。
5月下旬~9月中旬 :なんか暑い。夏だ、夏。
9月下旬~10月下旬:過ごしやすい。秋。
11月~4月上旬 :なんか寒い。冬だ、冬。
これが本当の春夏秋冬ですね。これだよ、これ。
・・・(・3・)・・・・・・・・
さてさて、本日はJavascriptアニメーション。
CSS3な時代が到来してから、CSSでも割とお手軽にアニメーションを実装できるようになりましたね。
でも!・・・でもですね。
CSSで複雑なアニメーションをつくろうとすると割と大変なんです。
ソースが煩雑になるし、やれ-webkit-やら-moz-やら、なんか色々つけなきゃいけないし、可読性に欠けるし、何やってるのか伝わりにくいし、更新性が・・・mgmg・・・
grunt(最近はgulpだって?そうですかぁ・・・(遠い目))等、つかって自動的にベンダープレフィックスつけるとかすれば、割とマシになりますが、まぁこの際、それは置いておこう。
みんなgrunt使っているよね的な思いが、僕らの思考を停止していくのです。よくない。
というわけで、今回はJavascriptアニメーションのライブラリ、世の中にある数多のJavascriptアニメーションのライブラリからtween.jsを紹介します。
目次
tween.jsの特徴
tween.jsは、まずなんといっても軽い。
圧縮版で、6KB!!!!
この軽さはスマホで採用しやすいですね。
そして、IE8でも動く!(※ちょっとした裏技を併用します。それはのちほど…)
これも中々高ポイントです。
jquery等の他のライブラリに依存してないってのも、素敵です。
もちろんjqueryとの併用も全く問題ありません。
対応ブラウザ
- IE8:△※
- IE9:○
- Chrome:○
- Firefox:○
- iOS8:○
- Android2.3:○
- Android4:○
※IE8では、stopメソッドを使用するとエラーになります。
使用したい場合は後述の「IE8でstopを使いたい」参照。
tween.jsの使いかた
こんな感じのものが比較的簡単に実装できちゃいます。
その1:データをダウンロード
https://github.com/sole/tween.js/
まずはダウンロードですね。上記のサイトの、右カラム一番下「Download ZIP」からデータをダウンロードします。
※githubに登録している人は、クローンするのでもいいですね。というか、その方がいいですね。
ダウンロードしたフォルダ内のbuild/tween.min.jsが、このjsの実体です。
それともう一つ、examples/js/RequestAnimationFrame.jsも必要です。
この2つのjsを使用するjsフォルダに入れておきましょう。
その2:HTML・CSSを用意
jsが用意できたところで、まずはHTML・CSSを用意しましょう。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[sourcecode lang="html"] <ul class="btn"> <li><button id="move1">#anim1動かす</button></li> <li><button id="stop1">#anim1止める</button></li> </ul> <div class="animArea"> <div class="anim" id="anim1">#anim1</div> </div> <script src="js/RequestAnimationFrame.js"></script> <script src="js/tween.min.js"></script> <script> ★ここに実際に動かすためのjsを書いていきます。★ </script> [/sourcecode] |
CSS
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 32 33 34 35 |
[sourcecode lang="css"] .btn{ margin-bottom:20px; } .btn:after{ content:''; clear:both; display:block; } .btn li{ float:left; margin-right:10px; } .animArea{ position:relative; height:100px; width:500px; margin-bottom:30px; border:2px solid #cccccc; background:#f6f6f6; } .anim{ position:absolute; width:60px; height:60px; padding:10px; color:#ffffff; font-weight:bold; } #anim1{ top:10px; left:10px; background:#234ac9; } [/sourcecode] |
まぁこの辺は適当に。
tween.jsを理解するためのデモなので、とりあえずな感じで。
その3:Javascriptの記述
さていよいよ本題のJavascript。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
[sourcecode lang="javascript"] //アニメーションの実行というか定義というか… //tween.jsを動かすために必要な宣言 var animate = function(){ requestAnimationFrame(animate); TWEEN.update(); } animate(); //使用する各DOMを取得 var move1 = document.getElementById('move1'); var anim1 = document.getElementById('anim1'); var stop1 = document.getElementById('stop1'); //スコープに関係なく扱えるようにできるため、ここで宣言。 var tw1; //#anim1動かすボタンを押したときの挙動 move1.onclick = function(){ animFunc1(); } //#anim1の動作用の関数 var animFunc1 = function(){ //スタート時の初期値 var pos = { x : 10 } //tweenの動きを定義 tw1 = new TWEEN.Tween(pos) //2000ミリ秒後にどうなってるか。 //この場合初期値10から410に変化する .to({ x: 410 }, 2000)※① //処理遅延の指定。指定したミリ秒後に実行される .delay(500) //イージングの指定。種類は色々あります。 //js本体のソースを見るのが早そう。 .easing(TWEEN.Easing.Bounce.InOut) //tweenがアップデートされるたびに呼び出される .onUpdate(function() { //#anim1のstyleを書き換え※② anim1.style.left = this.x + 'px'; }) //アニメーションが終わった時の挙動。 //ここでは初期位置に戻すようにしてある。 .onComplete(function(){ anim1.style.left = '10px'; }); //tweenをスタートさせる。他と同じように上に連結させても良い。 tw1.start(); } //#anim1止めるボタンを押したとき stop1.onclick = function(){ //tweenを止める tw1.stop(); } [/sourcecode] |
ここでのポイントは※②の部分です。
onUpdate内で行われる処理。
ここでアニメーションさせる実際の処理をいれています。
ここでいうthisというのは、
1 2 3 |
[sourcecode lang="javascript"] tw1 = new TWEEN.Tween(pos) [/sourcecode] |
のposにあたる部分
です。つまり
1 2 3 |
[sourcecode lang="javascript"] var pos = { x : 10 } [/sourcecode] |
で宣言されている
1 2 3 |
[sourcecode lang="javascript"] { x : 10 } [/sourcecode] |
というオブジェクトですね。
このxの値10が※①で指定されたミリ秒数(2000)後に、指定された値(410)に徐々に変化するようにしていくというのがこのjsです。
onUpdateは2000ミリ秒後まで、定期的に何度も実行されます。
実行されるたびに#anim1のstyle属性のleft値を書き替えているために、アニメーションされているということです。
デバック系のツールを使って※②にconsole.log(this)やれば、どういうことが起きているのかわかりやすいですね。
ここが分かれば、もう使えます。
onUpdate内で、動かしたい要素のスタイルを書き換えれば、アニメーションされることになります。
ちなみにオブジェクトのキーは別にxじゃなくたって、複数あったっていいです。
1 2 3 |
[sourcecode lang="javascript"] { a:10, b:20, c:30 } [/sourcecode] |
とかでもいいです。
これを
1 2 3 |
[sourcecode lang="javascript"] tw1 = new TWEEN.Tween({ a:10, b:20, c:30 }) [/sourcecode] |
でやってあげてtoでどのように変化するのか決めます。
1 2 3 |
[sourcecode lang="javascript"] .to({ a: 410, b:300, c:100 }, 2000) [/sourcecode] |
onUpdate内でthisでそれぞれが取れることになります。
1 2 3 4 5 6 7 |
[sourcecode lang="javascript"] .onUpdate(function() { this.a this.b this.c }) [/sourcecode] |
こんな感じで、初期値から指定した秒数後までの変化していく値を返し続けてくれるのが、このTween.jsの機能です。
これを踏まえた上で使用すれば、色々なアニメーション機能の実装ができるはずです。
これまでの例を言葉でまとめると・・・
- new TWEEN.Tween(obj)で変化させるオブジェクトを定義する
以降は「.」でメソッドをつないでいく。 - toメソッド(.to(obj, 000))で、定義したオブジェクトが指定ミリ秒後にどんな値に変化しているかを指定する。
- delayメソッド(.delay(000))で、アニメーションを何ミリ秒遅れさせるかを指定
- easingメソッド(.easing(xxx))で、イージングを指定する。
- onUpdateメソッド(.onUpdate(function(){処理}))で、定義したオブジェクトの数値が変化するたびに実行される処理を定義する。
- onCompleteメソッド(.onComplete(function(){処理}))で、定義したオブジェクトの数値が変化し終えた際の処理を定義する。
※toメソッドとonUpdateメソッド以外は、指定しなくてもOKです。
ちなみに、ここまでで実装したものが、デモのデモ1にあたるものです。
上記のような最小限の機能のみが実装されているのが、このjsの長所であり短所であるのですが、2つほど上記以外で紹介するべき機能を紹介します。
repeatとyoyoを使用して反復アニメーション機能
まずは反復アニメーション機能。
repeatとyoyoというメソッドを使えば、行って戻ってくるというアニメーションをつくることができます。
デモ2に当たる部分になりまね。
先ほどのソースの、
1 2 3 |
[sourcecode lang="javascript"] tw1 = new TWEEN.Tween(pos) [/sourcecode] |
の後を以下のように変えると反復アニメーションになります。
1 2 3 4 5 6 7 8 |
[sourcecode lang="javascript"] .to({ x: 410 }, 2000) .repeat(Infinity) .yoyo(true) .onUpdate(function() { anim1.style.left = this.x + 'px'; }); [/sourcecode] |
repeatはInfinityでなく、数値をいれると、その回数分リピートされます。
Infinityとすると無限に繰り返されます。
もちろんdelay、easing、onCompleteなどは、ここでも使用することが可能です。
chainを使用してアニメーションの連結
次にアニメーションの連結。
1つ目のアニメーションが実行されたら、次のアニメーションが実行される・・・
というようなことができます。
これを可能にするのがchainメソッドです。
デモ3の部分になります。
chainメソッドを使うためのソースを用意しましょう。
かなりボリューミーになってきているので、HTML・CSSはすでにあるものに追記する形として、追記する部分のみを書いています。
HTML
1 2 3 4 5 6 7 8 9 10 |
[sourcecode lang="html"] <ul class="btn"> <li><button id="move3">#anim3動かす</button></li> </ul> <div class="animArea animArea2"> <div class="anim" id="anim3">#anim3</div> <div class="anim" id="anim4">#anim4</div> </div> [/sourcecode] |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[sourcecode lang="css"] .animArea2{ height:190px; } #anim3{ top:10px; left:10px; background:#9d2eb9; } #anim4{ top:100px; left:10px; background:#2eb948; } [/sourcecode] |
javascript
まずは、#anim3と#anim4それぞれアニメーションを定義します。
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 32 33 34 35 36 37 38 |
[sourcecode lang="javascript"] //使用する各DOMを取得 var move3 = document.getElementById('move3'); var anim3 = document.getElementById('anim3'); var anim4 = document.getElementById('anim4'); //スコープに関係なく扱えるようにできるため、ここで宣言。 var tw3,tw4; //#anim3動かすボタンを押したときの挙動 move3.onclick = function(){ animFunc3(); } var animFunc3 = function(){ //#anim3アニメーション tw3 = new TWEEN.Tween({ x : 10 }) .to({ x: 410 }, 2000) .onUpdate(function() { console.log(this); anim3.style.left = this.x + 'px'; }); //#anim4アニメーション tw4 = new TWEEN.Tween({ x : 10 }) .to({ x: 410 }, 2000) .onUpdate(function() { anim4.style.left = this.x + 'px'; }); //#anim3アニメーションスタート tw3.start(); } [/sourcecode] |
これに関しては、今までやってきたものの通りです。
ここでchainメソッドを使用して、#anim3と#anim4のアニメーションを連結させます。
以下の一文を
tw3.start();
の上あたりに追記しましょう
1 2 3 |
[sourcecode lang="javascript"] tw3.chain(tw4); [/sourcecode] |
簡単ですね。
tw3とtw4をつなげる。まんまですね。
これにより、tw3のアニメーションが終わったタイミングでtw4アニメーションがスタートします。
ちなみに、
1 2 3 4 |
[sourcecode lang="javascript"] tw3.chain(tw4); tw4.chain(tw3); [/sourcecode] |
とすると、処理のループが可能です。
tw3が終わるとtw4がスタートして、tw4が終わるとtw3がスタートして・・・・と無限ループですね。
ですが、デモのサンプルコードはループをするようには作っていないので、このコードのままではループしません。
{ x : 10 }
という値が
{ x : 410 }
に変わりきったままですからね。
実際使用するときは、この点に気を付けた設計が必要になりますが、そのやり方までは説明はしません。。。
(だってもうかなりボリューミーな記事に・・・・・・・・)
というわけで、chainについてはこんな感じです。
何個でもつなげられるので、もっと複雑なアニメーションも作れますね。
その他の機能
他にもまだ以下のようなメソッドが用意されているようです
(軽く紹介なので全てではないです)
・onStart:スタート時にイベント発火。
・onStop:ストップ時にイベント発火。
おまけ:IE8でstopを使いたい
正直なところstopメソッドを使うシーンがあまり思い浮かびませんけれども。。。
動かない原因は、ライブラリの中でindexOfを使っているからです。
というわけで、indexOfを使えないブラウザ向けにindexOfを使えるようにしてしまえばOKです。
下記サイトのソースコードをまま流用しちゃいます。
JavaScriptのindexOf(その1)
1 2 3 4 5 6 7 8 9 10 11 12 |
[sourcecode lang="javascript"] if (!Array.indexOf) { Array.prototype.indexOf = function(o) { for (var i in this) { if (this[i] == o) { return i; } } return -1; } } [/sourcecode] |
indexOfが実装されていないものは配列のprototypeをごにょごにょっ・・・って感じですね。
詳細は割愛しますが、これでIE8でもindexOfが使えるようになります。
これをtween.min.jsよりも前に書いておきましょう。
まとめ?
てなわけで、javascriptアニメーションライブラリtween.jsの使い方でした。
正直デモのレベルであれば、jqueryのanimateを使用した方が、手っ取り早いですが、ちょっと複雑なものになってくると、tween.jsのようにアニメーションごとで何が行われているのかが理解しやすかったり、chainメソッドアニメーションをつなげることが出来たりする機能が活きてくると思います。
より詳細な使い方は以下で。
- tween.js
- https://github.com/sole/tween.js/
勝手に次回予告
なんだかいつも記事がボリューミーになってしまう・・・
まとめベタ・・・・orz
次回は、より高機能なjavascriptアニメーションライブラリの
TweenMax.js
を紹介しようと思います。
tween.jsは「自分でソースを書いてなんぼ。」的なライブラリでしたが、TweenMax.jsは、このjs自体が色々な機能をもっています。
数行jsを書いたら、くるくる動き出す・・・みたいなイメージですね。
その分、tween.jsよりもjs自体が重くなりますが。。。
今度はちょっと間隔短めで、12月あたりかなーと。
今年もなんかやるみたいですから、ソニックムーブAdvent Calendar。
そこに参加するかたちでTweenMax.jsを紹介しようと思います。
それではまたその時に~(・ω・)ノシ