附件:CineScroll方法论-AI电影级滚动动画网站构建指南-1.pdf
# CineScroll 方法论:AI 驱动的电影级滚动动画网站构建指南
> 你有没有刷到过苹果官网那种效果——滚动鼠标,产品就像在你面前旋转、分解、变形?看起来超级高级,但其实现在用 AI 就能做出来,而且不需要你会 3D 建模。
>
> 这篇教程手把手教你从零开始,做出一个电影级质感的滚动动画网站。
先说原理,搞懂了就不怕
整个流程其实就一句话:**把一段视频拆成一张张图片,然后用户滚动鼠标的时候,一帧一帧地播放这些图片。**
就像小时候翻的那种「翻页动画书」,翻得越快动画越快。只不过这里是用鼠标滚轮来「翻」。
![工作流程]

具体分 5 步:
1. 用 AI 画图工具生成「起始帧」和「结束帧」
2. 用 AI 视频工具把两张图变成一段过渡视频
3. 用 FFmpeg 把视频拆成一张张图片
4. 用 Claude Code 把这些图片做成滚动动画网站
5. 调整细节,完工
下面一步步来。
---
## 第一步:生成起始帧和结束帧
### 你需要什么工具?
画图工具选一个就行:
- **GPT Image**(ChatGPT 里直接画,或者用 API)
- **Midjourney**
- **Nano Banana 2**(Google 的,免费)
### 怎么画?
你需要画两张图:
- **起始帧**:动画开始时的样子
- **结束帧**:动画结束时的样子
![起始帧和结束帧对比]

### 举几个例子
| 网站类型 | 起始帧 | 结束帧 |
|---------|--------|--------|
| AI 工具站 | 各种 AI 工具图标散落在空中 | 图标排列成整齐的评分矩阵 |
| 时尚穿搭站 | 模特站中间,衣服鞋子包散落周围 | 所有单品飞到模特身上穿好 |
| 产品展示站 | 产品完整外观 | 产品爆炸分解图 |
| 耳机官网 | 耳机零件散落 | 零件组装成完整耳机 |
### 画图的关键要求
**背景色必须和网站背景色一致!** 这是最重要的一点。
如果你的网站是深色主题,背景就用 `#0a0a0f`(接近纯黑)。两张图的背景色要一模一样,不然做成动画会有明显的色差跳变。
### 起始帧 Prompt 示例(AI 工具站)
A dark digital scene on a solid #0a0a0f black background. Various AI tool
icons and logos are scattered randomly across the frame in a chaotic,
floating arrangement. The icons are stylized, glowing with soft purple
(#7c3aed) and blue (#3b82f6) neon edges. Futuristic and minimal.
No text. 2K resolution, 16:9 aspect ratio.
### 结束帧 Prompt 示例
A dark digital dashboard on a solid #0a0a0f black background. The same
AI tool icons are now neatly organized into a clean grid matrix layout,
each sitting inside a glassmorphism card with subtle frosted-glass borders.
Each card shows a small rating bar glowing in purple-to-blue gradient.
Futuristic, minimal, premium. No text. 2K resolution, 16:9 aspect ratio.
### 小技巧
- 生成结束帧时,把起始帧作为参考图上传,这样风格更统一
- 多生成几张,挑最好的一对
- 图片分辨率建议 2K(2048x1152 或 1920x1080)
---
## 第二步:生成过渡视频
### 你需要什么工具?
AI 视频生成工具选一个:
- **可灵 Kling**(国内可用,推荐)
- **Veo**(Google 的)
- **Runway Gen-3**
### 怎么做?
1. 打开视频生成工具
2. 上传你的起始帧作为「首帧」
3. 上传你的结束帧作为「尾帧」
4. 写一段描述过渡过程的 prompt
5. 生成视频
### 过渡视频 Prompt 示例
The scattered floating icons slowly drift together and smoothly arrange
themselves into a neat grid layout. Each icon glides into its position
within a card. The movement is gradual and elegant. Dark background
throughout.
### 关键注意事项
- **过渡要简单渐进**,不要太剧烈。因为用户是用滚轮一帧帧看的,太快的动作会显得卡顿
- **关掉「prompt 增强」功能**(如果有的话),让 AI 老老实实按你说的做
- 视频长度 5-8 秒就够了
- 导出 MP4 格式
---
## 第三步:用 FFmpeg 拆帧
这一步是把视频变成一张张图片。
### 安装 FFmpeg
Mac 用户:
```bash
brew install ffmpeg
Windows 用户去官网下载:https://ffmpeg.org/download.html
拆帧命令
# 创建存放帧图片的文件夹
mkdir frames
# 把视频拆成 JPEG 图片(24帧/秒)
ffmpeg -i your-video.mp4 -vf "fps=24" -q:v 2 frames/frame_%04d.jpg


这条命令会把视频按每秒 24 帧拆开。一个 5 秒的视频会得到大约 120 张图片,8 秒的会得到约 192 张。
转成 WEBP 格式(推荐)
WEBP 比 JPEG 小很多(通常能小 50% 以上),加载更快:
# 先安装 webp 工具
brew install webp
# 批量转换
cd frames
for f in frame_*.jpg; do
cwebp -q 80 "$f" -o "${f%.jpg}.webp"
done
# 删掉 JPEG,只保留 WEBP
rm *.jpg
检查结果
# 看看有多少帧
ls *.webp | wc -l
# 看看总大小
du -sh .
一般来说:
- 120 帧 ≈ 4-6MB
- 192 帧 ≈ 6-10MB
这个大小对网页来说完全可以接受。
第四步:用 Claude Code 搭建网站
这是最核心的一步。把帧图片变成一个可以滚动播放的网站。
技术栈
- HTML + CSS + JavaScript(纯静态,不需要框架)
- GSAP + ScrollTrigger(滚动动画库,免费)
- Canvas(用来高性能渲染帧图片)
核心原理
用户滚动鼠标
↓
ScrollTrigger 计算当前滚动进度(0% ~ 100%)
↓
进度映射到帧编号(比如 50% → 第 60 帧)
↓
Canvas 画出对应的帧图片
HTML 结构
<!-- Hero 帧动画区域 -->
<section class="hero-frames">
<canvas id="frame-canvas"></canvas>
<!-- 可选:动画播完后显示的文字 -->
<div class="hero-overlay"></div>
<div class="hero-content">
<h1>你的标题</h1>
<p>你的副标题</p>
</div>
</section>
<!-- 下面是正常的网站内容 -->
<section class="features">
...
</section>
CSS 关键样式
.hero-frames {
position: relative;
width: 100%;
height: 100vh; /* 占满一屏 */
overflow: hidden;
}
#frame-canvas {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
}
/* 遮罩层,用于在动画结束后让文字可读 */
.hero-overlay {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(10, 10, 15, 0.65);
pointer-events: none;
opacity: 0; /* 初始透明 */
}
.hero-content {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
opacity: 0; /* 初始隐藏 */
}
JavaScript 核心代码
// 注册 GSAP 插件
gsap.registerPlugin(ScrollTrigger);
// 配置
var FRAME_COUNT = 121; // 你的帧数量,改成你实际的数字
var canvas = document.getElementById("frame-canvas");
var ctx = canvas.getContext("2d");
var frames = new Array(FRAME_COUNT);
var currentFrameIndex = 0;
// 帧图片路径
function framePath(i) {
return "frames/frame_" + String(i).padStart(4, "0") + ".webp";
}
// 在 Canvas 上画一帧
function drawFrame(index) {
var img = frames[index];
if (!img) return;
var cw = canvas.width;
var ch = canvas.height;
// cover 模式:图片铺满画布
var scale = Math.max(cw / img.width, ch / img.height);
var w = img.width * scale;
var h = img.height * scale;
ctx.clearRect(0, 0, cw, ch);
ctx.drawImage(img, (cw - w) / 2, (ch - h) / 2, w, h);
}
// 让 Canvas 尺寸匹配屏幕(支持高清屏)
function resizeCanvas() {
canvas.width = canvas.offsetWidth * window.devicePixelRatio;
canvas.height = canvas.offsetHeight * window.devicePixelRatio;
}
// 预加载帧图片(前 25 张优先加载)
function loadFrames() {
var priority = 25;
for (var i = 1; i <= FRAME_COUNT; i++) {
(function (idx) {
var img = new Image();
img.onload = function () {
frames[idx - 1] = img;
if (idx === 1) drawFrame(0); // 第一帧加载完就画出来
};
if (idx <= priority) {
img.src = framePath(idx);
} else {
// 后面的帧延迟加载,避免卡顿
setTimeout(function () {
img.src = framePath(idx);
}, (idx - priority) * 25);
}
})(i);
}
}
// 初始化
resizeCanvas();
loadFrames();
window.addEventListener("resize", function () {
resizeCanvas();
drawFrame(currentFrameIndex);
});
// 核心:用 GSAP Timeline 串联所有动画
var frameObj = { frame: 0 };
var heroTl = gsap.timeline({
scrollTrigger: {
trigger: ".hero-frames",
start: "top top",
end: "+=300%", // 滚动 3 屏的距离
pin: true, // 固定住画面,滚动时不会滚走
scrub: 0.5, // 滚动和动画同步,0.5 秒的平滑过渡
},
});
// 第一段(占 80%):帧动画播放
heroTl.to(frameObj, {
frame: FRAME_COUNT - 1,
snap: "frame",
ease: "none",
duration: 8,
onUpdate: function () {
var idx = Math.round(frameObj.frame);
if (idx !== currentFrameIndex) {
currentFrameIndex = idx;
drawFrame(idx);
}
},
});
// 第二段(占 10%):遮罩变暗
heroTl.to(".hero-overlay", { opacity: 1, duration: 1 });
// 第三段(占 10%):文字淡入
heroTl.to(".hero-content", { opacity: 1, duration: 1 });
这段代码做了什么?
- pin: true — 滚动时把 hero 区域「钉」在屏幕上不动
- end: "+=300%" — 用户需要滚动 3 个屏幕高度的距离才能播完
- scrub: 0.5 — 滚动和动画平滑同步
- Timeline 串联 — 先播帧动画,播完后遮罩变暗,最后文字淡入
用户看到的效果就是:
- 开始滚动 → 画面开始动(帧动画)
- 继续滚动 → 动画播完,画面定格
- 再滚一点 → 背景变暗,标题文字浮现
- 继续滚动 → 离开 hero 区,进入下面的内容
第五步:下面的内容区域
Hero 帧动画是视觉亮点,但一个完整的网站还需要下面的内容区域。
推荐的页面结构
Hero 帧动画(视觉锚点)
↓
产品/功能卡片(展示核心内容)
↓
方法论/流程(建立信任)
↓
分类/集合(引导浏览)
↓
对比表格(促进转化)
↓
邮件订阅(留住用户)
↓
页脚(合规信息)
下面区域的动画
用 GSAP 的滚动入场动画就够了,不需要再做帧动画(会喧宾夺主):
// 卡片依次入场
gsap.from(".card", {
y: 60, // 从下方 60px 的位置
opacity: 0, // 从透明
duration: 0.8, // 0.8 秒完成
stagger: 0.15, // 每张卡片间隔 0.15 秒
ease: "power2.out",
scrollTrigger: {
trigger: ".cards-grid",
start: "top 85%", // 卡片区域顶部到达视口 85% 位置时触发
},
});
性能优化清单
做完之后,检查这几项:
- [ ] 帧图片用 WEBP 格式(比 JPEG 小 50%+)
- [ ] 前 25 帧优先加载,其余延迟加载
- [ ] Canvas 用
devicePixelRatio 适配高清屏
- [ ] 动画元素加
will-change: transform, opacity
- [ ] 图片总大小控制在 10MB 以内
部署上线
这是纯静态网站,随便找个平台就能部署:
- Vercel — 拖文件夹上去就行,免费
- Netlify — 同上,免费
- Cloudflare Pages — 速度最快,免费
- GitHub Pages — 免费,适合个人项目
常见问题
Q:滚动太久才播完动画?
A:减小 end: "+=300%" 的数字。改成 +=200% 就只需要滚 2 屏。
Q:动画不流畅?
A:检查帧图片是否都加载完了。可以加一个加载进度条,等加载完再允许滚动。
Q:手机上效果不好?
A:手机屏幕小,可以减少帧数(比如只用偶数帧),或者在移动端直接播放视频代替帧动画。
Q:背景色和帧图片有色差?
A:确保生成图片时 prompt 里写了精确的背景色值(如 #0a0a0f),并且 CSS 里的背景色和它一致。
总结
整个流程就是:
AI 画两张图 → AI 生成过渡视频 → FFmpeg 拆帧 → GSAP + Canvas 做滚动动画
核心技术点就一个:GSAP ScrollTrigger 的 pin + scrub + timeline。
掌握了这个方法,你可以给任何产品、任何主题做出苹果官网级别的滚动动画效果。不需要会 3D,不需要会 After Effects,AI 帮你搞定视觉素材,代码部分也可以让 Claude Code 帮你写。
去试试吧。
💡 省钱小技巧:图片生成和视频生成可以去 tempadd.com 用临时邮箱白嫖积分!