ELAB.

box-shadowを使ったPixel Artをやってみる

2014.12.23

“Pixel Art and Complex Systems” at JSAsia 2014 in Singapore.

Bit-Shadow Machine - Sheep vs Wolves vs Zombies from Vince Allen on Vimeo.

早速ですが、最近このPixel Artに感銘をうけました。

先日11月に開催されていた、JSConf.Asia Singapore 2014にて、@vinceallenvince氏のプレゼンで紹介されていたものです。

残念ながら参加はできなかったのですが、同僚のFBや参加レポートを見たり、社内報告会を聞いたりして、これは見たかった、、と思った次第。

http://ameblo.jp/dikkey/entry-11954954525.html
http://1000ch.net/posts/2014/jsconf-asia-2014-1st.html

これらのレポートでも触れられている通り、表現されているものが素晴らしいだけでなく、その実装をcanvasなどではなく、なんとbox-shadowを使ってPixel Artを描画してみたというもの。

box-shadowでそんなことができるのかー、というわけで、ちょっとデモを作ってみました、というエントリーです。

デモ

早速ですが、デモとしてライフゲームを作ってみました。
[start]ボタンをクリックすると始まります。

See the Pen LERYKq by ktknest (@ktknest) on CodePen.

ライフゲームとは、wikipediaから引用すると、

ライフゲーム (Conway’s Game of Life[1]) は1970年にイギリスの数学者ジョン・ホートン・コンウェイ (John Horton Conway) が考案した生命の誕生、進化、淘汰などのプロセスを簡易的なモデルで再現したシミュレーションゲームである。単純なルールでその模様の変化を楽しめるため、パズルの要素を持っている。

生物集団においては、過疎でも過密でも個体の生存に適さないという個体群生態学的な側面を背景に持つ。セル・オートマトンのもっともよく知られた例でもある。

http://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0

というもので、詳しく知りたい方は各自ググってみてください。

解説

ここから、box-shadowを使ったドット描画の仕組みについて説明していきます。

例えば左上を起点にして(20px, 10px)の位置に2pxのドットを描くのには、以下のようなスタイルで表現できます。

See the Pen YPGzBb by ktknest (@ktknest) on CodePen.

CSS

.frame {
  position: relative;
  background-color: #000;
  width: 100px;
  height: 100px;
}

.canvas {
  position: absolute;
  left: 1px;
  top: 1px;
}

HTML

<div class="frame">
  <div class="canvas" style="box-shadow: 20px 10px 0 1px #f00;"></div>
</div>

参考: box-shadowの構文

box-shadow: <offset-x> <offset-y> <blur-radius> <spread-radius> <color>

https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow

コードだけだとよく分からないので詳しく追ってみます。

まず、<div class="canvas">自体は幅&高さが0pxの空divです。
インスペクタでみるとこんな感じです。

これに対して、box-shadowを使い、水平方向に20px、垂直方向に10pxのオフセットを与えた影を落とします。さらに、<blur-radius>(ぼかし)は0として、<spread-radius>(広がり距離)は1pxとして指定すると、先ほどのようなドットが描かれます。

なお、以下の図解のように、ドットはオフセット値を起点として<spread-radius>の値の分、上下左右に広がるため、最小サイズは2pxとなります。

これに加えて、位置調整のため、<div class="canvas">に対して、top/leftで微調整をして位置を合わせています。

さらに、box-shadowはカンマ区切りで複数指定できるため、ドットの数の分だけ指定することで、好きなようにドットを描画できます。先ほどのデモはこれを1ステップ毎に演算し、都度styleを置き換えて実現したものです。

複数ドットの指定例

See the Pen YPGzgb by ktknest (@ktknest) on CodePen.

HTML

<div class="frame">
  <div class="canvas"
       style="box-shadow: 10px 10px 0 1px #f00,
                           8px 10px 0 1px #f00,
                          10px  8px 0 1px #f00,
                          10px 12px 0 1px #f00,
                          12px 10px 0 1px #f00;">
  </div>
</div>

おわりに

今回の習作では、イチからスクラッチで書いてしまっていますが、@vinceallenvince氏より、Bit-Shadow-Machineというフレームワークも公開されています。

正直、この描画まわりの実装よりも、ライフゲームのアルゴリズムを組み立てるのに最も苦戦してしまったのですが、、色々とボロがあるであろう点についてはご容赦ください(汗

以上、Frontrend Advent Calendar 2014 23日目の記事でした。

参考記事

https://github.com/vinceallenvince/jsasia2014
http://vinceallenvince.github.io/jsasia2014/
https://github.com/vinceallenvince/Bit-Shadow-Machine
http://ameblo.jp/dikkey/entry-11954954525.html
http://1000ch.net/posts/2014/jsconf-asia-2014-1st.html

Tweet このエントリーをはてなブックマークに追加