如何实现与附件样式匹配的可滚动Rotated Circular card列表

可滚动旋转圆形卡片列表实现方案
核心实现逻辑
- 基于原生CSS 3D变换 + 滚动驱动动画实现,无需引入重型第三方库,性能表现更优
- 整体结构分为三层:外层滚动容器、中层3D透视容器、内层卡片集合
具体代码实现
1. HTML结构
<!-- 外层滚动容器,控制横向滚动区域 --> <div class="scroll-container"> <!-- 3D透视容器,提供卡片旋转的3D空间 --> <div class="card-carousel"> <div class="circular-card">卡片内容1</div> <div class="circular-card">卡片内容2</div> <div class="circular-card">卡片内容3</div> <div class="circular-card">卡片内容4</div> <div class="circular-card">卡片内容5</div> <!-- 按需添加更多卡片 --> </div> </div>
2. CSS样式
/* 外层滚动容器配置 */ .scroll-container { width: 100vw; height: 100vh; overflow-x: auto; /* 隐藏默认滚动条,可按需保留 */ scrollbar-width: none; } .scroll-container::-webkit-scrollbar { display: none; } /* 3D轮播容器配置 */ .card-carousel { height: 100%; display: flex; align-items: center; gap: 2rem; padding: 0 40vw; perspective: 1200px; transform-style: preserve-3d; /* 绑定滚动驱动动画 */ animation: carousel-rotate linear; animation-timeline: scroll(root x); } /* 圆形卡片样式 */ .circular-card { flex-shrink: 0; width: 220px; height: 320px; border-radius: 28px; background: #ffffff; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15); /* 按索引设置卡片初始旋转偏移 */ transform: rotateY(calc(var(--card-index) * 12deg)) translateZ(120px); transition: transform 0.3s ease; } .circular-card:hover { transform: rotateY(calc(var(--card-index) * 12deg)) translateZ(180px) scale(1.08); } /* 滚动驱动旋转动画 */ @keyframes carousel-rotate { from { transform: rotateY(0deg); } to { transform: rotateY(-360deg); } }
3. JS逻辑
// 为每个卡片设置索引自定义变量 const cards = document.querySelectorAll('.circular-card') cards.forEach((card, index) => { card.style.setProperty('--card-index', index) }) // 不支持滚动驱动动画的浏览器降级方案:拖拽控制旋转 const carousel = document.querySelector('.card-carousel') let isDragging = false let startX, currentRotate = 0 carousel.addEventListener('mousedown', (e) => { isDragging = true startX = e.pageX }) document.addEventListener('mousemove', (e) => { if (!isDragging) return const deltaX = e.pageX - startX currentRotate += deltaX * 0.1 carousel.style.transform = `rotateY(${currentRotate}deg)` startX = e.pageX }) document.addEventListener('mouseup', () => { isDragging = false }) // 移动端触摸适配 carousel.addEventListener('touchstart', (e) => { startX = e.touches[0].pageX }) carousel.addEventListener('touchmove', (e) => { const deltaX = e.touches[0].pageX - startX currentRotate += deltaX * 0.1 carousel.style.transform = `rotateY(${currentRotate}deg)` startX = e.touches[0].pageX })
调整说明
- 卡片的旋转角度、translateZ数值可根据卡片总数调整,保证所有卡片均匀分布在圆周上,避免重叠过多
- 可通过调整
@keyframes中rotateY的正负值,匹配滚动方向和旋转方向的对应关系 - 卡片尺寸、圆角、阴影等样式参数可根据实际设计稿按需修改
内容的提问来源于stack exchange,提问作者Hasham Mubeen
相关产品推荐
相关产品推荐

