首页 >web前端 >css教程 >如何在3D中制作CSS Slinky

如何在3D中制作CSS Slinky

Lisa Kudrow
Lisa Kudrow原创
2025-03-13 10:26:10706浏览

How to Make a CSS Slinky in 3D

Braydon Coyer发起了一项每月CSS艺术挑战赛,并邀请我捐赠我的著作《Move Things with CSS》作为奖品。 首月主题是“春天”,这让我立刻想到了弹簧玩具——Slinky。

本文将探讨如何使用CSS创建模拟Slinky下楼运动的3D效果。

Slinky的HTML结构

为了灵活控制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的变换包含多个步骤,最终将场景旋转并定位。

Slinky环形的样式

以下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环形的变换和动画

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

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn