HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う

第5回 トゥイーンアニメーションを仕上げる

この記事を読むのに必要な時間:およそ 7.5 分

前回から,TweenJSのデモTWEEN CIRCLESをお題にした。同心円のリングが,ステージ上のクリックした位置に,時間差でトゥイーンする。前回,一応それらしい動きはできた。けれども,Canvasのあちこちを続けざまにクリックすると,同心円にしたリングのトゥイーンがばらばらになってしまった図1)。今回は,アニメーションやインタラクションをよく確かめて,スクリプトの仕上げにかかる。

図1 あちこちを続けざまにクリックするとリングのトゥイーンがばらばらになる

図1 あちこちを続けざまにクリックするとリングのトゥイーンがばらばらになる

前回のjsdo.itサンプルTween Circles Trialよりキャプチャ

隊列を乱さない

ステージ上を素早くあちこちクリックすると,なぜリングのトゥイーンは隊列を乱してしまうのか。それは,先頭と後尾でトゥイーンを時間的にずらしているからだ。先頭は前のトゥイーンをすでに終えていて,すぐにつぎのトゥイーンに向かう。しかし,最後尾はまだ前のトゥイーンが終わっていないため,つぎの目的地には向かえず,今のトゥイーンを終えようとする。だから,それぞれの向かう先がばらばらになってしまうのだ。

これを避けるには,新しいトゥイーンを命じるときには,前のトゥイーンは途中であっても止めさせればいい。そのメソッドが,静的メソッドTween.removeTweens()だ。引数には対象となるインスタンスを渡す。すると,そのインスタンスに定められたすべてのトゥイーンは解除される。

Tween.removeTweens(対象オブジェクト);

前回のコード2のトゥイーンを定める関数には,つぎのようなTween.removeTweens()メソッドの呼出しを加えればよい。

function setTween(target, nX, nY, duration) {
  createjs.Tween.removeTweens(target);
  createjs.Tween.get(target)
  .to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}

もっとも,新しいトゥイーンを命じたら,前のトゥイーンはつねに無視してよいなら,Tween.get()メソッドの第2引数でも定められる。今回のお題なら,こちらの方が簡単だ。

Tween.get(対象オブジェクト, {プロパティ:設定値, …})

第2引数はObjectインスタンスで渡す。オブジェクトには,設定したいプロパティとその値を納める。新たなトゥイーンを加えるとき前のトゥイーンはすべて除いてしまいたいときは,overrideプロパティにtrueを定めればよい(デフォルト値はfalse)。

function setTween(target, nX, nY, duration) {
  //createjs.Tween.get(target)
  createjs.Tween.get(target, {override:true})
  .to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}

これで,ステージを素早く続けざまにクリックしても,古いトゥイーンはすべてのリングから除かれるため,全体が新たな目的地に向かってトゥイーンを始める。もはや隊列の乱れはない図2)。まだ修正はわずかに引数ひとつではあるが,前回までのおさらいもかねて,つぎのコード1にscript要素全体を掲げる。

図2 ステージを素早く続けざまにクリックしてもリングの隊列は乱れない

図2 ステージを素早く続けざまにクリックしてもリングの隊列は乱れない

コード1 ステージ上のクリックした位置に複数のオブジェクトが時間差をつけてトゥイーンする

<script src="http://code.createjs.com/easeljs-0.6.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.4.0.min.js"></script>
<script>
var stage;
var circles = [];
var circleCount = 20;
var delay = 1 / circleCount;
function initialize() {
  var canvasElement = document.getElementById("myCanvas");
  stage = new createjs.Stage(canvasElement);
  var nWidth = canvasElement.width;
  var nHeight = canvasElement.height;
  for (var i = 0; i < circleCount; i++) {
    var nX = Math.random() * nWidth;
    var nY = Math.random() * nHeight;
    var circle = createCircle(10, "#113355", (i + 1) * 3);
    setAppearance(circle, nX, nY, 1 - i * 0.025, "lighter");
    setTween(circle, nWidth / 2, nHeight / 2, (0.5 + i * delay) * 1500);
    circles.push(circle);
    stage.addChild(circle);
  }
  stage.addEventListener("stagemouseup", startTween);
  createjs.Ticker.addEventListener("tick", stage);
}
function createCircle(stroke, color, radius) {
  var circle = new createjs.Shape();
  var myGraphics = circle.graphics;
  myGraphics.setStrokeStyle(stroke);
  myGraphics.beginStroke(color);
  myGraphics.drawCircle(0, 0, radius);
  return circle;
}
function setAppearance(instance, nX, nY, nAlpha, composite) {
  instance.x = nX;
  instance.y = nY;
  instance.alpha = nAlpha;
  instance.compositeOperation = composite;
}
function startTween(eventObject) {
  for (var i = 0; i < circleCount; i++) {
    var circle = circles[i];
    setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
  }
}
function setTween(target, nX, nY, duration) {
  createjs.Tween.get(target, {override:true})
  .to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}
</script>

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入