2013年9月16日 星期一

純CSS3做旋轉立方體

一個立方體有六個面,所以需要六個HTML元素,因為要轉動的是一個立方體,所以這六個面需要被放置到立方體裡面:
    <div class="cube">
        <div class="cube-face  cube-face-front">1</div>
        <div class="cube-face  cube-face-back">2</div>
        <div class="cube-face  cube-face-left">3</div>
        <div class="cube-face  cube-face-right">4</div>
        <div class="cube-face  cube-face-top">5</div>
        <div class="cube-face  cube-face-bottom">6</div>
    </div>
編寫立方體的樣式:
<style>
    .cube {
        width: 150px;
        height: 150px;
        position: relative;
        /* perspective:
            當放置的物件為3D物件時,此屬性可指定3D物件的視角。
            值越越越有的3D效果。如果沒有這個屬性,元素呈現在屏幕上將使用平行投影的投影線相互平行。
            我們將我們的立方體的父容器上設置此屬性,其所有孩子(面)都受到一個共同的角度來看。
            */
        -webkit-perspective: 500;
        /* transform-style :
            讓旋轉的子元素與母元素保持3D位置
            w3schools的範例
                http://www.w3schools.com/cssref/trycss3_transform-style_inuse.htm
            詳細解說
                http://css-tricks.com/almanac/properties/t/transform-style/
            */
            -webkit-transform-style: preserve-3d;
        /* 指定動畫讓立方體轉動 */
        -webkit-animation: rolling 3s infinite linear;
    }

    .cube-face {
        width: inherit;
        height: inherit;
        position: absolute;
        opacity: 0.5;
    }
    /* 定義一個3D translation (x,y,z)
                為了讓front face比較靠近自己的眼睛,我們將她的Z軸上做轉換。 
        */
    .cube-face-front {
        background-color: yellow; /* 為了方便查看六面,先隨便給六個面不同顏色 */
        -webkit-transform: translate3d(0, 0, 75px);
    }
    /* 背面為正面的相對面,所以側面轉180度,
                 側轉180度的translate3d(0, 0, 75px)會像z軸減75px,因為z軸的方向等於元素面對的方向 
        */
    .cube-face-back {
        background-color: red;
        -webkit-transform: rotateY(180deg) translate3d(0, 0, 75px);
    }
    /* 左面為正面逆向側轉90(rotateY預設為向右轉),因為z軸的方向等於元素面對的方向,
       所以面對左邊的元素,z軸的方向也是向左,看起來就像元素向左移動了75px 
        */
    .cube-face-left {
        background-color: green;
        -webkit-transform: rotateY(-90deg) translate3d(0, 0, 75px);
    }
    /* 右面 */
    .cube-face-right {
        background-color: blue;
        -webkit-transform: rotateY(90deg) translate3d(0, 0, 75px);
    }
    /* 上面 */
    .cube-face-top {
        background-color: orange;
        -webkit-transform: rotateX(90deg) translate3d(0, 0, 75px);
    }
    /* 下面 */
    .cube-face-bottom {
        background-color: black;
        transform: rotateX(-90deg) translate3d(0, 0, 75px);
    }

    @-webkit-keyframes rolling {
        from {
            -webkit-transform: rotateY(0deg);
        }

        to {
            -webkit-transform: rotateY(360deg);
        }
    }
    </style>

以上語法執行起來,但是看起來怪怪的,於是單獨一個接一個面來檢查(mark五個面),發現cube-face-front轉到後面時並沒有變小,cube-face-back轉到前面時並沒有變大,如果取消.cube-faceopacity設定,看起來就像是個梯形立方體在旋轉!

原因出在perspective(透視):

先來簡單了解一下vanishing point(消失點)是什麼
所謂的perspective(透視),就是在畫面中利用視線的消失點營造空間的感覺。
平常生活中,你看兩條平行的火車鐵軌會在某個地方融合在一起,那個融合的地方就是所謂的消失點

消失點的形成原因是因為我們眼睛觀看物品的特性所造成。當有一些物品的大小都相同時,越靠近我們眼睛的物品看起來會比較大,遠離我們的物品看起來較小 (雖然它們的原始大小都一樣)

而這個近看較大,遠看較小的情況是非常規律的,不會忽大忽小的亂變一通。因此我們可以想像的到,如果這些物品一直排列下去,到最後會小到我們的眼睛再也無法分辨,只能看到一個小黑點存在。這個黑點就是消失點

利用消失點的存在,我們就可以營造出畫面具有深淺遠近的空間感。因為我們看到畫面的物品越來越小,大腦就會依據以往的經驗判斷:『看起來比較大的這些東西離我比較近,看起來比較小的那些離我比較遠。』因而產生有空間的感覺。

我們在 .cube 設定了perspective屬性,當旋轉元素時,被消失點(vanishing point)標記的perspective(透視)也一起跟著旋轉;範例中我們在語法中將初始化在2D Place的後面,旋轉180度以後就來到了前面

我們想要的是,不管元素如何轉換,perspective(透視)永遠不會改變且保持一致,解決的方法就是將剛剛所有建立的元素都包到一個新的div裡面並設定perspective屬性:
    <div class="scene">
        <div class="cube">
            <!-- 省略 -->
        </div>
    </div>
修改style(新增 .secne 和修改 .clube)
        .scene {
            width: 150px;
            height: 150px;
            -webkit-perspective: 600;
        }
        .cube {
            width: inherit;
            height: inherit;
            position: relative;
            -webkit-transform-style: preserve-3d;
            -webkit-animation: rolling 3s infinite linear;

        }

沒有留言: