[翻訳]CSSでドット絵を描いてみよう
Thanks Jacque Schrag!! ↓↓↓ジャック・シュラッグさんによる元記事↓↓↓
以下本編('ω')ノ
ドット絵は見るにも描くにも楽しいものです。ネット上のドット絵メーカーが出てくるまでは、Photoshopの鉛筆ツールで何時間もかけて描き上げていました。今回は、CSS(と、ちょこっとだけHTML)を使って、ドット絵を描くためのコードをご紹介しようと思います。
すごいぞbox-shadow
ドット絵というものは、<div>タグでブロッキングしたうえで背景の色を変えればできてしまうのですが、正直、<div>が多くなってしまうので、いろいろな場面で汎用的に使うには不便です。どちらかといえば、<div>は一つにして、あとはbox-shadowにおまかせしたほうがスマートです。
box-shadowといえば、普段は下図のようにエレメントの後ろに影をつけるのに使われます。
それでは、直線を描くにはこれをどのようにすれば効果的でしょう?
box-shadow定義からblurとspreadのパラメータを削除すると、下のように影の枠をくっきりさせることができます。
では次に、影がブロックの後ろではなく横に来るように移動させてみます。以下のやり方でXとYのオフセットを調整しましょう。
Xオフセット:
・正の値なら右に動く
・負の値なら左に動く
Yオフセット:
・正の値なら下に動く
・負の値なら上に動く
この影は、適用されているエレメントと同じ大きさになります。そのため、影をブロックの右側に移動するには、Xオフセットをブロックの幅と同じ20pxに設定する必要があります。 Yオフセットを0に変更すると、2つのブロックが並んでいるように見えます。
なんだかドット絵っぽくなってきましたね!しかしこれでは「2ドット」だけなので、もっと打っていかなくてはなりません。ただ、ありがたいことに、box-shadowの効果は1か所だけに限るわけではありません。カンマで区切ることによって、影をたくさん作れるので、よりドット絵っぽくなります。
さて、もうbox-shadowの使い方はわかりましたね。今度はガチのドット絵を描いていきましょう。
ドット猫を描こう
今回は、プシーンのドット絵版を作ってみます。ドット絵が初めての場合は、既存のものを検索して、ドットを配置する場所を確認することをお勧めします。このバージョンのプシーンドットに作り直してみましょう。
※神山注:かわいい!天才!!
こちらは計414ピクセル(縦23マス、横18マス)のドットで出来ています。 ドットをそれぞれ簡単に識別できるよう、Photoshopで画像の上にグリッドを重ねてみました。
ドット絵はどこからでも描き出せるものですが、私は左上から描き始めるので、box-shadowのネガティヴオフセットを気にせず描けます。
また、バニラのCSSを使って手でbox-shadowの宣言を書くよりは、私はSASSを使います。カスタム版SASSのファンクションやリストを駆使することで、オフセットのポジションを自動計算し、DRYを守ったコードが書けます。
それでは、#catのブロックに定義を書きましょう。疑似要素に適用したときに、box-shadowよりもブロックに対して関係する位置の定義といえます。どういうことかというと、catブロックの隣に他の要素を設けると、影の上部にその要素が居座ってしまい、結果的にbox-shadowのための場所がなくなってしまうんです。そこで、catブロックのサイズをドット絵の最終的なサイズにすれば、この問題は解決しますが、代わりにドット絵の縦横を各々明確にするのに疑似要素が必要になってきます(ここで思い出してほしいのが、「影の大きさは box-shadow が適用された大きさを継承する」ということです)。下図を見ていただくと変化がわかりやすいかと思います。
#cat {
position: relative;
width: calc(23 * #{$size}); // Pixel size * # of columns
height: calc(18 * #{$size}); // Pixel size * # of rows
margin: 1rem;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: $size;
height: $size;
// box-shadow will be applied here
}
}
次に、変数に値を設定してみましょう。
// 今回のドット絵のピクセルサイズ
$size: 20px;
// 色の設定
$t: transparent;
$black: #000;
$gray: #cdc9cf;
$dkgray: #a09da1;
$pink: #ffa6ed;
では、それぞれのドットを何色にするか管理するリストを作りましょう。まずは1列目用のリストを左から設定します。
$first: ($t, $t, $t, $black, $t, $t, $t, $t, $black);
以降の列に関しては、それぞれ別の変数($second、$thirdといった具合で)を作ってもいいですが、入れ子のリストを作るほうがおすすめです。
$cat: (
($t, $t, $t, $black, $t, $t, $t, $t, $black),// 1列目
($t, $t, $black, $gray, $black, $t, $t, $t, $t, $black, $gray, $black)// 2列目
// 以下、列を追加していく
);
入れ子のリストを使うことで、box-shadowの効果をセルそれぞれに対して生成するのに必要な情報が一挙に管理できるという利点があります。XとYはオフセットと影の色を割り出すのに使えます。この情報を管理させる”pixelize”関数をカスタムしてみましょう。
ドット絵にあえてSASS
今回の”pixelize”に関しては、色付けを管理しているリストを使いやすいbox-shadow定義に落とし込むのが重労働ですので、この関数の内容を細かく以下で説明してみます。
@function pixelize($colors, $size) {
$result: '';
$numRows: length($colors);
@for $rowIndex from 1 through $numRows {
$y: ($rowIndex - 1);
$row: nth($colors, $rowIndex);
$numCols: length($row);
@for $cellIndex from 1 through $numCols {
$x: ($cellIndex - 1);
$color: nth($row, $cellIndex);
$sep: ', ';
@if $x == 0 and $y == 0 {
$sep: '';
}
$result: $result + '#{$sep}#{$x * $size} #{$y * $size} #{$color}'
}
}
$result: unquote($result);
@return $result;
}
◆1行目: この関数では、引数を2つ(ドット絵で使う、$colorsと$sizeのリスト)使います。
◆2行目: $result変数をstring形として初期化しています。関数の中で変更され、返されてくる変数です。
◆3行目: 既存のlength関数を使って、リストの列の数を返します。
◆5行目: リストの中にある列の数だけ繰り返すループを回します。$rowIndex がループ内で1だけインクリメントしていきます。
◆6行目: 列にあるセルすべてのY軸オフセットを割り出します。SASSにおけるリストは、index-0でなくindex-1なので、現行のindexから1を引きます。そうすることで、1列目に0のYオフセット、2列目に1のYオフセットといった具合で値を持つことになります。
◆7、8行目: そのときのリスト(その列の色を持つリスト)の値を返して、列に対する行の数を確定する方法として、長さを割り出します。
◆10行目: その列における行の数だけ繰り返すループを回します。
◆11、12行目: そのセルのXオフセットを割り出して、それに対応した色を返します。
◆14~17行目:box-shadow用にセパレーターを用意します。ただ、プロパティの値が有効であることを確認するために、最初のセルではこれを除きます。
◆19行目: $resultの値を、新しいセルを加算した現在の値へ上書きします。
・セパレーター
・Xの位置 * $size = Xオフセット
・Yの位置 * $size = Yオフセット
・色
◆23、24行目: $resultはstring形のため、unquote関数でクォーテーションを取り除いてから、$resultのを返します。
CSSでドット絵描けた!!
これらを合わせて、ついにプシーンドットの出来上がりです!
これいい感じじゃないですか?!プラスアルファで、リファクタリングしたりCSS変数を使ってみたり、JavaScriptを盛り込んでみたりなんかすれば、ユーザそれぞれが、それぞれの猫ちゃんたちの色を選ぶこともできちゃいますね。
今回の投稿が、みなさんのドット絵作りの励みになれば幸いです。仮にそうならなくても、皆さんが今回学んだbox-shadowを使って、各プロジェクトで活躍してくださることを祈っています。ドット絵がもっと見たいという方や、さらに動くドット絵も気になるという方は、CSS-TricksのGeoff Grahamさんによる"Fun Times with CSS Pixel Art"(←の記事を神山が翻訳したものがこちら)が詳しいのでチェックしてみてくださいね。
以上(*'ω'*)