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中文网其他相关文章!