JavaScript
Animate
CreateJS
AnimateCC

Animate CC 2018のカメラをJavaScriptで操作する

Adobe Animate CC 2018はカメラがスクリプトで操作できるようになりました。基本的なズームとパン(移動)を使った作例でご紹介します。jsdo.itに掲げたサンプル001は、カメラがマウスポインタの動きに応じてパンし、水平ドラッグでズームします。

サンプル001■Controlling camera in Animate CC 2018

1710003_003.png
>> jsdo.itへ

カメラとレイヤー深度を設定する

Animate CC 2018のHTML5 Canvasドキュメントでカメラを操作するには、タイムラインで[カメラを追加]しなければなりません(図001)。また、遠近の視差を表現しないとつまらないでしょう。そのためには、高度なレイヤーでレイヤー深度を調整してください(「高度なレイヤーを使用したレイヤー深度の作成」および「高度なレイヤーとレイヤー深度」参照)。

図001■カメラを追加して高度なレイヤーはオンにする

1710003_001.png

カメラを取得する

カメラを操作するには、カメラのオブジェクトを取得しなければなりません。そのためのメソッドがAdobeAn.VirtualCamera.getCamera()です。引数にはメインタイムライン(exportRoot)を渡します。

var camera = AdobeAn.VirtualCamera.getCamera(exportRoot);

カメラをコントロールするためのAPIは、「実行時のインタラクティブカメラの使用」をご参照ください。また、[コードスニペット]に[カメラ]のコードが加わりましたので、そちらを参考にしてもよいでしょう(図002)。

図002■[コードスニペット]パネルの[カメラ]の項目(HTML5 Canvas)

1710003_002.png

カメラのズームを操作する

カメラのズームは、メソッドgetZoom()setZoom()によりそれぞれパーセンテージで取得・設定します。

// ズームのパーセンテージを得る
var zoom = camera.getZoom();
// ズームのパーセンテージを定める
camera.setZoom(zoom);

ステージ上の水平ドラッグでズームイン/ズームアウトさせるのがつぎのコードです。Stage.stagemousedownイベントでドラッグ開始の座標(mouseDown)を得て、ドラッグのDisplayObject.pressmoveイベントによりカメラのズームを変えています。

var mouseDown = new createjs.Point();

stage.addEventListener('stagemousedown', function(event) {
    mouseDown.x = event.stageX;
    mouseDown.y = event.stageY;
});
stage.addEventListener('pressmove', function(event) {
    var zoom = camera.getZoom() + (event.stageX - mouseDown.x) * 0.02;
    if (100 < zoom && zoom < 250) {
        camera.setZoom(zoom);
    }
});

カメラの位置を操作する

カメラの位置は、メソッドgetPosition()setPosition()でそれぞれ取得・設定します。getPosition()メソッドの戻り値は、xyおよびzのプロパティをもったオブジェクトです。setPosition()メソッドには、座標値を3つの引数として渡します。

// カメラの位置を得る
var position = camera.getPosition();
// カメラの位置を定める
camera.setPosition(x, y, z);

つぎのコードは、マウスポインタがステージ中央から上下左右どちらにあるかによって、カメラの位置を動かします。アニメーションはTicker.tickイベントのリスナー関数で扱います。そうすると、マウスポインタの座標が取れませんので、Stage.stagemousemoveイベントで座標を変数に納めました。なお、ステージ(Canvas)の大きさを調べるとき注意すべきことについて、「HTML5 Canvasで書き出したCanvasの大きさが倍になる」をご参照ください。

var stageCenter = new createjs.Point(
    canvas.width / stage.scaleX / 2,
    canvas.height / stage.scaleY / 2
);
var mouseMove = new createjs.Point();
var mouseDown = new createjs.Point();
stage.addEventListener('stagemousemove', function(event) {
    mouseMove.x = event.stageX;
    mouseMove.y = event.stageY;
});
createjs.Ticker.addEventListener('tick', function(event) {
    var position = camera.getPosition();
    var positionX = (mouseMove.x > stageCenter.x) ? position.x - 1 : position.x + 1;
    var positionY = (mouseMove.y > stageCenter.y) ? position.y - 1 : position.y + 1;
    if (-90 < positionX && positionX < 90) {
        position.x = positionX;
    }
    if (-40 < positionY && positionY < 0) {
        position.y = positionY;
    }
    camera.setPosition(position.x, position.y, position.z);
});

ここでひとつ、ECMAScript 6の新しいMathクラスのメソッドをご紹介します。引数の符号(sign)つまり正か負か0かを、それぞれ+1、-1、0で返すMath.sign()です。このメソッドを使うと、上記コードでカメラの動く方向を決める条件(3項)演算子の式が、つぎのように書き替えられます。

// var positionX = (mouseMove.x > stageCenter.x) ? position.x - 1 : position.x + 1;
// var positionY = (mouseMove.y > stageCenter.y) ? position.y - 1 : position.y + 1;
var positionX = position.x + Math.sign(stageCenter.x - mouseMove.x);
var positionY = position.y + Math.sign(stageCenter.y - mouseMove.y);

以上のスクリプトをまとめたのが、つぎのコード001です。冒頭のサンプル001は、FLAファイルのメインタイムラインにこのコードを書いてパブリッシュしました。

コード001■カメラをマウスポインタの移動でパン/ドラッグでズームする

var camera = AdobeAn.VirtualCamera.getCamera(exportRoot);
var stageCenter = new createjs.Point(
    canvas.width / stage.scaleX / 2,
    canvas.height / stage.scaleY / 2
);
var mouseMove = new createjs.Point();
var mouseDown = new createjs.Point();
stage.addEventListener('stagemousemove', function(event) {
    mouseMove.x = event.stageX;
    mouseMove.y = event.stageY;
});
createjs.Ticker.addEventListener('tick', function(event) {
    var position = camera.getPosition();
    var positionX = position.x + Math.sign(stageCenter.x - mouseMove.x);
    var positionY = position.y + Math.sign(stageCenter.y - mouseMove.y);
    if (-90 < positionX && positionX < 90) {
        position.x = positionX;
    }
    if (-40 < positionY && positionY < 0) {
        position.y = positionY;
    }
    camera.setPosition(position.x, position.y, position.z);
});
stage.addEventListener('stagemousedown', function(event) {
    mouseDown.x = event.stageX;
    mouseDown.y = event.stageY;
});
stage.addEventListener('pressmove', function(event) {
    var zoom = camera.getZoom() + (event.stageX - mouseDown.x) * 0.02;
    if (100 < zoom && zoom < 250) {
        camera.setZoom(zoom);
    }
});

[追記: 2017年10月29日]「カメラの位置を操作する」に、Math.sign()メソッドによるコードの書き替えを追加。