Braydon Coyer發起了一項每月CSS藝術挑戰賽,並邀請我捐贈我的著作《Move Things with CSS》作為獎品。 首月主題是“春天”,這讓我立刻想到了彈簧玩具——Slinky。
本文將探討如何使用CSS創建模擬Slinky下樓運動的3D效果。
為了靈活控制Slinky的行為,我們將使用CSS自定義屬性。以下是用Pug編寫的HTML結構:
- const RING_COUNT = 10; .container .scene .plane(style=`--ring-count: ${RING_COUNT}`) - let rings = 0; while rings <p>這段代碼生成的HTML包含10個環形元素,每個元素都帶有<code>--index</code>屬性表示其索引。 </p><p></p><div><div><div style="--ring-count: 10"> <div style="--index: 0;"></div> <div style="--index: 1;"></div> <div style="--index: 2;"></div> <div style="--index: 3;"></div> <div style="--index: 4;"></div> <div style="--index: 5;"></div> <div style="--index: 6;"></div> <div style="--index: 7;"></div> <div style="--index: 8;"></div> <div style="--index: 9;"></div> </div></div></div><h3> Slinky的初始CSS樣式</h3><p>我們需要一個3D場景。以下CSS代碼定義了Slinky及其場景的屬性:</p><pre class="brush:php;toolbar:false"> :root { --border-width: 1.2vmin; --depth: 20vmin; --stack-height: 6vmin; --scene-size: 20vmin; --ring-size: calc(var(--scene-size) * 0.6); --plane: radial-gradient(rgb(0 0 0 / 0.1) 50%, transparent 65%); --ring-shadow: rgb(0 0 0 / 0.5); --hue-one: 320; --hue-two: 210; --blur: 10px; --speed: 1.2s; --bg: #fafafa; --ring-filter: brightness(1) drop-shadow(0 0 0 var(--accent)); } * { box-sizing: border-box; transform-style: preserve-3d; } .container { height: var(--scene-size); width: var(--scene-size); transform: translate3d(0, 0, 100vmin) rotateX(-24deg) rotateY(32deg) rotateX(90deg) translateZ(calc((var(--depth) var(--stack-height)) * -1)) rotate(0deg); } .scene, .plane { height: 100%; width: 100%; position: relative; } .plane { transform: translateZ(var(--depth)); }
.container
的變換包含多個步驟,最終將場景旋轉並定位。
以下CSS代碼利用自定義屬性--index
和--ring-count
來定位每個環形:
.ring { --origin-z: calc(var(--stack-height) - (var(--stack-height) / var(--ring-count)) * var(--index)); --hue: var(--hue-one); --accent: hsl(var(--hue) 100% 55%); height: var(--ring-size); width: var(--ring-size); border-radius: 50%; border: var(--border-width) solid var(--accent); position: absolute; top: 50%; left: 50%; transform-origin: calc(100% (var(--scene-size) * 0.2)) 50%; transform: translate3d(-50%, -50%, var(--origin-z)) translateZ(0) rotateY(0deg); } .ring:nth-of-type(odd) { --hue: var(--hue-two); }
--origin-z
計算每個環形在Z軸上的初始位置, transform
屬性則將環形定位並旋轉。
為了實現Slinky的翻轉和下落效果,我們需要計算每個環形的目標Z軸位置--destination-z
,並使用動畫來控制變換: (後續步驟略,因篇幅過長,已概括核心思路) 文章中詳細描述瞭如何通過Stylus預處理器生成針對每個環形的keyframes,以及如何處理動畫延遲和無限循環等問題,最終實現一個可配置的3D CSS Slinky效果。 也討論了CSS動畫的局限性以及JavaScript動畫庫(如GreenSock)的優勢。
本文詳細闡述了使用純CSS創建3D可配置Slinky效果的複雜過程,涵蓋HTML結構、CSS樣式、動畫實現以及預處理器Stylus的使用。 文章中也探討了CSS動畫的局限性和改進建議。 最終效果是一個可配置、可自定義的3D Slinky動畫。
以上是如何在3D中製作CSS Slinky的詳細內容。更多資訊請關注PHP中文網其他相關文章!