29
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

近畿大学Advent Calendar 2019

Day 11

立方体を描画してみよう!CSSだけで3D表現【フロントエンド】

Last updated at Posted at 2019-12-10

#はじめに
今回は,WebGL等を使わないで,単純な3DオブジェクトをCSSだけで描画する方法についてご紹介しようと思います.

#CSSでの3D表現の特徴
確かに複雑なオブジェクトを作るのであれば,WebGLを使うのが好ましいでしょう.
しかし,CSSでやる良さもあるので,主なメリットとデメリットを以下に記述します.

  • CSSで3Dをやるメリット

    • 直感的に作れる.
    • イベントなどを設定しやすい.
    • 見た目をCSSで簡単に変更できる.
  • CSSで3Dをやるデメリット

    • 複雑な立体は作るのが大変.
    • 曲線のある立体は作るのが難しい.
    • 複雑なものを作ると時間が溶ける.

####立方体のサンプル

See the Pen 3D Box by AO2324 (@AO2324) on CodePen.

####円柱のサンプル

See the Pen 3D Cylinder by AO2324 (@AO2324) on CodePen.

####クリックイベントをつけた立体のサンプル

See the Pen 3D Box has event by AO2324 (@AO2324) on CodePen.

#使用するCSSプロパティ
  • transform-style
  • transform
  • perspective

###transform-style (描画形式)
子要素の変形を立体的に描画するか平面的に描画するかを指定します.

平面的(初期設定)
transform-style:flat;
立体的
transform-style:preserve-3d;

See the Pen 3D Box (Flat / 3d ) by AO2324 (@AO2324) on CodePen.

###transform (要素の移動や回転)
transformプロパティを使用することで,要素を平行移動や回転,拡大など,変形させることができます.

指定方法は,transformの後にどう変形させるかを続けて記述します.
transform: 変形1 変形2;
変形の書き方
変形の種類+基本とする軸(値)

  • 変形の種類
    • translate : 平行移動
    • rotate : 回転
    • scale : 大きさ
    • skew : 傾斜
  • 基本とする軸
    • X : x軸
    • Y : y軸
    • Z : z軸
    • なし : ()の中にx軸とy軸をカンマ(,)で区切って表記
    • 3d : ()の中にx軸とy軸とz軸をカンマ(,)で区切って表記
サンプル
transform: translateX(50px) translateY(100px) rotateZ(90deg);
/* x軸方向に50px,y軸方向に100px平行移動したのち,z軸を中心に90度回転 */
transform: translate(50vw, 50vh);
/* x軸方向に50vw,y軸方向に50vh平行移動 */

###perspective (遠近感)
3Dのオブジェクトに遠近感をもたせます.
数値が小さいほど魚眼レンズのようになり,大きければ大きいほど全ての幅が均等になります.
スクリーンショット 2019-12-10 23.35.30.png
perspective:200px;
スクリーンショット 2019-12-10 23.20.10.png
perspective:10000px;
数値が小さい(200px)と上のような見え方に,数値が大きい(10000px)と下のような見え方になります.
個人的には 800px ~ 1000px くらいがちょうどいい気がします.
スクリーンショット 2019-12-10 23.20.28.png
perspective:1000px;

#実際に立方体を作ってみよう!

###Step1
まず,HTMLで立体の面となる要素を定義してあげます.

html
<div id="scene">
  <div class="boxBase">
    <div class="top"></div>
    <div class="bottom"></div>
    <div class="front"></div>
    <div class="back"></div>
    <div class="left"></div>
    <div class="right"></div>
  </div>
</div>

ここで,sceneは3Dオブジェクトを表示する場所,boxBaseは立方体,その中の要素は立方体のそれぞれの面を表しています.
これをCSSのtransformを使って変形することで,ペーパークラフトのように立体を作ることができます.

###Step2
何も指定しないと平面的に描画してしまうので,transform-style:preserve-3d;をboxBaseに設定して,子要素を立体的に表示するようにしてあげましょう.
ここで,一辺の長さも決めてしまいましょう.

css(1/4)
.boxBase {
  transform-style:preserve-3d;
  width:200px;
  height:200px;
}

###Step3
立方体の面となる要素の設定を行い,ついでに色や縁にもスタイルを適応させましょう.

css(2/4)
.boxBase > div {
  position:absolute;
  width:100%;
  height:100%;
  background-color:rgba(100, 100, 100, 0.7); /* 面の色 */
  border:0.5px solid black; /* 縁 */
}

###Step4
それぞれの面を変形して,立方体を組み立てていきましょう.

css(3/4)
.boxBase > .top {
  transform:translateY(100px) rotateX(-90deg);
}
.boxBase > .bottom {
  transform:translateY(-100px) rotateX(90deg);
}
.boxBase > .front {
  transform:translateZ(100px);
}
.boxBase > .back {
  transform:translateZ(-100px) rotateX(180deg);
}
.boxBase > .left {
  transform:translateX(-100px) rotateY(-90deg);
}
.boxBase > .right {
  transform:translateX(100px) rotateY(90deg);
}

###Step5
perspectiveで遠近感を調整しましょう.

css(4/4)
#scene {
  perspective: 1000px;
}

###立方体の完成

立方体(htmlファイル)
<div id="scene">
  <div class="boxBase">
    <div class="top"></div>
    <div class="bottom"></div>
    <div class="front"></div>
    <div class="back"></div>
    <div class="left"></div>
    <div class="right"></div>
  </div>
</div>

<style>
#scene {
  perspective: 1000px;
}
.boxBase {
  transform-style:preserve-3d;
  width:200px;
  height:200px;
}
.boxBase > div {
  position:absolute;
  background-color:rgba(100, 100, 100, 0.7);
  border:0.5px solid black;
  width:100%;
  height:100%;
}
.boxBase > .top {
  transform:translateY(100px) rotateX(-90deg);
}
.boxBase > .bottom {
  transform:translateY(-100px) rotateX(90deg);
}
.boxBase > .front {
  transform:translateZ(100px);
}
.boxBase > .back {
  transform:translateZ(-100px) rotateX(180deg);
}
.boxBase > .left {
  transform:translateX(-100px) rotateY(-90deg);
}
.boxBase > .right {
  transform:translateX(100px) rotateY(90deg);
}
</style>

アニメーションをつけてあげると立体になっている事がよくわかるので,ぜひ試してみてください.

立方体のアニメーション
#scene {
  perspective: 1000px;
  width:200px;
  height:200px;
  position:relative;
  top:50vh;
  left:50vw;
  transform:translateX(-50%) translateY(-50%);
}
.boxBase {
  transform-style:preserve-3d;
  width:200px;
  height:200px;
  animation: turnAround 30s linear 0s infinite normal none running;
}
@keyframes turnAround {
  0%{
    transform:rotateX(0deg) rotateY(0deg);
  }
  100%{
    transform:rotateX(360deg) rotateY(360deg);
  }
}

See the Pen 3D Box by AO2324 (@AO2324) on CodePen.

#最後に
今回はCSSでの3D表現のざっくりとした説明と,簡単な立体の作り方を書かせていただきました.
これだけだと,実際のWebページやアプリ開発でどのように活かせるかわからないかもしれません.
ですが,発想次第ではいろいろな事ができるので,ぜひCSSでもっともっと遊んでみてください.
スクリーンショット 2019-12-11 1.34.08.png
↑人型の立体物 ↓Webサイトのナビゲーション
スクリーンショット 2019-12-11 1.32.15.png

#参考
CSS3D!まるでWebGLのような3Dを超気軽に実装するCSS技 (中矢 雄介/Creator)

29
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?