HTML5 LogoをCanvasで描いてみた
かっこ良いんだか悪いんだか、ちょっとわからないけど、HTML5のロゴができたということなので、ちょっと遊んでみた。CCライセンスで提供されている。SVGデータもあるので、中身を見たところ、これならすぐにCavnasでも描けそうだと思い立ったので、帰宅電車の中でコードを書いてみた(はい、お気楽モードです)。
polygonは下記のように頂点の並びpointsと塗りつぶす色を指定しているだけ。
<polygon fill="hsl(13, 77%, 52%)" points="107.644,470.877 74.633,100.62 437.367,100.62 404.321,470.819 255.778,512 "/>
pointsを正規表現でパースするのが実装が簡単。一度に全部分解するのもいいけど、gオプションで有効なlastIndex機構を使って前から順番にパースする。以下のようなコードになる。forの使い方にちょっと抵抗を感じる人もいるかもしれない。
var pat = /(-?\d+(\.\d+)?)\s*,\s*(-?\d+(\.\d+)?)/g; g.beginPath(); for (var p, head = true; (p = pat.exec(points)); ) { var x = Number(p[1]); var y = Number(p[3]); if (head) { g.moveTo(x, y); head = false; ] else { g.lineTo(x, y); } } g.close(); g.fill();
次に、pathは下記のように相対/絶対座標と垂直/水平直線だけを使っている。大文字は絶対座標で、小文字が相対座標。Mは始点(moveTo), Hは水平直線、Vは垂直直線。
<path d="M108.382,0h23.077v22.8h21.11V0h23.078v69.044H152.57v-23.12h-21.11v23.12h-23.077V0z"/>
polygonの正規表現よりちょっと複雑だけど、大したことはない。Canvasには相対位置指定のlineToがないので、現在の(x, y)座標を変数に保持している。以下のようなコードになる。
var pat = /([MLVHZ])(\s*(-?\d+(\.\d+)?)(,|\s+)?(-?\d+(\.\d+)?)?)?/ig; var x = 0; var y = 0; g.beginPath(); for (var p; (p = pat.exec(path)); ) { switch (p[1]) { case 'M': x = Number(p[3]); y = Number(p[6]); g.moveTo(x, y); break; case 'v': y += Number(p[3]); g.lineTo(x, y); break; case 'H': x = Number(p[3]); g.lineTo(x, y); break; : (略) : case 'z': g.closePath(); break; } } g.fill();
こうしてできたのが、左の画面。単に表示してもつまらないので、くるくる回転伸縮アニメーションをつけた。
コードと実際の動作は、こちらからどうぞ:
気晴らしにSVGそのものからCanvasに描画するコードを書くのも面白いかもしれない。
Have fun!