Anime.js 3D卡片翻转:手把手3步实现滚动堆叠效果
【免费下载链接】animeJavaScript animation engine项目地址: https://gitcode.com/GitHub_Trending/an/anime
给SaaS产品团队页做卡片时,一排平铺的头像显得寡淡。这篇用Anime.js把一次滚动变成3D卡片翻转:18张卡片从屏幕下方逐层升起、微微倾斜,最后堆叠成扇形。可抄的代码都在examples/onscroll-responsive-scope/目录里。
翻转为什么有"厚度":CSS 3D与滚动进度的分工
这个效果不靠逐帧手搓。CSS只负责"看起来立体":给容器声明一个透视距离(perspective,决定3D有多夸张),让卡片每一层保持 preserve-3d(子元素留在同一个3D空间里),正面、背面、卡片本体才活在同一个三维空间。Anime.js只负责"动多少":内置的 onScroll(滚动进度驱动器)把"你滚了多远"换算成 0–100% 的进度,再把这个进度映射到每张卡片的旋转角和位移上。两者像门框和门:门框是CSS钉死的,门开到几度,由你的滚动来拉。这个映射是双向的——滚动回退时卡片逐层归位,手一停它们就停在当前角度,效果因此显得"真"。进度换算逻辑在src/events/scroll.js,想深挖可以去看。
搭骨架、给姿态、接驱动:三步复现扇形堆叠
把examples/onscroll-responsive-scope/的 index.html 和 index.js 拷进项目,整个效果正好拆成三个互不干扰的子问题,每一步都能独立看懂。
两层div叠出双面卡片,8行HTML搞定
这一步解决"双面卡片从哪来":每张 .card 里绝对定位 front、back 两个 div 叠在一起,正反面的图是同目录的 card.svg 和 card-back.svg,SVG任意分辨率都不糊。示例堆了18张卡,数量越多扇形越密。
<div class="stack"> <div class="card"> <div class="front"></div> <div class="back"></div> </div> <!-- 再重复17个 .card,见同目录 index.html --> </div>.stack 容器用 vh 单位锁定宽高,窗口怎么缩放,扇形比例都不塌。
配好3D透视的三行CSS,顺便藏住背面
这一步解决"正反面为什么不互相透"。关键两笔:backface-visibility: hidden(卡片转过90°时把这一面藏掉),背面再预先 rotateY(180deg) 转半圈。注意 transform-origin(翻转轴位置)被压到卡片底边之外(y=105%),卡片才会像"从桌面上站起来",而不是原地晃。
.sticky-content { perspective: 1000px; /* 透视距离,越小越夸张 */ transform-style: preserve-3d; } .card { transform-style: preserve-3d; transform-origin: 50% 105% 0; /* 翻转轴压到卡片下方 */ } .front, .back { backface-visibility: hidden; } .back { transform: rotateY(180deg); }接上onScroll,让滚动驱动旋转和位移
这一步解决"卡片怎么从静止里拉起来":先用 animate 写死动什么、动多少,再用 onScroll(...).link() 把播放权交给滚动。rotate 里的 stagger(批量生成一串递增取值的工具)让外侧两张卡倾斜最大、内侧最小,扇形自然摊开。
import { animate, onScroll, stagger } from '../../dist/modules/index.js'; const cardsAnimation = animate('.card', { transformOrigin: '50% 150%', y: { from: stagger(['-40vh', '40vh'], { from: 'center' }) }, rotate: { to: stagger([-30, 30]), delay: stagger([0, 950], { from: 'last', start: 200 }), }, duration: 750, }); onScroll({ target: '.sticky-container', enter: 'top', leave: 'bottom', sync: .1 }) .link(cardsAnimation);sync: .1 让动画进度比滚动"慢半拍",滚轮一松卡片还会多走一点再落定,动作就有分量了。
参数拖多少手感才出来:4个值和3个坑
💡 先照抄结构、再逐个改值,边滚边看,手感是调出来的:
| 参数 | 视觉影响 | 推荐起步值 |
|---|---|---|
| perspective | 3D"厚度",太小卡片会变形失真 | 1000px |
| transform-origin | 翻转轴位置,y 设太低像钟摆左右晃 | 50% 105% |
| rotate 的 stagger 区间 | 单张卡最大倾角,太大像要倒 | ±30° |
| delay 的 stagger 步长 | 卡片到场的"连续感",太大扇形拼不齐 | 50–950ms |
| sync | 滚动与动画的"橡皮筋"感,越大越滞后 | 0.1 |
⚠️ 三个新手必踩的坑:
- backface-visibility: hidden 只写在 .front 上 → 卡片转到90°时正反面同时透出来,翻转变"透明牌"。
- .stack / .card / .card > div 链条上任何一层漏了 preserve-3d → 3D被拍扁,perspective 完全失效,这是最常见的。
- transform-origin 留在默认 50% 50% → 翻转轴在中心,卡片只会原地晃荡,没有"从屏幕下升起"的纵深感。
不止卡片翻转:同仓库还有两个目录值得看
examples/onscroll-sticky/:同一套粘性滚动技巧、不同动效模式,如果你的页面只要"吸顶 + 视差",这个版本更省。examples/draggable-playground/:想把卡片从滚动驱动改成鼠标拖拽驱动,这里的 draggable(鼠标拖拽交互)用法可以直接搬。
完整实现都在examples/onscroll-responsive-scope/,改 rotate 的区间和 delay 的步长两个值,就能把它搬进你的项目。
【免费下载链接】animeJavaScript animation engine项目地址: https://gitcode.com/GitHub_Trending/an/anime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考