3D 旋转木马组件(CSS 卡片环旋转木马,数量/半径/速度可调)
3D 旋转木马组件:纯 CSS preserve-3d 构建卡片环,rotateY 分布 + translateZ 推远实现环绕纵深,卡片数量、半径、旋转速度、旋转轴实时可调,零 JS 依赖零图片。
效果演示(真实可交互)
完整代码
核心公式:第 i 张卡片 = rotateY(i × 360°/n) + translateZ(半径)。所有卡片绝对定位叠在圆心,通过 rotateY 按序号展开到不同角度,再用 translateZ 沿各自方向推出半径距离,就围成一个环绕圆心的立体卡片环。
<div class="scene">
<div class="carousel">
<div class="card" style="--i:0"><span>🚀</span><b>1</b></div>
<div class="card" style="--i:1"><span>🎨</span><b>2</b></div>
<div class="card" style="--i:2"><span>📱</span><b>3</b></div>
<div class="card" style="--i:3"><span>⚡</span><b>4</b></div>
</div>
</div>
.scene {
height: 360px;
display: flex; align-items: center; justify-content: center;
perspective: 950px; /* 视距,产生近大远小 */
}
.carousel {
position: relative;
width: 130px; height: 180px;
transform-style: preserve-3d; /* 子元素保留 3D 空间 */
animation: spin 14s linear infinite;
}
.card {
position: absolute; inset: 0;
border-radius: 16px;
background: linear-gradient(160deg, #6c8cff, #a96cff);
color: #fff;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
transform: rotateY(calc(var(--i) * 90deg)) translateZ(240px);
/* 4 张卡片:每张 90°,半径 240px */
}
@keyframes spin { to { transform: rotateY(360deg); } }
// 动态生成:数量 n → 每张角度 360/n
function build(n) {
carousel.innerHTML = '';
for (let i = 0; i < n; i++) {
const c = document.createElement('div');
c.className = 'card';
c.style.setProperty('--i', i);
c.style.transform = `rotateY(${i * 360 / n}deg) translateZ(240px)`;
carousel.appendChild(c);
}
}
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 卡片数量 | --i 与 360/n | 数量越多卡片越密,需同步增大半径防重叠 |
| 环半径 | translateZ 值 | 卡片距圆心的距离,演示中 140-340px 可调 |
| 旋转速度 | animation: spin 14s | 周期越短转得越快,演示中 4-40s 可调 |
| 旋转轴 | @keyframes spin | 仅 Y 轴环绕;X+Y 双轴则为翻滚效果 |
| 视距 | perspective: 950px | 500-1200px,越小透视越夸张 |
兼容性与性能
- 纯 CSS 3D 组合,
transform动画由 GPU 合成器负责,卡片环持续旋转开销极低 - Chrome / Safari / Firefox / Edge 全支持;iOS Safari 需保留
-webkit-transform-style: preserve-3d(演示已含兼容写法) - 卡片数量动态生成仅发生在滑块变化时,运行期无 JS 参与
- 正面卡片显示、背面卡片同样可见,可自由放置内容;若需隐藏背面可加
backface-visibility: hidden - 不支持的旧浏览器中卡片环退化为重叠的静态卡片堆,内容不丢失
常见问题
Q: 卡片互相重叠或露缝怎么办? 卡片宽度不变时,数量越多越需要更大的半径。粗略经验:半径 ≈ 卡片宽度 ÷ (2 × sin(180°/数量))。演示中数量与半径独立可调,方便直观验证这个关系。
Q: 为什么转起来感觉「扁」? 透视感不足通常是 perspective 太大或半径太小。把视距调到 700-900px、半径调大,近大远小的纵深感会明显增强。
Q: 想让鼠标悬停时暂停或反向转? 直接控制 animation-play-state: paused 与 animation-direction: reverse 即可,无需改动任何 JS。
Q: 可以商用吗? 可以。本组件为粤喵自研原创代码,免费商用无需署名,卡片内容、颜色、数量均可自由修改。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。