css3のtext-shadowだけでモナリザを描いてみた


はいー、できましたー。text-shadowを1ピクセルごと配置してモナリザを表現しています。
これまでいくつか「cssだけで◯◯」を見てきましたがあんなのはハッタリです。タグ使いまくりで全然cssだけじゃありません。この手法を使えばテキストとcssがあれば再現できます!

ジェネレータも作ったので、よかったら遊んでみてください。windowsのChrome6 devとFirefox3.6.6で動作確認していますが、Chromeはtext-shadowの描画が遅いので、Firefox推奨です。


Mona Lisa de text-shadow (CSS) - gallery
注意: Firebugなどでcssを見ると応答なしになったり場合によってはクラッシュするのでしっかりと準備して自己責任でお願いします。

モナリザの原理

text-shadowはテキストの影を演出するものです。構文は以下のようになっていて、コンマで区切れば複数の影を付けることが出来ます。(色が先頭でもいい)

text-shadow: x座標  y座標  ぼかし半径  色;

座標はテキストとtext-shadowの位置も調整できるようにoffsetを計算しながら、色はピクセルごとにgetImageDataメソッドを使って取得していくとモナリザcssが出来上がります。


ジェネレータ動作の流れ

処理はすべてクライアント側で。

  1. 画像をdataURLにしてcanvasに読み込む。
  2. getImageDataメソッドでピクセルごとの色を取得する。
  3. 取得したデータからtext-shadowの構文を組み立てる。
  4. cssを適用しtext-shadowを描画する。

工夫したところ、気付いたこと

  • 画像のdrag&drop読み込み。
  • 読み込む画像が大きいと処理が大変なので、幅・高さが最大で150pxになる安全設計。
  • imgのパスは同一ドメインでhttp:から始まるものじゃないとSecurity errorがでる。sinatraを使ってローカルサーバで開発した。結局はdrag&dropで読み込めるようにするためにdataURLを使うことにした。
  • getImageDataはimg.onload中じゃないと動かない。(そうしていないサンプルがあった)
  • FirefoxcanvasのImageDataオブジェクトをfor..inするとなにも出力されなかった。Chromeはみれた。プロパティは data、width、height。
  • canvasのwidth,heightはcssとごっちゃにするな。
  • canvasのdrawImage関数は引数のパターンが3つあって、画像を任意のサイズで読み込めたり、よく考えて作られていると思った。
  • textareaに大量の文字列を挿入するときは、一旦 display:noneした方が処理が速い。
  • input type="text"の横幅はsize属性じゃなくてcss widthで指定したほうがいい。chromeがsizeを無視する。
  • サンプルコードとして出力した大量のhtml文字列をdataスキーム化してwindow.openしてみたら重すぎて使い物にならなかった。
  • display:blockでもbox-shadowは適用される。
  • tipsy(tooltip,吹き出し)、jQuery spinbox、jQuery UI tabsの使用や、ボタンのライトアップで次の動作を示したりユーザビリティを意識して作った。
  • herokuで公開するのは便利。
  • Firefox4は3.6.6に比べてtext-shadow描画速度が気持ち速くなった。
  • ぼかし半径は小さい方が速く描画できる。