canvasをFlashライクに扱える!EaselJSの基本的な使い方

EaselJSは、著名なFlasherであるGrant Skinner氏が開発したCreateJSに含まれるHTML5 canvas用のJavaScriptライブラリです。CreateJSのサイトからダウンロードできます。EaselJSを使うことで、HTML5のcanvasをFlashに似た操作で扱うことができるようになります。

追記 2014/1/6

EaselJSは、バージョンアップを重ねるごとに仕様が若干変更されています。詳しくは下記ページで解説していますので、宜しければ合わせてご覧下さい。

EaselJSの読み込み

EaselJSを使うには、まずHTMLのhead領域でEaselJSのJavaScriptファイルを読み込みます。なお、EaselJSはHTML5のcanvasを使うので、IE6, 7, 8には対応していません。

HTML

<script type="text/javascript" src="js/easeljs-0.4.2.min.js"></script>

EaselJSの基本的な使い方

EaselJSの基本的な使い方を見ていきましょう。まず、Stageクラスのコンストラクタにcanvas要素を渡し、Stageインスタンスを作成します。次にcanvas上に表示するオブジェクトを作成し、StageインスタンスにaddChildメソッドで追加します。最後にStageインスタンスのupdateメソッドで描画を更新するとcanvas上に表示オブジェクトが描画されます。

下記の例では、半径50pxの赤い円形を作成し、canvasの中央に表示しています。この一連の流れを見てみるとFlashのActionScriptでの処理に非常に良く似ていることがわかります。Flasherの方にとっては、特にありがたいライブラリです。

JavaScript

(function(window) {
  var _canvas;
  var _stage;
  var _circle;
  
  function init(canvasID) {
    try {
      document.createElement("canvas").getContext("2d");
    } catch (e) {
      return;
    }
    _canvas = document.getElementById(canvasID);
    _stage = new Stage(_canvas);
    _circle = new Shape();
    var g = _circle.graphics;
    g.beginFill("#FF0000");
    g.drawCircle(0, 0, 50);
    g.endFill();
    _circle.x = _canvas.width >> 1;
    _circle.y = _canvas.height >> 1;
    _stage.addChild(_circle);
    _stage.update();
  }
  
  window.addEventListener("load", function(e) {
    window.removeEventListener("load", arguments.callee, false);
    init("my-canvas");
  }, false);
}(window));

Tickerクラスによるアニメーション

EaselJSのTickerクラスによるアニメーションを見てみましょう。Tickerクラスは、ActionScriptでのENTER_FRAMEに似た機能を提供します。まず、Ticker.setFPS()でFPSを指定します。FPSは1秒間に処理を行う回数ですが、Flashと同様に実行する環境によっては処理が追いつかないこともあるので、適宜調整しましょう。

次にTicker.addListener()でリスナーとなるオブジェクトを登録します。Tickerは、FPSで指定された間隔でリスナーのtickメソッドを呼び出します。そのため、リスナーオブジェクトは、tickメソッドを実装する必要があります。

下記の例では、赤い円形のShapeインスタンスをアニメーションさせています。Ticker.addListener()でtickメソッドを定義したMainインスタンスを登録することにより、FPSの間隔でMainインスタンスのtick()が実行されます。tick()では、Shapeインスタンスの座標を変更した後、Stageインスタンスのupdate()を実行することで、canvasの描画を更新しています。

JavaScript

(function(window) {
  var STAGE_WIDTH;
  var STAGE_HEIGHT;
  var _main;
  var _canvas;
  var _stage;
  var _circle;
  var _circleRadius;
  var _velocity;
  
  function Main(canvasID, circleRadius) {
    try {
      document.createElement("canvas").getContext("2d");
    } catch (e) {
      return;
    }
    _main = this;
    _canvas = document.getElementById(canvasID);
    STAGE_WIDTH = _canvas.width;
    STAGE_HEIGHT = _canvas.height;
    _circleRadius = circleRadius || 50;
    _velocity = {
      x : (Math.random() * 5 + 5) >> 0,
      y : (Math.random() * 5 + 5) >> 0
    };
    init();
  }
  
  Main.prototype.tick = function() {
    _circle.x += _velocity.x;
    _circle.y += _velocity.y;
    if (_circle.x - _circleRadius < 0 || _circle.x + _circleRadius > STAGE_WIDTH) {
      _velocity.x = -_velocity.x;
    }
    if (_circle.y - _circleRadius < 0 || _circle.y + _circleRadius > STAGE_HEIGHT) {
      _velocity.y = -_velocity.y;
    }
    _stage.update();
  };
  
  function init() {
    _stage = new Stage(_canvas);
    _circle = new Shape();
    var g = _circle.graphics;
    g.beginFill("#FF0000");
    g.drawCircle(0, 0, _circleRadius);
    g.endFill();
    _circle.x = STAGE_WIDTH >> 1;
    _circle.y = STAGE_HEIGHT >> 1;
    _stage.addChild(_circle);
    _stage.update();
    Ticker.setFPS(60);
    Ticker.addListener(_main);
  }
  
  window.addEventListener("load", function(e) {
    window.removeEventListener("load", arguments.callee, false);
    new Main("my-canvas");
  }, false);
}(window));