Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

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

はじめに

今回は,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)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
10
Help us understand the problem. What are the problem?