2017月09月05日

CSS3D!まるでWebGLのような3Dを超気軽に実装するCSS技

CSSでWebGLライクな3D表現は可能か?

ご覧ください、 可能 です。
ただし、できない(苦手とする)こともあります。

See the Pen OnlyCSS: Cube 3D Twister by Yusuke Nakaya (@YusukeNakaya) on CodePen.

やったこと

この記事の 3D表現 とは、単純に perspective + transform プロパティで「1つの要素を立体的に表示する」だけではなく、 「立方体を描画して、回転などの表現を加える」 事を目指しています。
立方体のコントロールについて、CSSだけでどこまで可能か、研究してみました。

立方体を描画する

親要素に transform-style: preserve-3d; を指定すると、 親要素の3D変形を継承して子要素の3D変形も有効 になります。
これは言葉では説明しにくいので、下のサンプルをご覧ください。
白いパネルが親要素、オレンジのパネルが子要素で、指定の有無による違いを確認できます。
このプロパティを使って、立方体を組み立てます。

See the Pen transform-style: preserve-3d; by Yusuke Nakaya (@YusukeNakaya) on CodePen.

ただし、いつも通りですが IE11ではサポートされてない ので、実務レベルではまだ注意が必要です。
Edge はOKなようです。

Can I use
http://caniuse.com/#search=transform-style

できる:サイコロを作る

キューブ は比較的簡単に表現できます。
6枚の壁をそれぞれ適切に配置し、回転させています。
CSSらしいテクニックとして borderborder-radius でエッジ部分を工夫したり、 filter: drop-shadow(); で描画を複製していて、右のサイコロは実体のない影です。

See the Pen Only CSS: Double Dice by Yusuke Nakaya (@YusukeNakaya) on CodePen.

できる:クリスタルを作る

Sass(SCSS)なら演算もできるので、 計算によるピラミッド も比較的容易に表現できます。
ピラミッドを上下反転して重ね合わせ、クリスタルのような形に仕上げています。
CSSらしいテクニックとして borderdouble を指定して、テクスチャの中央が抜けた、不思議なデザインにしています。
また、壁に filter: drop-shadow(); を指定し、かつアニメーションをかけ、光っているようなイメージを表現しています。

See the Pen OnlyCSS: Shining Crystal by Yusuke Nakaya (@YusukeNakaya) on CodePen.

できない:複雑なポリゴンを作る

とあるロボットアニメの 頭部パーツのアレ を再現してみました…が、失敗しました。
複雑なポリゴン制御は、かなりの時間を浪費してしまうかもしれません。
当初はロボット全体の構築を考えていましたが、 それはもうUnityとかWebGLでやった方が良い と思います(笑)。
数学が得意で時間が潤沢にあれば理論上は可能ですから、興味があればチャレンジしてみてください。

See the Pen OnlyCSS: Gundam Antenna by Yusuke Nakaya (@YusukeNakaya) on CodePen.

注意する:アニメーションとパフォーマンス

立方体を縦横無尽にアニメーションさせると、まさにWebGLのような表現になります。
ただし、 壁(要素数)が増えるとカクツキなどが目立ってくる ので、やりすぎ注意。
以下のサンプルはただキューブが並んでるだけですが、要素数で言うと450個。PCスペックによってはちょっとツラいかもしれません。
ちなみに、少しのカクツキなら transform-duration を小さくする(速く動かす)と、ある程度なら誤魔化せます。

See the Pen OnlyCSS: Cube 3D by Yusuke Nakaya (@YusukeNakaya) on CodePen.

CSSで3Dする時に気をつけること

1. 気軽に立体化できない

Three.jsのgeometryのように 気軽な感じで立体オブジェクトを扱えません
例えば、ただのキューブでも6枚の壁(要素)が必要で、1枚ずつ位置や回転を指定していく必要があり、この作業は正直、面倒です。

2. 曲面や球面は難しい

球体や円錐など、カーブしている面は難しい です。
理論上は細かくポリゴンを貼り込んでいけば可能っちゃ可能ですが、要素数が増える分だけ描画パフォーマンスが悪化します。

3. 光の再現は難しい

ライトやシャドウなど 相互関係を維持した光源処理は難しい です。
background: linear-gradient;filter: blur(); などを駆使して、手動で擬似的に再現しなければいけません。

4. mix-blend-mode とは同居できない

mix-blend-mode: screen; を指定すると transform-style: preserve-3d; が無効化されました。
まだ詳しく調査してませんが、他にも同居できないプロパティがあるかもしれません。

まとめ

CSSのみで、3D表現も可能です。

  • ただのCSSなので スマートフォンでも(そこそこ)動く
  • ただのCSSなので 様々なプロパティの応用で広がる可能性
  • ただのCSSなので WebGLより学習コストが低い と言うか CSS知識だけで今すぐできる
  • ただのCSSなので 曲面や球面などを含む複雑なポリゴンは無茶 、WebGLベースでどうぞ
  • いつも通りですが IE11ではできない ので実務で使う際は注意

CSSの世界は、制限がありながらも非常に奥深く、まだ見ぬ可能性にあふれています。
できることと、できないことの境界線を見極め、ギリッギリを攻めていきましょう!

CODEPENで色々サンプル公開中

CODEPEN
https://codepen.io/YusukeNakaya/
よかったらフォローしてください!

RELATED POSTS