Help us understand the problem. What is going on with this article?

CSSで奥行のあるキューブを表現するための手順

More than 1 year has passed since last update.

See the Pen CSS- CUBE by hamamoto_abc (@hamamoto_abc) on CodePen.

CSSで何かビジュアル的に面白そうな表現のものないかなと探していたのですが、ネット探すと以下のHPがあったので見てみたのですがなかなか凄いです!
 ------------------------
 CSS3D!まるでWebGLのような3Dを超気軽に実装するCSS技
 https://dev.oro.com/posts/2017/09/design/css_3d/
 ------------------------
コードも参照出来て非常に勉強になったのですが、解説までは書かれてないので私が勉強した内容を纏めてみました。

※ ここで記載するコードは上記HPの「サイコロ」を参考に勉強した内容を元に、私でも理解しやすいように変更してあるので上記HPのオリジナルのものとは違います。

まずは、キューブの前後の面を用意。

See the Pen CSS-CUBE-1 by hamamoto_abc (@hamamoto_abc) on CodePen.

<div class="cube">
    <div class="面">
        <div class="前"></div>
        <div class="後"></div>
    </div>
</div>
<div id="目印"></div>
<style>
.cube {
    position:absolute; top:100px; left:100px;
    font-size: 70px;
}
.cube>.>* {
    position:absolute; top:0; left:0; width:100px; height:100px;
    border:10px double silver; border-radius:20px;
    background-color:yellow; opacity:0.3;
}
#目印 { position:absolute; top:0; left:0; width:100px; height:100px; background-color:black; opacity:0.1; }
</style>

「cube > 面 > 各面...」という形で用意します。のちにそれぞれ役割が出てきます。
※ x,y が100pxの位置をベースに組み立てるので #目印 はそのための確認用です。

この状態では "各面" は absolute になっているので基点(x,y=100px)に重複して表示されます。

キューブの中心をイメージして、そこを基準に面を移動する。

See the Pen CSS-CUBE2 by hamamoto_abc (@hamamoto_abc) on CodePen.

ここからは、頭の中にイメージを思い描くことが大事になってきます。
キューブを表現したいので、まず「前面」を手前に移動 translateZ(50px) して、「背面(後面)」は後方に移動 translateZ(-50px) してから裏返し180度回転 rotateY(180deg) します。

.cube>. { perspective: 400px; }
.cube>.>. { transform: translateZ( 50px);                 }
.cube>.>. { transform: translateZ(-50px) rotateY(180deg); }

perspectiveは "視点" らしいです。視点の位置ですかね。離れて見るのか近くで見るのか。
近くで見ると空に伸びる巨大なスカイツリーでも、遠くからみると俯瞰してツリーの全体像が見えるという感じだと思います。

この値を小さくしていくと、どんどん近くから見るような感じで表現されるので見え方は巨大になっていきます。
.前 は 50px 前方にあるので perspective をそれより小さくすると視点が.前を追い越してしまうので見えなくなります。

上、下、左、右 の面を作る。

See the Pen CSS-CUBE-3 by hamamoto_abc (@hamamoto_abc) on CodePen.

<div class="上"></div>
<div class="下"></div>
<div class="左"></div>
<div class="右"></div>
.cube>.>. { transform: translateY(-50px) rotateX(  90deg); }
.cube>.>. { transform: translateY( 50px) rotateX( 270deg); }
.cube>.>. { transform: translateX(-50px) rotateY( -90deg); }
.cube>.>. { transform: translateX( 50px) rotateY(-270deg); }

上 ⇒ 上へ移動 translateY(-50px) して、上を向かせるために90度回転 rotateX(90deg) させる。
下 ⇒ 下へ移動して下向きにするために 270度回転させる。
左 ⇒ (省略)
右 ⇒ (省略)

キューブを回転させよう!

.cube>. {
    perspective: 400px;
    animation : xxx 10000ms linear infinite;
}
@keyframes xxx {
      0% { transform: rotateX(  0deg) rotateY(  0deg); }
    100% { transform: rotateX(360deg) rotateY(360deg); }
}

上記のように追記するとついに動き出します!
基点(x,y=100px) から X軸中心に360度、Y軸中心にも360度回転しているので基点を中心に回転している感じです。

ただ、まぁヘンですよね。まだ 2D です。
※Edgeだともうこの時点でなぜか 3D みたいです。

See the Pen CSS-CUBE-4 by hamamoto_abc (@hamamoto_abc) on CodePen.


3D にしよう!

See the Pen CSS-CUBE-4.5 by hamamoto_abc (@hamamoto_abc) on CodePen.

.cube>. {
    perspective: 400px;
    transform-style: preserve-3d; /* <= これを追加 ★ */
    animation : xxx 10000ms linear infinite;
}

これでやっと奥行が出てきていい感じです。
でも、よく見ると微妙に変に歪んでますよね。

視点 perspective を一つ上にしてみましょう。

.cube {
    position:absolute; top:100px; left:100px;
    font-size: 70px;
    perspective: 400px; /* <= をここに移動 ★ */
}
.cube>. {
    transform-style: preserve-3d;
    animation : xxx 10000ms linear infinite;
}

これでちゃんといい感じになりました。

なぜこれでうまくいくのかは、きちんと私が理解できていないのでうまく説明できないのですが、変更前の記述では animation でぐるぐる回る箇所が視点になっているので一緒に回って歪むのかな~?と思います。

See the Pen CSS-CUBE-5 by hamamoto_abc (@hamamoto_abc) on CodePen.


回転の基点をキューブの中心に持ってくる。

基点(x,y=100px)を中心に回るので、現状ではキューブの左上を中心に回っています。
これをキューブの中心にしたいので、キューブ自体の位置を移動します。

.cube>.>* {
    position:absolute; top:-60px; left:-60px; /* <= -60px 移動 ★*/
    width:100px; height:100px;
    ・・・

キューブの半径とborder-radiusの幅分で 50px+10px だけ移動して中央に持っていきます。

See the Pen CSS- CUBE by hamamoto_abc (@hamamoto_abc) on CodePen.


完成です!

どうでしょうか?
CSSだけでここまでできるというのは素晴らしいです。
CSSだしCPU負荷も低いし。

なーんて思ってたらそこまで低くはまだないようです。
ただ、一昨年に買った非力なKindle Fire 7インチ(2015年、第5世代)でも一応スムーズにくるくる回ってくれてますので素晴らしいですよね。

けっこう勉強になったし、面白かったです。

Why do not you register as a user and use Qiita more conveniently?
  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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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