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

第2回 トゥイーンをランダムに定める

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

トゥイーンを繰返す

では,トゥイーンアニメーションに動きを加えよう。トゥイーンを繰り返してみたい。Tween.get()メソッドの第2引数にオブジェクトを渡し,そのloopプロパティにtrueを定めると,トゥイーンが繰り返される。だが,このアニメーションには不満を感じるだろう。

// createjs.Tween.get(target)
createjs.Tween.get(target, {loop:true})

前掲コード1は,トゥイーンにかける時間と移動先の垂直座標をランダムに定めた。確かに,ランダムな時間と位置にアニメーションする。けれど,Tween.get()メソッドに第2引数を渡して繰返されるのはその同じトゥイーンだ。つまり,ランダムな設定は初めに行われたら,その値のままトゥイーンが繰り返される。

繰返すたびにランダム値を変えるには,その設定の関数(setRandomTween())を改めて呼出さなければならない。Tween.call()メソッドは,関数の呼出しをトゥイーンに加える。

Tweenオブジェクト.call(関数, 引数の配列)

Tween.call()メソッドの第1引数に呼出す関数を定め,第2引数には関数に渡す引数を配列で渡す。配列に納めるのは,複数の引数が渡せるようにするためだ。つぎのようにTween.call()メソッドをドット.でトゥイーンに加えれば,ランダムに設定する関数(setRandomTween())が呼び出される。

function setTween(target, myPoint, time, easing) {
  createjs.Tween.get(target)
  .to({x:myPoint.x, y:myPoint.y}, time, easing)   // ;
  .call(setRandomTween, [target]);
}

もっとも,これでも望むアニメーションにはならないだろう。Tweenクラスのトゥイーンを定めるメソッドがドット.でつなげられたとき,後のメソッドのトゥイーンは前のトゥイーンが終わったところから続く。Tween.call()を呼び出す前のTween.to()メソッドで,トゥイーンするオブジェクトは右端にきている。そこから,Tween.call()メソッドでランダムな垂直位置を定めてトゥイーンすれば,右端で上下するだけのアニメーションになってしまう図1)⁠

図1 右端にトゥイーンした後垂直に上下する

図1 右端にトゥイーンした後垂直に上下する

そこで,トゥイーンは左右の端を行き来するアニメーションにしよう。

左右を行き来するランダムなトゥイーンアニメーション

トゥイーンの行き先は,関数でランダムに定めよう。関数(getNextPosition())には,トゥイーンを左右どちらの端から始めるのか引数(side)で渡す。すると,反対の端のランダムな座標をPointオブジェクトで返す。この関数はランダムなトゥイーンを定める関数(setRandomTween())から呼び出すことになる。

行き先座標を返す関数(getNextPosition())における垂直座標(nextY)の定め方は,前掲コード1と同じだ。引数(side)にはトゥイーンを始める端が文字列("left"または"right")で渡される。その値が左なら右端(right)⁠そうでなければ左端(left)を水平座標(nextX)とする。そして,つぎのトゥイーンを始める端は,変数(currentSide)にとっておく。

var left = 0;
var currentSide;
// function setRandomTween(target) {
function setRandomTween(target, side) {
  // var nextY = Math.random() * (bottom - top) + top;
  // var nextPoint = new createjs.Point(right, nextY);
  var nextPoint = getNextPosition(side);
  // ...[中略]...
}
function getNextPosition(side) {
  var nextX;
  var nextY = Math.random() * (bottom - top) + top;
  if (side == "left") {
    currentSide = "right";
    nextX = right;
  } else {
    currentSide = "left";
    nextX = left;
  }
  return new createjs.Point(nextX, nextY);
}

なお,左端座標を新たに変数(left)として宣言した。また,ランダムなトゥイーンを定める関数(setRandomTween())には,第2引数にトゥイーンを始める端(side)が加わっている。

そこで,Tween.call()メソッドにも,呼び出す関数(setRandomTween())の新たな引数(currentSide)を加えなければならない。そして,画像ファイルを読込み終えたリスナー関数(draw())からは,ランダムなトゥイーン設定の関数(setRandomTween())を左端("left")から始めることにして呼び出す。

function draw(eventObject) {
  // ...[中略]...

  // setRandomTween(myBitmap);
  setRandomTween(myBitmap, "left");
  // ...[中略]...
}
function setTween(target, myPoint, time, easing) {
  createjs.Tween.get(target)
  .to({x:myPoint.x, y:myPoint.y}, time, easing)
  // .call(setRandomTween, [target]);
  .call(setRandomTween, [target, currentSide]);
}

これでオブジェクトは,左右にトゥイーンで行き来を繰り返すコード2)⁠そして,垂直位置とトゥイーンの時間は,毎回ランダムに変わる。

コード2 ランダムな垂直位置と時間で左右を行き来するトゥイーンアニメーション

var stage;
var myBitmap;
var top = 0;
var bottom;
var left = 0;
var right;
var currentSide;
function initialize() {
  canvasObject = document.getElementById("myCanvas");
  var file = "images/Pen.png";
  var loader = new createjs.LoadQueue(false);
  right = canvasObject.width;
  bottom = canvasObject.height;
  stage = new createjs.Stage(canvasObject);
  loader.addEventListener("fileload", draw);
  loader.loadFile(file);
}
function draw(eventObject) {
  var myImage = eventObject.result;
  var halfWidth = myImage.width / 2;
  var halfHeight = myImage.height / 2;
  top += halfHeight;
  bottom -= halfHeight;
  left += halfWidth;
  right -= halfWidth;
  myBitmap = new createjs.Bitmap(myImage);
  myBitmap.regX = halfWidth;
  myBitmap.regY = halfHeight;
  myBitmap.x = halfWidth;
  myBitmap.y = (top + bottom) / 2;
  stage.addChild(myBitmap);
  stage.update();
  setRandomTween(myBitmap, "left");
  createjs.Ticker.addEventListener("tick", stage);
}
function setRandomTween(target, side) {
  var nextPoint = getNextPosition(side);
  var randomTime = Math.random() * 5000 + 1000;
  setTween(target, nextPoint, randomTime, createjs.Ease.bounceOut);
}
function setTween(target, myPoint, time, easing) {
  createjs.Tween.get(target)
  .to({x:myPoint.x, y:myPoint.y}, time, easing)
  .call(setRandomTween, [target, currentSide]);
}
function getNextPosition(side) {
  var nextX;
  var nextY = Math.random() * (bottom - top) + top;
  if (side == "left") {
    currentSide = "right";
    nextX = right;
  } else {
    currentSide = "left";
    nextX = left;
  }
  return new createjs.Point(nextX, nextY);
}

なお,変数(left)に定める左端座標は,画像ファイルを読込み終えたリスナー関数(draw())で,オブジェクトがCanvasの外に切れないように幅の半分(halfWidth)内側に定めている図2)⁠ご参考までに,jsdo.itにも次のようにコードを掲げた。

図2 トゥイーンするオブジェクトがCanvasの外に切れないよう左端座標を内側に定める

図2 トゥイーンするオブジェクトがCanvasの外に切れないよう左端座標を内側に定める

次回は,いよいよお題を仕上げる。トゥイーンする端をCanvasの四辺に拡げ,イージングもランダムに切り替えよう。このお題についても,新CreateJS版を掲げておく。

著者プロフィール

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

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

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入