最好的實踐,就是給定一個實踐的目標去實踐。 目標:利用 CSS3 的一些特性,繪製一個魔方,要可以玩轉的那種,即上下左右每一層都可以獨立旋轉。效果如下: 為了完成此效果,將使用到以下相關概念和樣式:坐標、3D呈現、平移、旋轉。 (1)坐標 屏幕的起點坐標是(0,0,0),往右遞增為 x 方向,使用 ...
最好的實踐,就是給定一個實踐的目標去實踐。
目標:利用 CSS3 的一些特性,繪製一個魔方,要可以玩轉的那種,即上下左右每一層都可以獨立旋轉。效果如下:
為了完成此效果,將使用到以下相關概念和樣式:坐標、3D呈現、平移、旋轉。
(1)坐標
屏幕的起點坐標是(0,0,0),往右遞增為 x 方向,使用 left 屬性表示,往下走,遞增為 y 方向,使用 top 屬性表示。而 3D 場景中 z 正方向(遞增)為走出屏幕到你面前的方向。
但這個坐標的起點不一定得是屏幕,只是遵循相同的方向。當元素使用 position:absolute 來絕對定位時,其位置坐標是以最近的 position:relative 父元素為(0,0,0) 來計算的,因此,我們繪製一個3D場景時,通常會定義一個最外層的 position:relative 元素來進行場內發揮。
以下完整的頁面代碼,會繪製一個x,y,z坐標軸,會使用到本文涉及的各個內容,後邊的內容均以此頁面為基礎,便於動手體驗。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CSS3 魔方</title>
<!-- 樣式部分全寫這裡 -->
<style>
.wrap {
transform-style: preserve-3d;
width: 300px; height: 300px;
position: relative; /* 定位起點元素 */
border-top:solid 1px gray; /* x 軸 */
border-left:solid 1px gray; /* y 軸 */
/* 傾斜一點方能見立體效果 */
transform: rotateX(-30deg) rotateY(-30deg);
}
/* z 軸正方向 */
.zaxis_p {
position:absolute;
width : 300px;
height:1px;
border-top:solid 1px gray;
/* xy面上,90度立起來就是 z */
transform: rotateY(-90deg);
/* 立起來的旋轉點 */
transform-origin:0 0 0;
}
/* z 軸負方向 */
.zaxis_n {
position:absolute;
width : 300px;
height:1px;
border-top:dashed 1px gray; /*(虛線)*/
transform: rotateY(90deg);
transform-origin:0 0 0;
}
</style>
</head>
<body style="padding:300px;">
<div class="wrap">
<div class="zaxis_p"></div>
<div class="zaxis_n"></div>
</div>
</body>
</html>
效果如下圖:
(2)3D 呈現
transform-style: preserve-3d;
上邊繪製的坐標軸,最外層的 wrap 有 transform-style: preserver-3d 屬性,它表示,它是維持其三維態的,其子元素可在其三個維度空間施展。如果沒有此項,子元素在 z 空間上是沒有作用的,也即我們的 z 軸會變成一個點。
(3)平移
沿著坐標軸的方向保持姿勢移動,對於 x 與 y 軸而言,移動可以通過改變 left,top 值來達到目的,對於 z 軸(x,y軸同樣適用)則使用平移樣式。如,讓元素在 z 軸上後移 200個像素,讓其在上邊坐標z軸的虛線上,我們可以使用:
transform: tanslateZ(-200px);
我們在坐標中添加一個元素,其樣式定義如下:
.square {
position:absolute;
width:100px; height:100px;
background:green;
top:0; left:0;
transform:translateZ(-200px);
}
<div class="square"></div>
效果如下:
(4)旋轉
物體的旋轉與轉動的軸心點有關,就像一個球,我們可以掛一根繩子轉大圈,也可以直接轉它,這個軸心與以下樣式定義有關:
transform-origin:0 0 0;
後邊的這個" 0 0 0 "的值為相對位置,是以元素自身為起點來算的。所以,具體到每個元素,這個(0,0,0)表示的是該元素的起點位置,與別的元素無關。有關transform-origin 更多的描述與用法可參考相關資料。
有了旋轉軸心點,在方向上給個角度就可以了。如,繞 z 軸旋轉 45 度。
transform: rotateZ(45deg);
度數可正可負,每一根坐標軸,把軸的正向對準你的眼睛(對準鼻梁也不錯),此時,順時針為正角度,逆時針為負角度。
旋轉的示例,在下邊的綜合示例中給出。
(5)動畫
CSS3 形成動畫效果有兩種方式,其本質都是呈現樣式屬性值的變化過程。
第一種方式
定義一個關鍵幀(@keyframes)樣式體表示變化過程,並取個名字。然後,使用 animation 屬性指定該名字讓元素動起來。這種方式功能強大,對時間軸內的動畫定義能力強,可以按百分比定義每一段的屬性變化值。我們以讓上邊定義的 square 在 z 軸上邊繞 z 軸轉邊從 -200px 平移到 200px 為例來體驗一下。
/*設置動畫關鍵幀,名字為 movez */
@keyframes movez {
0% { /* 從這樣的屬性開始 */
transform: translateZ(-200px) rotateZ(0deg);
}
100% { /* 變化到這樣的屬性 */
transform: translateZ(200px) rotateZ(3600deg);
}
}
.square {
position:absolute;
width:100px; height:100px;
background:green;
top:0; left:0;
transform-origin:0 0 0;
/* 按 movez 來呈現動畫過程 */
animation:movez 10s linear infinite;
}
效果如下:
第二種方式
使用屬性 transition 指定一個屬性和一個時長,只要這個屬性值發生變化,它就按規定的時長進行漸變形成動畫。
我們回到平移的那個 square,為其添加 transition 屬性,指明 transform,時長設置為 5s,即5秒。
.square {
position:absolute;
width:100px; height:100px;
background:green;
top:0; left:0;
transform:translateZ(-200px);
/* 指定漸變屬性,時長 */
transition: transform 5s;
}
此時,我們來改變它的 transform 平移值:
<script>
setTimeout(
function(){
document.querySelector(".square").style.transform = "translateZ(200px)";
},
1000
);
</script>
效果如下,多麼優雅的一個變化過程,軟著陸。
(6)小結
熟悉以上了這些概念與特性,就有了達成魔方目標的工具。更多特性若有興趣,可進一步加深瞭解,想象空間很大。