この記事は、CSS Advent Calendar 2018 - Qiitaの19日目の記事です。
まずはじめに
みなさんWebで画像を表示させるときどうしていますか?
基本は
<img src="sample.png" />
これですよね。
それ以外にも画像を表示させる方法はいろいろ。
画像を表示させる方法
わりと使うのがbackground-image
に指定してあげるやつ
<div class="main-image"></div>
<style>
.main-image {
background-image: url("http://...")
}
</style>
次はbase64エンコードされたやつを埋め込むやつ。
小さい画像なら埋め込んだ方がユーザ体験がよくなったり(?)するのでわりと使うことあるらしい(?)画像をbase64エンコードしてあげてその文字列をsrc
内に書けば画像を表示できます。以下のエンコーダが便利です。
<img src="data:image/png;base64,xxxxx..." />
基本は上の3つぐらいだと思います。(SVGとか,canvasはさておき)
本編: box-shadowで画像を表示する
ところで、box-shadow
を使うとドット絵がつくれます。
話はわりと簡単で、要素自体を透明にしちゃって影でピクセルを作っていこうというそれだけのはなし。
これが
<div class="pixel-art"></div>
<style>
.pixel-art {
background: transparent;
width: 10px;
height: 10px;
box-shadow:
0 10px red,
10px 20px blue,
20px 10px green;
}
</style>
![スクリーンショット 2018-12-13 14.58.54.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F0faaf236-02cc-49cc-c06e-9e24920b363b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a0de24e75d07fa036a1cdbfde1dd4128)
こうなる。
画像のピクセル全部打ったらbox-shadowだけで画像になるじゃんっていうのが今回の話の原点。
というわけでジェネレーターをVue.jsを使ってつくってみた。
See the Pen CSS PixelArt Generator by いーふとイチオカ🔰(@redshoga) (@redshoga) on CodePen.
画像を入力すると画像のすべての画素をbox-shadow
に変換して、もとの画像が表示できるhtmlファイルが取得できるようになります。わりとCPUを食うので低スペPCの人はご注意。
比較実験: 表示
今回はプロ生ちゃんの画像を使います。(400x400[px]に切り抜いています)(PNG形式で192KB)
かわいい。
これを3つのソースで、表示を比較してみます。
1つめ、<img>
使うやつ(74バイト+画像(192KB))
<!DOCTYPE html>
<html>
<body>
<img src="./puronama.png">
</body>
</html>
![スクリーンショット 2018-12-13 15.21.44.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F1b6310a7-43d1-232d-d020-708dc98b411a.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=bc72567e62c5aaff73fcac8a8a79ecd0)
2つめ、backgroud-image
使うやつ(200バイト+画像(192KB))
<!DOCTYPE html>
<html>
<body>
<div class="image"></div>
<style>
.image {
width: 400px;
height: 400px;
background-image: url("./puronama.png")
}
</style>
</body>
</html>
![スクリーンショット 2018-12-13 15.21.49.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F8a551811-2144-5570-b253-b821af63ec7c.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=537d615cb36b31441500f425ee97491f)
3つめ、box-shadow
で書くやつ(5.8MB)
ちなみに処理の都合上1px下にずらしてます。
<div class="pixel-art"></div>
<style>
.pixel-art {
background: transparent;
width: 1px;
height: 1px;
box-shadow: 0px 1px rgba(255, 255, 255, 255), ...
}
![スクリーンショット 2018-12-13 15.21.53.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2Ffe2f1a6c-c64c-9627-fb83-23f9957214a3.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=52ca888814b9d4cee6590e95c24c0668)
表示が変わるはずはない。
ちなみにbox-shadow
で書くやつを拡大するとしましまが見えたりします。<img>
とかでちゃんと書くとブラウザかOSがここらへんをいい感じにやってたんだなあっと関心。
![スクリーンショット 2018-12-13 15.28.12.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F991af6ff-268d-5c33-d874-248b93eb63e3.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=011d330a226bd59e8024cb8c8a50ebfb)
比較実験: CPU使用率
やってて気が付いたのがbox-shadow
で画像を書くやつ。表示が遅すぎる。(当たり前だよなぁ) それで画像の描画終了までのChrome DevToolsのPerformanceを見てみた。
1つめ、<img>
使うやつ
![スクリーンショット 2018-12-13 15.26.16.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F75896f5e-859b-a4ef-74d3-b628e01bdf51.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=1be3e8d591272efb44a30b5bf2355f68)
2つめ、backgroud-image
使うやつ
![スクリーンショット 2018-12-13 15.25.54.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2Fca75610c-5056-0094-8946-6db1b2b6548e.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=8514b4dd7b3024e8af69918636cc6364)
3つめ、box-shadow
で書くやつ
![スクリーンショット 2018-12-13 15.27.37.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F91558%2F0522aa3c-a993-bd64-7390-e963875155c8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=701098d8577edaf2bcd52aa5d2c9306e)
LoadingとPaintingに時間がだいぶかかってる。
そもそも、<img>
使うやつとbackgroud-image
使うやつはローカルのファイルを引っ張って表示、それに対してbox-shadow
で書くやつは自分のコード自身に画像データが入っているので、なんともいえない比較ですね。
とにかく10倍程度描画速度に差があることがわかりました。(たぶんCPU性能に依存してます。)
おわりに
CSSはアニメーションがいろいろできます。そのため、今回の作成したやつを使えばbox-shadow
にアニメーションをつけて...なんて使い方はしないですね。たぶん。
box-shadow
で画像を描画するのはふたつの意味でヨウリョウが悪いですね。(おしりおわり)