影视级3D网页场景 是做什么的?
人们用感觉词汇(“史诗”、“流畅”、“它被吞掉了”、“像电影一样”)描述动画。代码需要精确的决策:屏幕上有什么、摄像机在哪里、什么在移动、移动多快、使用什么缓动曲线、如何照明、以及文本在滚动的每个点做什么。当这些决策留给猜测时,结果在技术上可能不错,但不是他们想象的那样——而每一次修改都比一开始就做对要付出更高的成本。
这个技能通过两步来弥合这一差距:先确认再构建(将描述转化为精确的、经过确认的场景规范)和在可靠的基础上构建(一个使规范可靠实现并使滚动顺畅的架构和技术库)。
它适用于任何场景——捆绑作品集中的场景(一台打开的笔记本电脑、一个环绕的原子技能图标、点燃并燃烧的Logo、一个黑洞隧道)是该方法的实际范例,而不是可供挑选的菜单。
文件
references/scene-language.md 精确的运动词汇 + 将模糊词汇翻译成具体内容
references/scene-spec.md 场景规范 / 分镜板格式,附有实际范例
references/techniques.md 如何构建每种效果(摄像机、着色器、粒子、文本……)
references/architecture.md 固定滚动场景模式、时间线、性能、陷阱
references/house-style.md 默认视觉风格,以及如何从参考中获取风格
references/effects.md 模板中完成的场景,详细分析——可复制或从中学习
references/portfolio.md 基于模板构建完整的作品集
references/content-guide.md 模板的内容字段
references/portrait-rig.md 模板的动态人物主视觉
模板/ 完整的Next.js作品集网站(实际范例)
scripts/create-site.mjs 创建一个新的单页网站(Next.js、默认背景、准备就绪的场景)
scripts/new-scene.mjs 搭建一个新的固定场景(区域 + 时间线, + 3D画布除非使用 --no-canvas)
scripts/video-frames.mjs 从参考视频中提取帧,以便研究其运动
scripts/create-portfolio.mjs 将完整的作品集模板复制到新文件夹中
scripts/retheme.mjs 重新着色模板的强调色系列
工作流程
1. 理解他们想象的内容
阅读请求,了解:页面的用途、每个场景应该展示什么、感觉、任何参考(网站、视频、图片、电影、游戏)以及任何硬性约束(现有网站、框架、品牌颜色)。
如果他们提供了参考,在开始其他任何事情之前先研究它——它包含的信息比任何描述都多。图片:仔细看。视频:运行 scripts/video-frames.mjs 并按顺序查看帧(见下文“读取参考视频”)。网站:如果可以打开,滚动它并每隔一段距离截图。将风格(颜色、光照、类型、背景运动)与编排(何时移动什么)分开记录——人们通常只想要参考中的其中一个,如果不清楚,你应该询问是哪一个。
2. 将其翻译为场景规范
阅读 references/scene-language.md,然后按照 references/scene-spec.md 中的格式编写规范。对于每个场景:一句话说明想法、对象、默认风格或选定的外观,以及一个节拍表——在滚动的每一段(0–15%、15–40%……)屏幕上显示的内容,包括摄像机运动、运动(动词 + 缓动 + 持续时间)、灯光/颜色变化、效果(粒子、扭曲、发光)以及文本做什么。
模糊的词汇在这里解决,而不是在代码中。“它被吸进去”变成:标题字母螺旋向屏幕中心移动,每个字母在漩涡边缘到达它时开始,旋转150°,同时缩小到15%并在滚动10%的范围内模糊到6px;背景在同一窗口中向中心扭曲。如果一个词可能意味着两种截然不同的东西,提供两种具体的解读,并选择更可能的一种作为默认值。
3. 构建前确认
将规范展示给用户——他们只需一分钟阅读,却能节省数小时。请他们纠正任何与他们想象不符的地方,特别是节奏(太快/太慢)和每个场景的关键时刻。保持消息简短:节拍表加上2–3个有针对性的问题,并附上你的默认答案,这样“好的,继续”就是一个有效的回复。
如果你无法询问(一次性或自动化请求),继续使用你的默认设置,并在最终消息中包含规范,以便用户可以精确地重新定向。
4. 分层构建
在编写代码之前阅读 references/architecture.md——从它的“这到底是否需要WebGL?”表格开始——以及 references/techniques.md 以了解规范中的每种效果。
代码的位置:
- 新网站(落地页、产品页、任何单页):
node <技能目录>/scripts/create-site.mjs <文件夹>创建一个现成的Next.js项目,带有默认背景、字体和lint设置;向其中添加场景。 - 现有网站:在其项目中进行操作,并首先阅读
architecture.md中的“在现有网站中工作”。 - 完整作品集:从模板开始(
references/portfolio.md)。
然后按此顺序构建每个场景,在每一层之后进行检查:
- 粗布——固定区域,每个节拍一个插槽的滚动时间线,占位形状和摄像机路径。
scripts/new-scene.mjs <项目> <名称> --beats N生成此骨架,已连线(滚动进度 → 共享时间线 → 3D摄像机和DOM标题,减少运动回退,离开屏幕时暂停);添加--no-canvas表示仅DOM效果。滚动查看:节拍顺序和节奏是否正确? - 运动——真实的运动和过渡,使用规范中的缓动和持续时间。时机是人们对动画反应最强烈的部分;在让它变漂亮之前先做对。
- 外观——材质、光照、颜色、发光、粒子、背景、排版。
- 润色——指针倾斜、空闲漂移、小的次要运动、移动端取景、减少运动。
运行 npm run lint 以及构建——React规则在逐帧突变错误变成细微错误之前就将其捕获。
5. 根据规范验证
构建(npm run build),运行它,并在每个节拍的滚动位置截图。将每个截图与节拍表逐行比较:那个对象是否在那里,摄像机是否如描述那样取景,文本是否到位,颜色是否正确?在展示之前修复不匹配的地方。每次滚动后等待一秒再截图——场景会逐渐到位。还要检查手机大小的视口(375×812)和减少运动。如果你没有浏览器工具,坦诚地说场景已构建但未查看,并列出需要检查的内容。
6. 使用精确语言优化
当用户做出反应(“感觉廉价”、“太多”、“不够戏剧化”)时,使用 scene-language.md 像对待原始请求一样翻译反馈,提出具体的更改(“将俯冲从滚动的8%减到14%,并在之前添加0.3秒的停顿”),然后执行。当他们不确定时,一次只更改一件事,这样他们就能知道哪些有帮助。
读取参考视频
node <技能目录>/scripts/video-frames.mjs <视频> --every 0.25 --out frames/
它需要 ffmpeg(脚本会解释如何安装)。按顺序查看帧,并按时间段记录:屏幕上有什么、什么移动了以及如何移动(方向、速度、缓动——是加速、过冲还是稳定?)、摄像机(静态、推拉、环绕、抖动)、剪辑与连续移动、以及颜色/光照。这个列表就是节拍表的第一稿。对于快速时刻,在该时间段内重新运行 --every 0.04(使用 --from、--to)。
不可妥协的事项
这些来自真实的失败案例;每个都有 architecture.md 中的原因。
- 每个场景都有一个减少运动的版本(一个仍然显示所有内容的静态布局)。
- WebGL仅客户端加载,并在其区域离开屏幕或标签页隐藏时暂停。
- 3D和DOM文本读取相同的时间线函数,因此它们不会漂移分离。
- 固定区域内的滚动关联值使用函数变换,而不是范围数组。
- 使用伪造的发光(叠加光晕),而不是后期处理泛光效果,除非用户接受其成本。
- 页面的所有内容都是真实的、可读的文本(在DOM中)——而不是仅渲染到画布中。
- 永远不要在文案中编造关于人物或产品的事实;设计文本可以,但声明不行。你没有得到的价格、规格、日期、统计数据和奖项,应以可见的
[占位符]形式存在。 - 任何自动播放的内容(加载时的开场)都有一个可见的跳过控件,并且每个场景都有一个无WebGL的回退(海报图片或静态布局)。
- 在他人现有的网站中,只更改效果所需的部分,并说明哪些内容被移动了。
需要保留的致谢
模板中致谢了原始作者以及其构建所依赖的开源组件(ColorBends 和 Magnet 的 React Bits,以及 dungyov.com 的字体配对)。在重用这些部分时,请保留这些致谢。