けんごのお屋敷

2013-09-22

私達はトトロでさえキャンバスに描画できる

先日 @monochromegane と一緒に昼ごはんに行ってペペロンチーノを食べてた時「家でもペペロンチーノを作る」という話をしていたら『Vim でペペロンチーノ作るプラグインまだ?』みたいな誰得プラグインの話をしていた僕です。こんにちは。

そんな誰得プラグインに負けないくらい誰得なものが出来上がってしまったのですが、せっかくなので公開しておきます。


HTML5 に canvas というブラウザ上に図を書くための機能があります。結構いろいろなことが出来て、パーティクルを飛び交わせたり、かっこいいアニメーションを作ったり、Flash ばりの表現力があります。前々からこの canvas の勉強をしてみたいと思っていたので、一つなにか作ってみようと思って出来たのがこれです。

canvas にレインボートトロを描画する
Google Chromeでの閲覧推奨です。1分程度のアニメーションですが、アニメーション中は結構CPUを使います。

ソースはブラウザから ソースの表示 とかでも見れますし、もしくは github にも公開しています。

HTML5 の canvas を使う

canvas の使い方に関しては HTML5.jp の Canvas リファレンス が詳しいですが、一応ソースの解説のために簡単な説明だけ書いていきます。

canvas を使うためには、まず以下のような HTML を作ります。

<!DOCTYPE html>
<html>
<body>
    <canvas id="stage"></canvas>
</body>
</html>

これだけです。HTML に canvas タグさえあれば、あとはこれを JavaScript で操作するだけです。JavaScript では

canvas = document.getElementById('stage');
context = canvas.getContext('2d');

という風にキャンバスのコンテキストを取得して、それを使って描画していきます。getContext の引数に 2d と渡す辺り、3Dの表現も扱えそうですが、まだまだそこまで到達できてません。

サンプルのトトロは、半径 3px の円を繋げてトトロの形を作っています。円を書くためにはコンテキストの arc というメソッドを使って

context.beginPath();
context.fillStyle = 'rgb(255, 255, 255)';
context.arc(x, y, 3, 0, Math.PI * 2);
context.fill();

このように書くと、中心座標を (x, y) として半径 3px の白色で塗りつぶした円が描画されます。つまり、この x と y をトトロの形にそって連続で円を描画しています。

トトログラフ

トトロの形に沿って (x, y) の座標を定義した配列を作ってその配列分だけ繰り返して円(というか点?)をプロットしていってもいいのですが、今回は平面曲線の関数を使ってみました。

Wolfram Alpha というサイトをご存知でしょうか。

Wolfram Alpha(WolframAlphaともWolfram|Alphaとも表記される)はウルフラム・リサーチが開発した質問応答システム。
事実についての質問に対して、構造化されたデータを使って計算し、直接答えを返すオンラインサービスである。
他の検索エンジンのように、答えを含んでいる可能性のあるドキュメントやウェブページのリストを返すわけではない。
by Wikipedia

まあよくわかりませんが、たとえばこのサイトで totoro curve と検索してみてください。すると x, y の座標軸上にトトロの絵が書いてある検索結果が表示されると思います。そしてその下には恐ろしく長い方程式がありますが、キャプチャを見ると式の先頭に x(t) = ... と表記されていることがわかります。キャプチャには写っていませんが、下の方には y(t) = ... という表記もあります。つまり、この式で計算した (x, y) を画面上にプロットしていけばキャプチャにあるようなトトロの絵が出来上がります。

座標の計算、そして描画

座標の計算をするのが f.jsf(t) という関数です。トトログラフ(仮名)の式をそのまま JavaScript で書いて計算しているだけです。引数の t には 0 〜 100π までの範囲の値を渡すことになります。サンプルのトトログラフでは、10000個の点を繰り返しプロットしていますので 0 〜 100π を 10000 分割して、その値を毎回 f の引数として渡し、式を計算して得られた (x, y) 座標に対してキャンバスの arc 関数を使って点を描画しています。

先に紹介した Wolfram Alpha のサイトは検索すれば他のキャラクターのグラフもいくつか存在します。たとえば 初音ミク だったり 孫悟空 だったり。あと、キャラクターとはちょっと違いますが ハートマーク なんかもあります。

こういったものを参考に、平面曲線の関数 f(t) を置き換えれば自分の好きな絵を書くことができます。

おわりに

github のソースを見てもわかるように、100行もいかないくらいの簡単なソースでここまで出来る canvas はやっぱりすごい。もっとちゃんと勉強すればなんでも出来るようになる気がします。

ただ、やっぱり CPU 使用率は激しいです。トトログラフのプロットを開発してる最中はもちろん何度も再生して確認するわけですが、その度に僕の Mac が ファアアアァアアァァン と悲鳴をあげていました。その点はまだまだ Flash に負けていますが、表現力としては申し分ないですね。これからもっと軽くスマートになっていくんでしょうか。技術の進歩はとても早いので期待しておきます。

  • このエントリーをはてなブックマークに追加