Posted at

CreateJSでスマートフォン向けサイトのアニメーションを実装するときに気をつけるポイント

More than 5 years have passed since last update.

Flashを使わずに、スマートフォン向けサイトでアニメーションを実装する際、いくつか選択肢があると思います。

その中でもCreateJSを使った際に、いくつか気を付けなければいけないポイントがあったので、まとめました。


気をつけるポイント


  • 最新のCreateJSを使う

  • タッチ操作に反応させる

  • CSSのtransformを使ってcanvasを縮小させると、Android4.x系のデフォルトブラウザで表示がおかしくなる

  • canvasが画面サイズより大きいと、CSSで overflow:hidden などとしても余計な余白が生成されてしまうので、JSで動的にサイズを設定してあげる

  • 一部のAndroid4.x系のデフォルトブラウザで、PreloadJSのcompleteイベントが2回コールされる


最新のCreateJSを使う

通信負荷を分散させるために、CDN (Content Delivery Network) でホスティングされているCreateJSを使います。

バージョン情報は下記サイトで確認します。

CreateJS CDN Libraries

以下のように、EaselJS, TweenJS, SoundJS, PreloadJSを一括で読み込める記述方法もあります。


HTML

<head>

<script src="http://code.createjs.com/createjs-2013.09.25.min.js"></script>
</head>


タッチ操作に反応させる

CreateJSのイベント処理は、PCでのイベントがベースになっています。(mousedownやclickなど)

clickイベントなどは、何もしなくてもタッチ操作に反応してくれますが、mousedownなどは反応してくれません。mousedownなどをタッチ操作に反応させるには、ステージ生成後に下記処理を行います。


HTML

<body>

<canvas id="canvas" width=320 height=320></canvas>
</body>


JavaScript

var canvas = document.getElementById("canvas");

var stage = new createjs.Stage(canvas);
createjs.Touch.enable(stage);


CSSのtransformを使ってcanvasを縮小させない

画像をcanvas上に描画する際、解像度の高いスマートフォンでより綺麗に見せるために、倍のサイズで描画したものを縮小して表示させる方法が有効です。

例えば以下のように、CSSのtransformを使って実現する方法があります。この方法だと、画像を描画する座標などもそのままスケールしてくれるため、簡単に調整出来ます。


CSS

#canvas {

-webkit-transform: scale(0.5, 0.5);
-moz-transform: scale(0.5, 0.5);
-ms-transform: scale(0.5, 0.5);
-o-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
}

ところが、 Android4.x系のデフォルトブラウザで上記canvasを表示させると、縮小前と縮小後の両方の画像が一緒に描画されてしまいます。 (chromeやsafariは問題ありません。)

解決策として、canvasではなく描画する画像を、以下のように縮小して使うことで、解像度の高いスマートフォンで画像を綺麗に見せることが出来ます。


JavaScript

var bitmap = new createjs.Bitmap("img/xxx.png");

bitmap.setTransform(0, 0, 0.5, 0.5);
stage.addChild(bitmap);


canvasサイズはJSで動的に設定してあげる

画面サイズが大きいスマートフォンに合わせて、大きいサイズで設定したcanvasを、画面サイズが小さいスマートフォンでは、はみ出た部分をマスクしてしまえばいいかと考えていました。

しかし canvasが画面サイズより大きいと、親の要素でCSSで overflow:hidden などとしても余計な余白が生成されてしまいました。 他にもいろいろとCSSで解決しようとしたのですが、よい方法が見つかりませんでした。

結局、画面サイズより大きいcanvasがそもそもの原因なので、JSで動的にサイズを設定してあげる方法が、シンプルな解決策でした。

以下は、単純に画面サイズにcanvasサイズを合わせる方法です。


JavaScript

var canvas = document.getElementById("canvas");

var stage = new createjs.Stage(canvas);

stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;


以下は、例えば640x320のcanvasに描画したものを、画面中央に表示してはみ出た部分は切り捨てる、というようなことをしてます。


JavaScript

var windowWidth = window.innerWidth;

var windowHeight = window.innerHeight;

if (windowWidth < 640) {
$('#canvas').css({"margin-left":-windowWidth/2+"px"});
stage.canvas.width = windowWidth;
stage.x = -(640 - windowWidth) / 2;
} else {
$('#canvas').css({"margin-left":-640/2+"px"});
stage.canvas.width = 640;
}



CSS

#canvas {

position: absolute;
left: 50%;
}

stage.x = -(650 - windowWidth) / 2; としているのは、切り捨てた部分の領域分、canvas上の描画位置をずらしています。


PreloadJSのcompleteイベント

CreateJSには画像や音声といったアセットファイルを簡単にプリロードしてくれる、PreloadJSというライブラリがあります。

例えば、画像ファイルを読み込んでcanvasに表示するようなサンプルコードは、以下のようになります。

公式のドキュメントも、だいたい同じです。


JavaScript

var manifest = [{src:"img/xxx.png", id:"image"}];

var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(manifest);

function handleFileLoad(event) {
var type = event.item.type; // 読み込んだファイルのタイプ
var data = event.result; // 読み込んだデータ
}

function handleComplete() {
// 何かしらの処理
...
}


fileloadイベントはファイルを読み込む度に発生し、completeイベントは全てのファイルを読み込んだ後に発生します。

ところが 一部のAndroid4.x系のデフォルトブラウザで、PreloadJSのcompleteイベントが2回コールされていました。 このケースでも、chromeやsafariでは起きません。

個人的にはあまり気持ちのよい解決策ではなかったのですが、以下とすることで解決出来ました。


JavaScript

function handleComplete() {

loader.removeEventListener("fileload", handleFileLoad);
loader.removeEventListener("complete", handleComplete);

// 何かしらの処理
...
}



まとめ

スマートフォンでCreateJSを使ってアニメーションを実装する際、chromeやsafariなどはPC版とほぼ同じような挙動をしてくれました。Android2.3系のデフォルトブラウザも、パフォーマンスはかなり落ちますが、挙動はまあまあ安定してます。

しかしAndroid4.x系のデフォルトブラウザは別です。とてもユニークな挙動をしてくれますので、特に念入りな動作確認が必須だと思いました。

この記事で触れたこと以外にも、以下のような記事もあります。

CreateJS x Android でハマったこと