このサイトのドット絵——ロゴの星、モード切替のアイコン、浮かんでいる月や雲——は、画像ファイルではありません。すべて文字列のグリッドから canvas に描画しています。
スプライトは「読めるデータ」で持つ
ドット絵の定義はこれだけです。1文字が1ピクセル、. は透明、他の文字はパレットの色に対応します。
const star = {
palette: { A: "#ffe7a3", C: "#ffffff" },
rows: [
"...A...",
"...A...",
"..AAA..",
"AAACAAA",
"..AAA..",
"...A...",
"...A...",
],
};
この形式の良いところは、コードがそのままドット絵のプレビューになることです。差分レビューでも形の変化が一目で分かり、「月をもう少し太く」のような修正依頼にエディタだけで応えられます。
描画は fillRect を並べるだけ
レンダラーはTypeScriptで20行ほどです。グリッドを走査して、透明以外のマスを拡大率ぶんの矩形で塗ります。
for (let y = 0; y < rows.length; y++) {
for (let x = 0; x < rows[y].length; x++) {
const color = palette[rows[y][x]];
if (!color) continue;
ctx.fillRect(x * scale, y * scale, scale, scale);
}
}
image-rendering: pixelated を添えれば、拡大してもエッジはくっきりしたままです。
マークアップ側は宣言だけ
使う側は data 属性を書くだけにしました。起動時に走査して、該当箇所へ canvas を差し込みます。
<span data-pixel="moon" data-scale="7"></span>
絵柄と倍率がHTMLから読めるので、装飾の配置換えにスクリプトの修正が要りません。
画像ゼロ運用の副産物
- アイコンの色をテーマに合わせて差し替えるのも、パレットの変更だけ
- 転送量はスプライト定義の数百バイトのみ
- 「サイトと同じ筆致で」新しいアイコンを増やせるので、デザインの統一感が崩れない
最後の点は思った以上に効きます。既製のアイコン集を混ぜると途端に「borrowed感」が出ますが、同じエンジンから生まれた絵は自然と馴染みます。