CreateJSとNode.jsを使ってサーバーサイドでCanvasを扱おう―CreateJS勉強会/鹿野発表資料

CreateJSとNode.jsを使ってサーバーサイドでCanvasを扱おう―CreateJS勉強会/鹿野発表資料

こんにちは、ICSの鹿野です。
先日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入門」で詳しく解説してあります。

visual1

Section2. Node.jsでCanvasを使う

Node.jsでnode-canvasというモジュールを使うと、サーバーサイドでHTML5 Canvas要素を使った画像処理ができるようになります。PHP等を使ったサーバーサイドの画像加工の代替手段となるのがメリットです。しかし、クライアントサイドのCanvasと同じく低レベルなCanvas(Context2D)のAPIを使用する必要があり、コードが複雑になりがちです。そこでCanvasを扱いやすくするためのCreateJSの登場です。
※ node-canvasは依存ライブラリが多く、インストールがやや煩雑です。インストールの際には、公式のWikiQiita等の解説記事を参照してください。

visual2

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を実行することでインストールできます。

visual3

実際のコード

それでは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をブラウザで閲覧すると以下のような図形が表示されるのが確認できます。

スクリーンショット 2015-02-05 18.35.50

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による画像送信

Socket.IOによる画像送信

参加者からの質問

5分という短い時間のため、ライトニングトークではお伝えできなかった点が多くありました。ここでは勉強会後にいただいたいくつかの質問にお応えします。

サーバーサイドで画像を合成するメリットが知りたい

大きなメリットとしてはクライアントサイドの実行環境に左右されず、同じ描画結果を提供できることです。クライアントサイドで画像を作る場合は、OSやブラウザの性能によって生成される画像に差異が生まれます。例えばクライアントサイドでフォントを使って画像加工する場合、ブラウザによってアンチエイリアスがかからない場合があり、Webフォントを使ったとしても同じ描画結果にはなりません。サーバーサイドで画像加工をすればそのような問題は発生しません。

リアルタイムのデータ同期について詳しく聞きたかった

スマホで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、CSS3、JSを使ったリッチなWebページ制作を業務として扱った後、2014年よりICSでアプリ開発に携わる。豚骨ラーメンが大好きです。