今回は、CSSをつかって三角柱をつくり、それをくるくると回してみます。
こんな感じです。
では、ざっくりとですが、HTML、CSSの解説を。
HTML
<div class="wrapper"> <div class="surface s0"></div> <div class="surface s1"></div> <div class="surface s2"></div> </div>
非常にシンプルです。
三角柱なので面を3つ用意して、管理しやすくするためにそれらを1つの要素でラップしておきます。
CSS
* { margin: 0; padding: 0; border: 0; } html { background: #eee; } .wrapper { position: absolute; top: 50%; left: 50%; -webkit-transform-style: preserve-3d; -webkit-transform-origin: 0 0; -webkit-animation: "box3d" 10s infinite linear; -moz-transform-style: preserve-3d; -moz-transform-origin: 0 0; -moz-animation: "box3d" 10s infinite linear; -ms-transform-style: preserve-3d; -ms-transform-origin: 0 0; -ms-animation: "box3d" 10s infinite linear; -o-transform-style: preserve-3d; -o-transform-origin: 0 0; -o-animation: "box3d" 10s infinite linear; transform-style: preserve-3d; transform-origin: 0 0; animation: "box3d" 10s infinite linear; } .surface { position: absolute; width: 330px; height: 80px; -webkit-transform-origin: 50% 50%; -webkit-transform-style: preserve-3d; -moz-transform-origin: 50% 50%; -moz-transform-style: preserve-3d; -ms-transform-origin: 50% 50%; -ms-transform-style: preserve-3d; -o-transform-origin: 50% 50%; -o-transform-style: preserve-3d; transform-origin: 50% 50%; transform-style: preserve-3d; } .surface.s0 { top: -5px; background: #c80000; background: rgba(200, 0, 0, .8); -webkit-transform: translateX(-165px) translateY(-40px) rotateX(0deg) translateZ(23.09px); -moz-transform: translateX(-165px) translateY(-40px) rotateX(0deg) translateZ(23.09px); -ms-transform: translateX(-165px) translateY(-40px) rotateX(0deg) translateZ(23.09px); -o-transform: translateX(-165px) translateY(-40px) rotateX(0deg) translateZ(23.09px); transform: translateX(-165px) translateY(-40px) rotateX(0deg) translateZ(23.09px); } .surface.s1 { top: -5px; background: #00c800; background: rgba(0, 200, 0, .8); -webkit-transform: translateX(-165px) translateY(-40px) rotateX(60deg) translateZ(-23.09px) rotateX(180deg); -moz-transform: translateX(-165px) translateY(-40px) rotateX(60deg) translateZ(-23.09px) rotateX(180deg); -ms-transform: translateX(-165px) translateY(-40px) rotateX(60deg) translateZ(-23.09px) rotateX(180deg); -o-transform: translateX(-165px) translateY(-40px) rotateX(60deg) translateZ(-23.09px) rotateX(180deg); transform: translateX(-165px) translateY(-40px) rotateX(60deg) translateZ(-23.09px) rotateX(180deg); } .surface.s2 { top: -5px; background: #0000c8; background: rgba(0, 0, 200, .8); -webkit-transform: translateX(-165px) translateY(-40px) rotateX(120deg) translateZ(23.09px); -moz-transform: translateX(-165px) translateY(-40px) rotateX(120deg) translateZ(23.09px); -ms-transform: translateX(-165px) translateY(-40px) rotateX(120deg) translateZ(23.09px); -o-transform: translateX(-165px) translateY(-40px) rotateX(120deg) translateZ(23.09px); transform: translateX(-165px) translateY(-40px) rotateX(120deg) translateZ(23.09px); } @-webkit-keyframes box3d { 0% { -webkit-transform: rotateX(0deg); } 30% { -webkit-transform: rotateX(0deg); } 33.33% { -webkit-transform: rotateX(-120deg); } 63.33% { -webkit-transform: rotateX(-120deg); } 66.66% { -webkit-transform: rotateX(-240deg); } 96.66% { -webkit-transform: rotateX(-240deg); } 100% { -webkit-transform: rotateX(-360deg); } } @-moz-keyframes box3d { 0% { -moz-transform: rotateX(0deg); } 30% { -moz-transform: rotateX(0deg); } 33.33% { -moz-transform: rotateX(-120deg); } 63.33% { -moz-transform: rotateX(-120deg); } 66.66% { -moz-transform: rotateX(-240deg); } 96.66% { -moz-transform: rotateX(-240deg); } 100% { -moz-transform: rotateX(-360deg); } } @-ms-keyframes box3d { 0% { -ms-transform: rotateX(0deg); } 30% { -ms-transform: rotateX(0deg); } 33.33% { -ms-transform: rotateX(-120deg); } 63.33% { -ms-transform: rotateX(-120deg); } 66.66% { -ms-transform: rotateX(-240deg); } 96.66% { -ms-transform: rotateX(-240deg); } 100% { -ms-transform: rotateX(-360deg); } } @-o-keyframes box3d { 0% { -o-transform: rotateX(0deg); } 30% { -o-transform: rotateX(0deg); } 33.33% { -o-transform: rotateX(-120deg); } 63.33% { -o-transform: rotateX(-120deg); } 66.66% { -o-transform: rotateX(-240deg); } 96.66% { -o-transform: rotateX(-240deg); } 100% { -o-transform: rotateX(-360deg); } } @keyframes box3d { 0% { transform: rotateX(0deg); } 30% { transform: rotateX(0deg); } 33.33% { transform: rotateX(-120deg); } 63.33% { transform: rotateX(-120deg); } 66.66% { transform: rotateX(-240deg); } 96.66% { transform: rotateX(-240deg); } 100% { transform: rotateX(-360deg); } }
長いです。非常に長いです。
これは多くのブラウザに対応するためにベンダープレフィックスをつけているから長くなっています。
ポイントとしては、
- wrapperの変形基準点を左上にする。
- surfaceの変形基準点を中心にする。
- wrapperの変形基準点とsurfaceの変形基準点を重ねる。(surfaceのx座標、y座標をそれぞれ高さの半分、幅の半分だけ移動させる)
- surfaceを60度ずつ回転させる(正三角形なので)
- surfaceを三角形の重心の分だけ押し出す。(1辺の√3/6倍)
といった感じでしょうか。
非常に言語化しにくいので、コードを見てもらったほうが早いかもしれません。