2011年4月18日月曜日

CSS桜ひらひらはこうして作りました

都内の桜ももう散りましたね。

先月、jsdo.itというJavascript, HTML5, CSSをブラウザ上でコード書いて共有できるサイトに、桜の花びらが舞うCSSアニメーションのコードをアップしました(Webkitブラウザ限定ですが)。

さーくらー ひらーひらー - jsdo.it

これのbookmarklet版のコードも公開してます。
桜ひらひらbookmarklet - jsdo.it

今SafariかChromeを利用している方なら、下記のリンクをクリックすればこのページ内を桜の花びらが舞います。

桜ひらひらbookmarklet

これをどうやって実現しているか今日は書きたいと思います。
まあ僕がやることはいつもたいしたことじゃありません。多少手間がかかることをちまちまやってるだけです。


■花びら
まず花びら。半分ずつ作ります。
下の画像はdivを加工していく過程で、左から右にどんどん適用style増えていきます。(見やすさのために実際の2倍の大きさにしてます)


左端は、width: 9px, height: 6px のdivを作りまして、position: absolute にしておき、そしてborder-radius: 6px 0px 0px 0px として左上だけ丸めた状態です。
次に -webkit-transform: skew(-30deg) でちょっと歪めてます。
さらに、-webkit-transform: skew(-30deg) scale(1.2, 1)で横方向1.2倍、縦方向1倍、要するに横にちょびっと引き伸ばします。
さらにさらに、-webkit-transform: skew(-30deg) scale(1.2, 1) rotate(12deg) で少し傾けます。
これに background: -webkit-gradient(linear, left top, right bottom, from(rgba(224, 176, 192, 1)), to(rgba(255, 240, 240, 1))) で色着けます。
見やすさのために付けてたborder外したのが一番右の画像。
これを左半分とします。

同じようにもう半分を作りますが、skewとscaleの縦方向の値の符号を反転したものを作ってあげます。
width: 9px, height: 6px, position: absolute, border-radius: 6px 0px 0px 0px のdivは同じですが、 -webkit-transform: skew(30deg) scale(1.2, -1) rotate(12deg) とします。色もグラデの向きがちょっと違い、 background: -webkit-gradient(linear, left bottom, right top, from(rgba(224, 176, 192, 1)), to(rgba(255, 240, 240, 1))) です。まあこの辺は、向きとか形とか実際に確認しながらやってます。



これら半分ずつを合わせて1枚の花びらにしたいので、同じdivの中に2つを入れます。
position: absoluteが効いてて見事に重なってくれてますので、少し位置を合わせるために、下半分の div を top: 4px 指定します。
これに色着けた状態でborder外したのが左から3番目のものです。
見やすさのために倍の大きさにしてますが、本来の大きさは一番右のものです。



さて、ここまでを整理して、style設定をいくつかのclassに分けて、divで花びら作るhtmlはこうなります。

コード:
<style type="text/css">
/* 花びら(parent) */
.petal {
width: 15px;
height: 10px;
}

/* 花びらの半分基礎 */
.petalBase {
border-radius: 6px 0px 0px 0px;
position: absolute;
top: 0px;
left: 3px;
width: 9px;
height: 6px;
}

/* 花びらの左半分になるところ */
.petalLeft {
background: -webkit-gradient(
linear, left top, right bottom,
from(rgba(224, 176, 192, 1)),
to(rgba(255, 240, 240, 1))
);
-webkit-transform: skew(-30deg) scale(1.2, 1) rotate(12deg);
}

/* 花びらの右半分になるところ */
.petalRight {
top: 4px;
background: -webkit-gradient(
linear, left bottom, right top,
from(rgba(224, 176, 192, 1)),
to(rgba(255, 240, 240, 1))
);
-webkit-transform: skew(30deg) scale(1.2, -1) rotate(12deg);
}
</style>


<div class="petal">
<div class="petalBase petalLeft"></div>
<div class="petalBase petalRight"></div>
</div>



■花びら回転
花びらを回転させましょう。
さきほど花びらを作ったとき、半花びら2つを内包する親divを作りましたので、そいつをCSSアニメーションで動かせばいいのです。
アニメーションの設定はこんな感じで、まずは3D-X回転のみです。

コード:
<style type="text/css">
/* 花びら回転 */
.petalRotate {
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 1s;
-webkit-animation-name: rotateX;
}

@-webkit-keyframes rotateX {
0% {-webkit-transform: rotate(0deg) rotateX(0deg);}
100% {-webkit-transform: rotate(0deg) rotateX(360deg);}
}
</style>


<div class="petal petalRotate">
<div class="petalBase petalLeft"></div>
<div class="petalBase petalRight"></div>
</div>


petalRotateクラスではアニメーションは終わりなしの無限Loop、動作の加速度はリニア、アニメーション1回にかかる時間は1秒、アニメーションの細かい設定名はrotateX、という指定です。
keyフレームは、アニメーションがn%進んだ位置でのアニメーションしたい属性とその値を書きます。間の値は補完されます。今回はwebkit-transformで2次元の回転(rotate)と3次元縦方向回転(rotateX)を指定して、rotateは値変えてないので実質アニメーションしませんが、3D縦方向は1sでくるくるします。

このアニメーション設定クラスpetalRotateを親divのclassに追加すればくるくるしだします。rotateは後で使います。
(すいません、実サンプル載せてなくて。)


■花びらの移動
回転できたら回転する花びらを移動させたいところです。ひらひら舞い落ちるんで。
しかし回転のアニメーションは1sです。一緒のclassに移動するアニメーション設定まで突っ込んだら、1sで移動開始点から終了点まで動くことになり、風情がない落ち方になります。

「ねぇ、知ってる?秒速5センチなんだって。桜の花の落ちるスピード。」

ということで、回転とは独立したアニメーションを設定したいわけですが、そのために「回転する花びら」をdivで囲んで、そいつにアニメーションを適用します。
花びらの構造がこんなふうになるわけです。
<div class="parentPetal petalTrans"> <!-- 移動アニメーション用-->
<div class="petal petalRotate"> <!-- 回転アニメーション用 -->
<div class="petalBase petalLeft"></div> <!-- 花びら半分A -->
<div class="petalBase petalRight"></div> <!-- 花びら半分B -->
</div>
</div>


CSS含むコードはこんな感じ:
<style type="text/css">
/* 花びら(parent) */
.petal {
width: 15px;
height: 10px;
}

/* 花びらの半分基礎 */
.petalBase {
border-radius: 6px 0px 0px 0px;
position: absolute;
top: 0px;
left: 3px;
width: 9px;
height: 6px;
}

/* 花びらの左半分になるところ */
.petalLeft {
background: -webkit-gradient(
linear, left top, right bottom,
from(rgba(224, 176, 192, 1)),
to(rgba(255, 240, 240, 1))
);
-webkit-transform: skew(-30deg) scale(1.2, 1) rotate(12deg);
}

/* 花びらの右半分になるところ */
.petalRight {
top: 4px;
background: -webkit-gradient(
linear, left bottom, right top,
from(rgba(224, 176, 192, 1)),
to(rgba(255, 240, 240, 1))
);
-webkit-transform: skew(30deg) scale(1.2, -1) rotate(12deg);
}

/* 花びら回転 */
.petalRotate {
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 1s;
-webkit-animation-name: rotateX;
}

@-webkit-keyframes rotateX {
0% {-webkit-transform: rotate(-58deg) rotateX(0deg);}
100% {-webkit-transform: rotate(-58deg) rotateX(360deg);}
}

/* 花びら移動 */
.animationArea {
position: relative;
overflow: hidden;
width: 640px;
height: 640px;
border: 1px solid red;
}

/* 移動アニメ適用div */
.parentPetal {
position: absolute;
}

/* 花びら落下 */
.petalTrans {
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 10s;
-webkit-animation-name: transPetal;
}

@-webkit-keyframes transPetal {
0% {top: -5%; left: 90%;}
5% {top: -5%; left: 90%;}
95% {top: 105%; left: 10%;}
100% {top: 105%; left: 10%;}
}
</style>


<div class="animationArea">
<div class="parentPetal petalTrans">
<div class="petal petalRotate">
<div class="petalBase petalLeft"></div>
<div class="petalBase petalRight"></div>
</div>
</div>
</div>


ひらひらアニメーションする「エリア」を設けるために、さらに親divをひとつ作ってます。この領域内を花びらが舞い、領域の外では見えなくなるようにするために、overflow:
hiddenです。実際のjsdo.itのコードではこの領域をJavaScriptで画面いっぱいになるようにブラウザ幅等取得して調整してます。

移動アニメーション適用のためのdivにもposition:
absolute指定付けときます。そしてアニメーションさせるstyleとして、positionのtop, leftを用います。

アニメーション時間は10秒間にしました。視界の外から入って外に出て行く、ために、top: -5% 位置から入って、top:
105%位置に抜けてるようにしてます。leftは90%からスタートして10%位置へ。右上から入って左下に抜ける道筋になります。

アニメーション進行時間の0-5%、95-100%が同じ位置です。これは、実際のアニメーションは5-95%の間で、前後は画面外で静止しているようにしてます。次から次へと同じルート上を落ちてくるとせわしないかな、ということで、ちょっとしたWaitが入ってるようなもんです。

ついでに、ちゃっかり回転の方のアニメーション設定の、rotate(rotateXではない)を -58 deg
に設定しています。これは花びらの落ちるコースの角度に合わせたもので、topとleftの移動距離を使ってatan(アークタンジェント)で計算して出せます。


■ひらひら
ここまでは花びら1枚の、作成方法とアニメーションの設定について書きました。
複数の花びらがひらひら舞うようにするには、JavaScript使って花びらの量産し、その1枚ずつにそれぞれ回転・道筋のアニメーション設定、をしています。
このあたりはJavaScriptの説明になりさらに長くなるので、詳細は割愛しますが、ざっと以下のような手順です。
  1. 花びら1枚ずつにid振って、たくさん作ります(jsdo.itのコードでは48枚)
    回転用divと移動用divにそれぞれid振ります。
  2. それをアニメーション領域のdivの子として追加します
  3. アニメーション設定(回転と道筋)をJavaScriptで48個分書き出します
    まず先に道筋を、topは-5%スタートの105%エンドで固定で、leftを、スタートは20-150%くらいの範囲、エンドを0-130%くらいの範囲で、乱数用いて決定します。
    これでアニメーション領域の幅(px数)と%で、縦横の移動距離わかるので、atan使って、花びらのコースに沿った角度を求めて、回転の方のアニメーション設定に活かします。
    (今回は面倒だったので、これらを<style>に生テキストとして突っ込んでます)
    この段階ではまだアニメーションしてません。
    まだkeyframeを用意しただけで、それぞれの花びらに対して、-webkit-animation-なんとか、のstyleを適用してません。
  4. すべての花びらのアニメーション時間設定を、これも多少のバリエーション持たせたstyleを用意します。
    回転は0.8s - 1.2s、移動は9 -13sの範囲からランダムに設定されます。これで他よりややゆったり落ちる花びら、他より多めにくるくる回ってる花びら、などが生まれます。道筋も、基本的に右上方面から左下方面、ってだけで角度はバリエーションありますので、1枚ずつは同じ道筋・回転の速さでループしていても、複数枚が舞うことで、すぐには飽きないようにというのを狙ってます。
  5. 最後にすべての花びらに生成したstyleを適用します。


最初の方にも書きましたが、やってることは別に難しいことでもなんでもなくて、ちまちまと多少面倒なことを積み重ねているだけです。
もし気になることなどあれば、jsdo.itの方には質問等かくとこあるので、そちらへ。

2011年4月15日金曜日

icotileのロゴデザインをしました -icotile のどのあたりが HTML5 なのか? 番外編-

少し前に、icotile(http://icotile.ogaoga.org/)のロゴデザインやその他機能の実装等をやりました。おかげさまでicotile、「第 0 回 HTML5 プログラミング&クリエイティブ・コンテスト」にて優秀作品賞をいただきました
(って書くと作成し終わったかのようですが、icotile自体は今もまだアップデート続いてます)

icotileとは:
Twitter のフォローしている人/されている人やリストを iTunes のような操作感で管理でき、また各ユーザーに対して自分だけのメモも残せる Web アプリケーション。Developed by @ogaoga / Designed by @piyotori
ということですが、僕はCSS3まわりやビジュアル的なデザイン面以外でも普通にJavaScriptのロジック部分も書いたりしてますし、むしろogaogaさんが総合的な意味でデザインやってたりします。


さて、icotile企画者にてUI含めほとんどの部分を作ったogaogaさんが、「icotile のどのあたりが HTML5 なのか? #html5j」を書いてます。その中でCSS3まわりについては piyotori がそのうち書くでしょう、って振られてたのですが、なかなか書けずにいましたが、重い腰を上げて書くことにします。


が、CSS3じゃなくてまずはロゴデザインの話します (キリッ


まず最初に書いておきますが、僕はデザイナーを生業とするものではありません。普段はhtml5はもとよりデザインもWebも関係ないような仕事をしています。ので、そんな風にデザインやってんのかよ的なところ多々あると思いますが、ご容赦ください。

初めに。icotile一緒に作りましょうという話をogaogaさんからいただいのたのが今年1月中旬くらいで、html5コンテストは2/10締め切り。あまり期間がない(ある方か?)けれども、ロゴだけでもまずはなんとしてでも作らねば状態でした。が、Webサービスのコンセプトを聞いた後、さらにはロゴこんな感じと、既存フォントで作ったイメージも提供いただいたので、イメージを掴みやすかったです。

そのときいただいたロゴイメージ:


このイメージと、「icotile」という名前がそもそも「アイコンがタイル上に並ぶ」ことに由来していることから、I, C, O, T, I, L, Eのアルファベットを1文字ずつタイルに描かれた文字みたいに並べてロゴにしようと思いました。
で、iPadですらすらっとお絵描きしてみたのがこれ。
…と思ったらあれ?画像がない。だいぶ前に消しちゃったっぽい。
すいません。
なかったことにして話を進めますが、ラフな絵を描いた段階で頭の中では、タイルの1辺を a pxとして、文字の幅は a/4 pxで、カッチリ計算したフォントみたいなの作ろうと思ってました。


で、計算により描画する、ということで、はいここでhtml5のcanvasです。強引。


っつーわけで僕は canvas 使って ロゴに使う1文字ずつの画像を作成することにしました。

まず正方形のcanvas を用意し、1辺のpxを指定して、そこからすべて計算により図形を描画して文字を作っていきます。
簡単な I を例にすると、仮に1辺が120pxだとして、下図のような、緑の点を基点とした、横幅が 120/4 = 30、高さが120 の長方形描けばいいのです。


緑の点の座標は、まずXは、canvasのセンターが120 / 2 = 60なので、そこから文字幅 120 / 4 = 30をさらに 2 で割った値をマイナスしてあげた、X=45、Yはcanvasの一番上なので0、となります。

JavaScriptはこんな感じ。
    var cnvs = document.createElement("canvas");
cnvs.width = 120;
cnvs.height = 120;
cnvs.id = "id_cnvs_I"
$("body").append(cnvs);

var ctx = document.getElementById("id_cnvs_I").getContext('2d');
ctx.fillStyle = "black";
ctx.fillRect(45, 0, 30, 120);

これで、120x120のcanvasの真ん中に棒が一本みたいなのができます。

でもこれだとカッチリカクカクな棒なので、角丸になるように、半径 r の円弧を使って角丸boxを書く関数を用意します。これはこちらの記事を参考にさせていただきました。

[javascript]canvasで円や角丸の矩形を描画する - 週末ラボ

これでこんな「I」の文字ができます(外枠は本当はありません)。


この文字を一回り大きいサイズの角丸四角で囲みたくなります。「タイル」をイメージするんで。

しかし。僕自身このエントリで書いてるようにロゴ文字を作っていったので、さて外枠描画しようかなってときに、canvasサイズ小さいじゃん!ってなりました。まあいろいろな対応が考えられますが、とりあえずcanvasをひとまわり大きいサイズにするにはしますが、こんな手順で外枠付けました。

0.例では120x120のcanvasだったが128x128のcanvasを最初に用意することにする(外枠マージン上下左右4pxずつ)
1.外枠のマージン分canvasを移動させて文字を描画する
2.canvasを大きくする前と同じままのコードで文字を描画する
3.外枠のマージン分移動したcanvasを元に戻す
4.外枠描く

「canvasの移動」には translate を使います。translateはちょっと混乱しますが、画用紙にひたすら同じ図形を描いているロボットアームがあったとして、画用紙をずらしたらずれた位置に同じ図形描きますよねってのをイメージしていただくとよいかと思います。
実際に I を描いてさらに外枠付けるコードはこんな感じです。
    var cnvs = document.createElement("canvas");
cnvs.width = 128;
cnvs.height = 128;
cnvs.id = "id_cnvs_1"
$("#font_draw_area").append(cnvs);

var ctx = document.getElementById("id_cnvs_1").getContext('2d');
ctx.fillStyle = "black";

pi = Math.PI;
/* 角丸boxパス作成 */
var makeRoundRectPath = function(ctx, x, y, w, h, r){
ctx.beginPath();
ctx.arc(x + r, y + r, r, - pi, - 0.5 * pi, false);
ctx.arc(x + w - r, y + r, r, - 0.5 * pi, 0, false);
ctx.arc(x + w - r, y + h - r, r, 0, 0.5 * pi, false);
ctx.arc(x + r, y + h - r, r, 0.5 * pi, pi, false);
ctx.closePath();
}

/* 文字描画 */
ctx.translate(4, 4); /* canvas移動 */
makeRoundRectPath(ctx, (120 / 2) - (30 / 2), 0, 30, 120, 6);
ctx.fill();
ctx.translate(-4, -4); /* canvas移動戻す */

/* 外枠描画 */
ctx.strokeStyle = "black";
makeRoundRectPath(ctx, 0, 0, 128, 128, 6);
ctx.stroke();

/* 画像オブジェクトに */
var imgObj = new Image(128, 128);
var imgSrcData = document.getElementById("id_cnvs_1").toDataURL("image/png");
imgObj.src = imgSrcData;
$("body").append(imgObj);
$("#id_cnvs_1").remove();
最後の方が妙なことやってますが、後で説明します。
これで、以下のような I の画像ができあがります。


今回説明する都合上単純化しており外枠はstrokeで済ませました。でも実際にはroundRectをさらに改造したもの、を組み合わせて、外枠描画するようにしてます。


「I」は簡単でしたが「T」はどうでしょうか。

まず横棒(X=0, Y=0, W=120, H=30の長方形)と縦棒(X=45, Y=0, W=30,
H=120の長方形)を描画します。(わざと半透明色にしてます)


これでもいいのですが、Tの「脇」が気になります。以下の赤いところ。


今回はここも丸みを持たせるデザインにしようと思います。そこで、角丸boxの外側を描画する関数を用意します。下図のようなイメージで、指定した領域(うす緑)の4つの角を描画するものです。


実際には、どこの角を塗るか指定するMaskもつけて、こんな感じの作りました。

/* 角丸Outerパス作成 */
// mask: bit3=lefttop, bit2=righttop, bit1=rightbottom, bit0=leftbottom
function makeRoundRectOuterPath(ctx, x, y, w, h, r, mask){
ctx.beginPath();
if(mask & 0x08){
ctx.moveTo(x, y);
ctx.arc(x + r, y + r, r, - pi, - 0.5 * pi, false);
ctx.lineTo(x, y);
ctx.lineTo(x, y + r);
}

if(mask & 0x04){
ctx.moveTo(x + w - r, y);
ctx.arc(x + w - r, y + r, r, - 0.5 * pi, 0, false);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w - r, y);
}

if(mask & 0x02){
ctx.moveTo(x + w, y + h - r);
ctx.arc(x + w - r, y + h - r, r, 0, 0.5 * pi, false);
ctx.lineTo(x + w, y + h);
ctx.lineTo(x + w, y + h - r);
}

if(mask & 0x01){
ctx.moveTo(x + r, y + h);
ctx.arc(x + r, y + h - r, r, 0.5 * pi, pi, false);
ctx.lineTo(x, y + h);
ctx.lineTo(x + r, y + h);
}
ctx.closePath();
}
これで両脇を丸くしてやってTができます(外枠付与前)。



こんな感じで残りの、C、O、L、Eも一文字ずつちまちまと計算しながらデザインしました。
Eは、真ん中の横棒を浮かせるか根元に付けるか試して、最終的には浮かせることにしました。




さて、こんな風にすべてcanvasで描画できるのなら、そのままサイトに組み込んでしまえ、と最初はやりました。
canvasそのまま組み込んでもいいのですが、canvas上の描画された絵をimageとして使いたいので、「I」の字描画コードの最後でしてたようなことをやります。

しかし、ロゴというなるべく早く読み込まれて然るべきもの(と思う)をこんな処理してるのもどうかと思ったので、そうやって作った画像を名前をつけて保存してサーバにアップして画像として最初から読み込むようになってます。


こうして1文字ずつの画像はできましたが、今のicotileのsign in後に右上に出てるロゴなんかは、7文字繋がった1枚の画像になってます。
それもcanvas利用して作成してます。
 1.文字の画像をcanvasで描画
 2.image objectに
 3.横長canvasに2のobjectを適切な座標に読み込む
 4.1~3を ICOTILE ぶん繰り返す
 5.横長canvasを image object にして 最後はブラウザ上から「名前を付けて保存」
で、作ってます。

実際のものとは違いますが、たとえば上で作成した「I」の字を128pxじゃなくて36px版にして、7文字連結するコードはこうなります。
    var cnvs = document.createElement("canvas");
cnvs.width = 36;
cnvs.height = 36;
$("body").append(cnvs);

var ctx = cnvs.getContext('2d');

pi = Math.PI;
/* 角丸boxパス作成 */
var makeRoundRectPath = function(ctx, x, y, w, h, r){
ctx.beginPath();
ctx.arc(x + r, y + r, r, - pi, - 0.5 * pi, false);
ctx.arc(x + w - r, y + r, r, - 0.5 * pi, 0, false);
ctx.arc(x + w - r, y + h - r, r, 0, 0.5 * pi, false);
ctx.arc(x + r, y + h - r, r, 0.5 * pi, pi, false);
ctx.closePath();
}

/* 文字描画 */
ctx.translate(2, 2); /* canvas移動 */
makeRoundRectPath(ctx, 12, 0, 8, 32, 2);
ctx.fill();
ctx.translate(-2, -2); /* canvas移動戻す */

/* 外枠描画 */
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
makeRoundRectPath(ctx, 0, 0, 36, 36, 4);
ctx.stroke();

/* 画像オブジェクトに */
var imgObj = new Image(36, 36);
var imgSrcData = cnvs.toDataURL("image/png");
imgObj.src = imgSrcData;
$("body").append(imgObj);
$(cnvs).remove();

/* 横長canvas */
var cnvs = document.createElement("canvas");
cnvs.width = (36 * 7) + 6;
cnvs.height = 36;
$("body").append(cnvs);

ctx = cnvs.getContext('2d');

/* imageをcanvas上の指定位置に読み込む x 7回 */
for(var i = 0; i < 7; i++){
var x = (36 + 1) * i;
var y = 0;
ctx.drawImage(imgObj, x, y);
}
$(imgObj).remove();

/* 画像オブジェクトに */
var imgObj = new Image((36 * 7) + 6, 36);
var imgSrcData = cnvs.toDataURL("image/png");
imgObj.src = imgSrcData;
$("body").append(imgObj);
$(cnvs).remove();
これで258x36の右クリック保存可能なlogo画像ができました。


だいたいこのようにしてicotileの(sign in後の)ロゴ画像は作られました。
実際には、タイルの1辺のサイズを指定すればあとは各文字の描画位置を比率で計算してすべて描画されるようにスクリプトは書いています。
※canvas上に描く図形の座標がキリがいい数字になる(ことが多くなる)ように設計されてないと、意に反したクオリティの画像になる場合があります。

(sign in前のページのロゴ(Tの字がくるくるするやつ)の話は、またicotileのどこがhtml5か -CSS3アニメ編-としてでも書こうと思います)



まあ何面倒なことやってんだってことでもあるのですが、開発段階ではcanvasそのまんまでサイトに組み込んでみることで、文字の色とかサイズとか微調整だとかやりながら、デザインも行えてしまうという、(若干こじつけの)メリットがあります。
また、ブラウザとテキストエディタがあればデザインが行えるというメリットもあります。イラレやフォトショなどなくてもいいのです。

というわけで、「icotile のどのあたりが HTML5 なのか?」の番外編として、ロゴデザインワークが実はcanvasにて行われていた、というお話でした。


番外編な上にさらに番外:
勢い余って、ICOTILEフォントっぽいもの、作りました。すべての文字のための関数用意するのは時間かかりました。
そして案の定、使いどころないです。