Help us understand the problem. What is going on with this article?

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 でハマったこと

finc
健康寿命を伸ばすアプリFiNCの開発・運営を行うモバイルヘルステクノロジーベンチャー
https://finc.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away