關於CSS中的 3D transform
記錄了關於CSS中的3D transform一些觀念並練習
最近在練習關於css 3d的部分,將一些心得作為筆記。
這篇我將介紹如何使用 CSS 的 transform
屬性來模擬 3D 效果,並探討transform-style
對元素子層的影響。
透視效果
perspective
屬性用於在 2D 平面上模擬 3D 形狀,給使用者提供深度感(即 Z 軸)。透視值越大,表示物體離我們越遠,深度感也越強。使用方法如下:
transform: perspective(800px);
這段 CSS 設置會讓元素看起來像是在 800px 的距離之外觀看。調整這個值可以控制視覺深度。
3D 變換樣式
transform-style
屬性決定了一個元素的子元素是否保留其在 3D 空間中的定位。這對於創建複雜的 3D 結構至關重要。
flat
(預設值): 子元素將不會獨立存在於 3D 空間中,它們會被扁平化並平鋪在父元素的 2D 平面上。preserve-3d
: (用於 3D 結構) 子元素將保持其獨立的 3D 位置與轉換狀態。若父元素未設定此值,子元素的 3D 轉換將無法生效。
可用值如下:
transform-style: flat;
transform-style: preserve-3d;
撰寫類似旋轉木馬的 Slider
我們將實現一個簡易的 3D 旋轉木馬效果的 Slider,並添加動畫效果。
步驟 1:設置基礎結構
首先,我們需要設置基本的 HTML 結構和 CSS 樣式。
我們使用 CSS 變數(--quantity
和 var(--position)
)來定義總項目數和每個項目的位置。
<div class="wrapper">
<div class="slider" style="--quantity: 6">
<div class="item" style="--position: 1">
<div class="content">1</div>
</div>
<div class="item" style="--position: 2">
<div class="content">2</div>
</div>
<div class="item" style="--position: 3">
<div class="content">3</div>
</div>
<div class="item" style="--position: 4">
<div class="content">4</div>
</div>
<div class="item" style="--position: 5">
<div class="content">5</div>
</div>
<div class="item" style="--position: 6">
<div class="content">6</div>
</div>
</div>
</div>
步驟 2:設置基本樣式
設定外層容器 (.wrapper
)、Slider 容器 (.slider
) 和項目 (.item
) 的尺寸與定位。我們將 Slider 容器置於畫布中央,並讓所有項目堆疊在同一個位置。
.wrapper {
width: 100%;
height: 80vh;
overflow: hidden;
position: relative;
}
.wrapper .slider {
width: 200px;
height: 250px;
left: calc(50% - 100px);
}
.wrapper .slider .item {
position: absolute;
inset: 0;
}
.wrapper .slider .item .content {
width: 100%;
height: 100%;
background-color: red;
}
步驟 3:添加 3D 效果
使用 perspective
和 transform-style
屬性來實現 3D 效果。修改slider和item
.wrapper .slider {
width: 200px;
height: 250px;
left: calc(50% - 100px);
transform-style: preserve-3d;
transform: perspective(2500px);
}
接著transform,添加z軸,以及y軸轉的角度
.wrapper .slider .item {
position: absolute;
inset: 0 0 0 0 ;
/* 使用 CSS 變數計算每個項目的位置 */
transform:
rotateY(calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg))
translateZ(450px);
}
calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg)
這段運算的目的是將 N 個quantity均勻地分佈在 360∘ 的圓周上。
參數 | 數值意義 | 目的 |
---|---|---|
360 / var(--quantity) | 間隔角度 | 計算每個項目之間的固定角度間隔。例如,有 6 個項目,間隔為 360/6=60∘。 |
var(--position) - 1 | 序號修正 | 這是項目的索引。由於第一個項目 (--position: 1 ) 應從 0∘ 開始,因此需減去 1。 |
rotateY(...) | Y 軸旋轉 | 根據計算出的角度,將項目圍繞中心軸旋轉,使其面向圓周外側。 |
translateZ(450px) | Z 軸平移(半徑) | 這是圓柱體的半徑。它將項目沿 Z 軸向外推出 450 像素,使其在旋轉後不會堆疊在中心點,而是形成一個圓。 |
Example:
- 項目 1 (
--position: 1
): - 項目 2 (
--position: 2
): - 項目 6 (
--position: 6
):
步驟 4:添加動畫效果
最後,我們為 .slider
容器添加一個無限的旋轉動畫 (autoRun
),讓整個旋轉木馬持續運行。我們在 to
狀態中將 rotateY
設置為 360∘,實現一圈完整的旋轉。
.wrapper .slider {
width: 200px;
height: 250px;
left: calc(50% - 100px);
transform-style: preserve-3d;
transform: perspective(2500px);
animation: autoRun 20s linear infinite;
}
@keyframes autoRun {
from {
transform: perspective(2500px) rotateX(-16deg) rotateY(0deg);
}
to {
transform: perspective(2500px) rotateX(-16deg) rotateY(360deg);
}
}
接著一個簡單的 3D 旋轉木馬效果的 Slider就實現了。