css gridでドット絵を描こう 仕組み編
公開日 2018/05/14
今回はcss gridを勉強している時に、「あれ?これってめちゃめちゃ細かくすればドット絵描けるじゃん」と思い、ドット絵を描いたのでそれに関するナレッジシェアです。これを読み終わる頃にはあなたもcssドット絵職人です。
css gridで遊ぶぞ!
grid mario ver.1
まずはこれを見てください。(この段階は試行錯誤中なので真似しないでね)
Embedded content: https://codepen.io/ebifly/pen/qxREjK/
cssだけでマリオを描きました。
まず、マリオを描くためには12×16のドットが必要なので、htmlに192個のdivを書きます。
grid-template-rows: 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25% 6.25%;
grid-template-columns: 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33% 8.33%;
cssにはこのようにgrid-template-rowsに6.25%を16個grid-template-columnsを12個書きます。
表示領域に合わせてマリオを縮めようと思って%指定にしていたんですが、無理。
height:1600px;
width:1200px;
とにかくこれで正四角形が12x16個、用意出来ました。
この192個のdivひとつひとつにbackground-colorを設定していけばドット絵が完成するというだけのお話しです。
grid mario ver.2
ただ上記の方法だと、「〇列の〇行目はこの色…」とひとつひとつ順にブラウザとHTMLを見比べながら埋めていかないといけないため時間がかかり過ぎます。
例えば、背景に色入れたいから一回り大きくして14×18に書き直そう!なんて思った日には地獄が待っています。コードも見づらいです。
先程のコードにリファクタリングを掛けてもっとドット絵を描きやすくしてみました。
Embedded content: https://codepen.io/ebifly/pen/JLrMQL/
親要素の修正
まずはグリッドの親要素、ここでは「bl_mario」の内容を書き換えていきます。
$pixel:10px;
grid-template-columns: 1fr repeat(12, $pixel) 1fr;
grid-template-rows: repeat(16, $pixel);
ドットは常に正四角形且つ%指定が難しいので、変数にまとめました。
そして、columnsとrowsの指定にrepeatを使いました。
repeatはrepeat(数字, サイズ)で指定した「数字」の回数分「サイズ」を繰り返してくれる関数です。これで何度も同じ数字を打たなくて済みます。
つまり上記は
grid-template-columns: 1fr 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 1fr;
grid-template-rows: 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px 10px;
と同義です。
grid-template-areasを指定することで直感的にドットの配置が出来るようになります。
grid-template-areas :
"... ... ... ... r01 r01 r01 r01 r01 ... ... ... ..."
"... ... ... r02 r02 r02 r02 r02 r02 r02 r02 r02 ..."
"... ... ... g01 g01 g01 y01 y01 g02 y02 ... ... ..."
"... ... g04 y05 g03 y03 y01 y01 g02 y02 y04 y04 ..."
"... ... g04 y05 g03 g05 y01 y01 y06 g06 y04 y04 y07"
"... ... g07 g07 y08 y08 y01 y01 g08 g08 g08 g08 ..."
"... ... ... ... y09 y09 y09 y09 y09 y09 y09 ... ..."
"... ... ... g09 g09 r03 g10 g10 g10 ... ... ... ..."
"... ... g13 g09 g09 r03 g11 g11 r04 g12 g12 g12 ..."
"... g14 g14 g14 g14 r05 r05 r05 r05 g12 g12 g12 g15"
"... y10 y10 g16 r06 y11 r07 r07 y12 r08 g17 y13 y13"
"... y10 y10 y14 r09 r09 r09 r09 r09 r09 y15 y13 y13"
"... y10 y10 r10 r09 r09 r09 r09 r09 r09 r11 y13 y13"
"... ... ... r12 r12 r12 ... ... r13 r13 r13 ... ..."
"... ... g18 g18 g18 ... ... ... ... g19 g19 g19 ..."
"... g20 g18 g18 g18 ... ... ... ... g19 g19 g19 g21";
コードを見てもらえばわかるように、アスキーアートのようにコーディングできます。
さらにエリアの指定により1ドット1ドット丁寧に描いていたものが、「この範囲は赤(r01)。この範囲は緑(g01)。」のように範囲での着色が出来るのです。空白のエリアには「.」を書きます。
これによりHTMLの記述も少なくなります。
子要素
続いて子要素の変更点について触れていきます。
まずはHTMLに着目しましょう。
<div class="bl_mario">
<div class="bl_mario_itemRed1"></div>
<!—- bl_mario_itemRed13まで繰り返し -->
<div class="bl_mario_itemGre1"></div>
<!—- bl_mario_itemGre21まで繰り返し -->
<div class="bl_mario_itemYel1"></div>
<!—- bl_mario_itemYel15まで繰り返し —>
</div>
200行書いていたHTMLが50行程度に収まりました。
この時のポイントとしてはひとつひとつ真面目に書いてたら気が遠くなるのでエメットを利用して.bl_mario_itemRed$*13のように書くと一瞬です。エメットは$*数字で連番で展開してくれます。
続いてcssです。
$red: #db2900;
$green: #8a7301;
$yellow: #ffa33c;
@for $i from 1 through 21 {
&_itemRed#{$i} {
@if $i < 10 {
grid-area: r0#{$i};
} @else {
grid-area: r#{$i};
}
background-color: $red;
}
&_itemGre#{$i} {
@if $i < 10 {
grid-area: g0#{$i};
} @else {
grid-area: g#{$i};
}
background-color: $green
}
&_itemYel#{$i} {
@if $i < 10 {
grid-area: y0#{$i};
} @else {
grid-area: y#{$i};
}
background-color: $yellow;
}
}
HTMLで書いた連番のクラスをfor構文でまとめて指定しつつ、grid-areaの指定も同時に行っています。
もう少し噛み砕いて説明すると、
.bl_mario_itemRed01にgrid-areaのr01を指定。bgcの指定。
.bl_mario_itemRed02にgrid-areaのr02を指定。bgcの指定。
︙
.bl_mario_itemRed21にgrid-areaのr21を指定。bgcの指定。
(itemGre,itemYelも同様)
これにより親要素で指定していたgrid-template-areasに子要素達が収まり、色がつけられるようになります。
if構文になっているところは一桁の時は頭に0を付ける処理です。
仕組みとしてはこれだけです
補足
grid-areaの指定をわざわざ一桁の時に0を付与していることに気付いたと思うのですが、これは親要素のgrid-template-areasを見易くするという意図があります。
例えば、grid-areaの指定を「英字+数字(一桁の時に0を付けない)」空白箇所の「…」を「.」にすると
grid-template-areas :
". . . . r1 r1 r1 r1 r1 . . . ."
". . . r2 r2 r2 r2 r2 r2 r2 r2 r2 ."
". . . g1 g1 g1 y1 y1 g2 y2 . . ."
". . g4 y5 g3 y3 y1 y1 g2 y2 y4 y4 ."
". . g4 y5 g3 g5 y1 y1 y6 g6 y4 y4 y7"
". . g7 g7 y8 y8 y1 y1 g8 g8 g8 g8 ."
". . . . y9 y9 y9 y9 y9 y9 y9 . ."
". . . g9 g9 r3 g10 g10 g10 . . . ."
". . g13 g9 g9 r3 g11 g11 r4 g12 g12 g12 ."
". g14 g14 g14 g14 r5 r5 r5 r5 g12 g12 g12 g15"
". y10 y10 g16 r6 y11 r7 r7 y12 r8 g17 y13 y13"
". y10 y10 y14 r9 r9 r9 r9 r9 r9 y15 y13 y13"
". y10 y10 r10 r9 r9 r9 r9 r9 r9 r11 y13 y13"
". . . r12 r12 r12 . . r13 r13 r13 . ."
". . g18 g18 g18 . . . . g19 g19 g19 ."
". g20 g18 g18 g18 . . . . g19 g19 g19 g21";
こんな感じの下半身が太いおじさんになります。
表示上では問題無しですがこれでは、結合や位置関係が非常に分かりにくくドット絵を楽しく書けません。
grid-areaが100や1000を超えるようなものになった時には、一桁代も合わせて001や0001にする必要があるということです。
まとめ
以上で「css gridでドット絵を描こう 仕組み編」は終わりです。
cssでドット絵を描く方法は理解して頂けたかと思います。
次回は「css gridでドット絵を描こう 実践編」として、実際にドット絵を描く順序に沿って注意点なども紹介出来ればと思います。
何かおかしい所やcssドット絵ガチ勢の方がいましたらコメントにてよろしくお願いします。