2012/12/26更新

[CSS3] Transformを用いて3D立方体を表示する、アニメーションさせる

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
最近リリースされた、聖戦紀ブレイブナインというソーシャルカードゲームで、Webアプリで3Dでいい感じに動いているのを見て、自分も作ってみたいなーと思いました。

ブレイブナインのコードを読んでるとどうもCSS3のTransformを使っている模様。
今回はそれを使って、立方体(キューブ)を作ってみました。

画像


CSS3のTransformとは

CSS3のTransformは、対象HTML要素に対して、移動/回転/拡大縮小を行うことが出来るCSSプロパティです。
例えば以下のように使う事が出来ます。
<div class='target1'></div>
<style>
  .target1 {
    transform: translateX:(100px);
    -webkit-transform: translateX:(100px);
  }
</style>
上記例では、target1の要素をx軸方向に100px移動しています。
このTransformは、2Dの変換はもちろん、3Dの変換も行うことが出来ます。 今回は、その機能を利用しました。
CSS3 Transformについての詳細は、以下などのリファレンスをご参照ください。
http://www.w3schools.com/cssref/css3_pr_transform.asp



今回の完成イメージ

今回は、以下のような立方体と動きを作りたいと思います。
1
2
3
5
6
視点を上下に動かせます

CSS3 Transformで3D表現を行う為のHTML

まずは、立方体を構成するHTMLを記述します。
<div class="stage">
    <div class="cube">
        <div class="wall" id="front">1</div>
        <div class="wall" id="back">2</div>
        <div class="wall" id="left">3</div>
        <div class="wall" id="right">4</div>
        <div class="wall" id="top">5</div>
        <div class="wall" id="bottom">6</div>
    </div>
</div>
.stageクラスは、立方体を描画する領域を表現します。
.cubeクラスは、立方体全体を示す要素です。
.wallクラスは、立方体を構成する各面となります。



立方体を構成するCSS

立方体を構成するためのCSSは、以下となります。
/* 3D描画領域を指定するクラス */
.stage {
    /* perspectiveで深さ的なものを指定できます */
    -webkit-perspective: 1000;
    /* perspective-originで、立方体をみる視点らしきものを指定できます */
    -webkit-perspective-origin: 50% 50%;
    width: 400px;
    height: 400px;
    position: relative;
}
/* 立方体を保持する要素に対するクラス */
.cube {
    width: 200px;
    height: 200px;
    /* transform-styleにperserve-3dを指定すると3Dに見えるようになります */
    -webkit-transform-style: preserve-3d;
    position: absolute;
    left: 100px;
}
/* 立方体を構成する壁に対する共通的なスタイル */
.wall {
    width:200px;
    height:200px;
    color: white;
    font-size: 144px;
    text-align: center;
    line-height: 200px;
    font-weight: bold;
    /* absoluteにすることで、壁を重ねて描画します */
    position: absolute;
    top: 50px;
    left: 100px;
}
#front {
    background-color: rgba(255, 0, 0, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: translateZ(100px);
}
#back {
    background-color: rgba(0, 255, 0, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: rotateY(180deg) translateZ(100px);
}
#left {
    background-color: rgba(0, 0, 255, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: rotateY(90deg) translateZ(100px);
}
#right {
    background-color: rgba(255, 255, 0, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: rotateY(-90deg) translateZ(100px);
}
#top {
    background-color: rgba(255, 0, 255, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: rotateX(90deg) translateZ(100px);
}
#bottom {
    background-color: rgba(0, 255, 255, 0.7);
    /* 重なっている壁をtransformで回転・移動して壁の位置へ配置します */
    -webkit-transform: rotateX(-90deg) translateZ(100px);
}

上記で注意すべき箇所は、以下のポイントです。
  • .stageクラスで、深さや視点を指定している。
  • .cubeクラスで、3Dに見えるようにtransform-styleを指定している。
  • #front,#backなどで、壁の位置を指定している。transformは、行列の外積計算となるので、回転→移動と移動→回転では、実行結果が異なる。

これで、無事に立方体が描画されるはずです。



立方体を回転させる

次に立方体を動かします。今回は、y軸を中心に回転するようにしました。
以下のCSS Animationで実現します。
#cube {
    -webkit-animation: rotateY 10s linear infinite;
    animation: rotateY 10s linear infinite;
}
@keyframes rotateY {
    0% {transform: rotateY(0deg)}
    100% {transform: rotateY(360deg)}
}
@-webkit-keyframes rotateY {
    0% {-webkit-transform: rotateY(0deg)}
    100% {-webkit-transform: rotateY(360deg)}
}
#cube指定の要素のtransform:rotateYをアニメーションさせることで、自転しているような動きを実現できます。



視点を変えてみる

記事の最初に示した完成例では、視点を変更できるようにしています。
これは、以下のように実現しました。
<!-- スライダーUIを作成する -->
<input id="range_perspective" type="range" min="-100" max="100" step="10">
<script type="text/javascript">
window.addEventListener('load', function() {
    var stage = document.getElementById('stage');
    // スライダーの値がかわった際に、.stageクラスのperspeciveOriginを変更します。
    document.getElementById('range_perspective').onchange = function(e) {
        stage.style.webkitPerspectiveOrigin = '50% ' + this.value + '%';
    }
}, false);
</script>
スライダーの値が変化したところで、視点を変化させるような簡易的な実装です。



最後に

CSSで3Dを表現できると知って今回実装しましたが、なかなか楽しかったです。
ただ視点の位置や、視点の位置と回転の関係など面倒なことも多い感じで。
もう少し使いやすいようにしたいなぁと思う今日この頃です。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。