HTML5 Canvasのフレームワーク「CreateJS」(基本的な使い方は入門サイトをご覧ください)について、2015年2月10日に開催されたCreateJS勉強会 (第5回) でライトニングトーク「CreateJSとNode.jsを使ってサーバーでCanvas要素を使おう」を発表しました。今回はそのスライドを元に、サーバーサイドでCreateJSを使うメリットを紹介します。
デモ
今回紹介するnode-easelを使ったデモです。スマホ画面にTwitterのアイコンが、PC画面には白い矩形が表示されています。スマホで選んだTwitterのユーザーのアイコンがPC側でアニメーションします。画像加工はサーバーサイドで動くCreateJSを使って行われています。
Section1. Node.jsとモジュールについて
Node.jsはブラウザではなくサーバーサイドで動くJavaScriptで、手軽にhttpサーバーを立てたりファイルの読み書きができます。Node.jsにおけるさまざまな処理はモジュールという単位に分けられていて、httpサーバーを立てるためのhttpモジュール、リアルタイムなWebコンテンツを作るためのSocket.IO等があります。今回はその中のNode.jsでCanvasを扱うためのモジュールとCreateJSを扱うためのモジュールを使います。なお、インストール方法やモジュールについては記事「TypeScriptで始めるNode.js/io.js入門」で詳しく解説してあります。
Section2. Node.jsでCanvasを使う
Node.jsでnode-canvasというモジュールを使うと、サーバーサイドでHTML5 Canvas要素を使った画像処理ができるようになります。PHP等を使ったサーバーサイドの画像加工の代替手段となるのがメリットです。しかし、クライアントサイドのCanvasと同じく低レベルなCanvas(Context2D)のAPIを使用する必要があり、コードが複雑になりがちです。そこでCanvasを扱いやすくするためのCreateJSの登場です。 ※ node-canvasは依存ライブラリが多く、インストールがやや煩雑です。インストールの際には、公式のWikiやQiita等の解説記事を参照してください。
Section3. Node.jsでCreateJSを使う
node-easelというモジュールを使うと、Node.jsでCreateJSが使えるようになります。CreateJSのスイートであるEaselJS(0.7.0)とTweenJS(0.6.1)が使用可能で、PreloadJSやSoundJSは非対応です。使用するAPIがクライアントサイドのCreateJSとほぼ同じあるため、学習コストを低く抑えることができるのがメリットです。 ※ node-easelは、node-canvasがインストールされている環境でコマンドラインからnpm install node-easel
を実行することでインストールできます。
実際のコード
それではnode-easelを使ってサーバーサイドで星の図形を描くというサンプルを通して、実際のコードを見てみましょう。Node.jsの処理はapp.jsというJavaScriptファイルに記述してあります。
var Canvas = require("canvas"); // node-canvasの読み込み
require("node-easel"); // node-easelの読み込み
var canvas = new Canvas(400, 400); // Canvasの作成
var stage = new createjs.Stage(canvas); // CanvasからStageを作成
var shape = new createjs.Shape(); // Shapeの作成
// Shapeのgraphicsプロパティで星の図形を描画
shape.graphics
.beginFill("#FF3DB1")
.drawPolyStar(200, 200, 100, 5, 0.6);
stage.addChild(shape); // ShapeをStageに配置
stage.update(); // Stageをアップデート
var base64String = canvas.toDataURL(); // Canvasの描画情報をBase64形式に変換
console.log(base64String); // コマンドラインにBase64の文字列を出力
上記はサーバーサイドのソースコードですが、StageクラスやShapeクラスなどクライアントサイドでCreateJSを使う時と同じAPIが使われています。最後にCanvasのtoDataURL()メソッドを実行することで、Canvasの描画情報がBase64形式(※)の画像になります。以下のコマンドをコマンドラインから実行すると、上記のJavaScriptがNode.jsとして実行され、Base64形式の画像情報が出力されます。 ※ Base64とはバイナリデータを文字列にエンコードした情報で、コード内でバイナリデータを取り扱うのに向いています。
node app
# Base64の画像文字列が出力される
HTMLファイルを作成し、imgタグのsrc属性に出力された文字列を指定し、そのHTMLをブラウザで閲覧すると以下のような図形が表示されるのが確認できます。
Section4. node-easelを使った画像加工デモ
冒頭のデモにおいてはサーバーサイドで動的にスプライトシートを作っています。スマホでTwitterのユーザーを決定すると、下図のようにTwitterのプロフィール画像と事前に用意しておいたグラフィックスとを合成します。合成が完了したらCanvasのtoDataURL()メソッドを使ってBase64に変換しておきます。
▲サーバーサイドでのスプライトシート作成
また、このスプライトシートと同時にTwitterのユーザー名が記載された吹き出し画像も作成しています。下図のようにTwitterのユーザー名をTextクラス化して事前に用意しておいたグラフィックスと合成します。
▲サーバーサイドでの吹き出し画像作成
スプライトシートの作成が完了したら、このBase64の画像データをクライアントサイドに送信します。送信にはSocket.IO(※)を使っています。クライアントサイドではCreateJSのSpriteクラスを使ってアニメーションを実行します。 ※ Socket.IOは、Node.jsにおいてリアルタイムなデータ通信を簡単にしてくれる技術です。詳しくは記事「Node.jsとSocket.IOによるPCとスマホブラウザのペアリングデモ」を参照してください。
▲Socket.IOによる画像送信
参加者からの質問
5分という短い時間のため、ライトニングトークではお伝えできなかった点が多くありました。ここでは勉強会後にいただいたいくつかの質問にお応えします。
Q. サーバーサイドで画像を合成するメリットが知りたい
大きなメリットとしてはクライアントサイドの実行環境に左右されず、同じ描画結果を提供できることです。クライアントサイドで画像を作る場合は、OSやブラウザの性能によって生成される画像に差異が生まれます。たとえばクライアントサイドでフォントを使って画像加工する場合、ブラウザによってアンチエイリアスがかからない場合があり、Webフォントを使ったとしても同じ描画結果にはなりません。サーバーサイドで画像加工をすればそのような問題は発生しません。
Q. リアルタイムのデータ同期について詳しく聞きたかった
スマホでTwitter IDを決定すると、サーバーサイドにそのTwitter IDのアイコンの画像加工命令が出ます。その命令を受けて画像を加工したサーバーサイドは、加工済みの画像データをPC側に送信します。このサーバー・クライアント間のデータのやりとりは、Socket.IOという技術で実現されています。Socket.IOはNode.jsと組み合わせてリアルタイムなデータ処理を実現する技術です。Socket.IOについては記事「Node.jsとSocket.IOによるPCとスマホブラウザのペアリングデモ」にて詳しく解説しています。
最後に
勉強会の後のアンケートで、「未知のライブラリに出会えてよかった」「サーバーサイドでCreateJSが使えるのをはじめて知った」「いろいろなコンテンツに応用できそう」という声をいただきました。node-easelを使えば、PHP等を使ったサーバーサイドにおける画像加工の知識がなくてもJavaScriptの知識だけでサーバーサイドの画像加工ができるので、フロントエンドエンジニアにとっては新たな表現を行うチャンスになるかと思います。 デモのソースコードはGitHubで公開してありますので興味のある方は是非御覧ください。(ソースコード)
CreateJS勉強会(第5回)の関連記事
- HTML5 CanvasとWebGLの使い分け : 池田発表資料 (前編)
- WebGLのドローコール最適化手法 : 池田発表資料(後編)
- PreloadJSで「悩ませないローディング」の作り方
- CreateJSとNode.jsを使ってサーバーサイドでCanvasを扱おう
- 新CreateJSをコンテンツ制作に活かす | 新しいCreateJSで書くコードはどう変わるのか : 野中氏発表資料