沉浸式3D网站
这是一个页面,其中的3D是实时的,而非3D视频。访客的滚动就是时间线,光标则是第二个摄像头。真实的文字位于上方,可读且可选;WebGL画布位于其后。
你所交付的内容: 一个包含以下内容的构建文件夹:BRIEF.md、一个真正的 index.html、旁边的引擎文件,以及来自桌面端、手机端和减少动效模式的一系列截图,外加一份简短报告,说明你检查了什么以及哪些内容你无法检查。
是什么导致这些页面失败
大多数“3D网站”在整个页面中只使用一种技巧:一个旋转的模型,文字在其上淡入。到第三个部分时,访客已经看完了所有内容并停止滚动。四条规则可以防止这种情况:
- 每一幕都做不同的事情。 从 references/scene-kit.md 中使用至少四种不同的场景设备,且连续两次不使用相同的设备。
- 一个峰值。 有一幕是某人会向朋友描述的那个时刻。它获得最多的滚动空间、最好的场景,以及前一幕的平静,以便它能够更好地展现。
- 3D服务于信息。 每个场景都展现关于主题的真实内容:它是由什么构成的、它如何工作、它给人什么感觉。纯装饰性的场景会被删除。
- 文本在任何滚动位置都应保持可读。 如果在任何帧中,某行文字在场景之上难以阅读,那么移动的是场景,而不是文字。
第0步:简报
重复使用用户已经提供给你的内容。如果他们提供了完整的简报或说了“由你判断”,则自己编写 BRIEF.md,标记为在创意授权下编写,自行以品牌的口吻回答下面的每个问题,然后继续。否则,在一条消息中提出全部八个问题,以真实问题的形式提出,而不是你编造的菜单:
- 它是什么,为谁而建,以及他们最终应该做什么? 一个操作,一个随处使用的标签。
- 用三到五个词描述感觉,外加最多三个来自非网站领域的参考:一部电影、一个游戏、一张专辑封面、一家商店。命名网站会导致页面抄袭。
- 用他们的话来描述旅程: 访客最先看到什么,然后是什么,最后是什么。
- 什么地方应该平静,什么地方应该激烈。
- 在每个阶段,人们应该有什么感觉,以及他们应该记住的哪个时刻。 参见 references/feel.md。
- 这个网站应该做一件他们没有见过的网站做过的事情。 标志性动作的种子。推动他们给出真实的答案;“令人难忘”不算。
- 距离高端简约有多远: 提供 references/structures.md 中的范围。
- 一个连续的世界,还是独立的场景? 最大的结构性分支,由他们决定。此外:他们已经拥有的东西(标志、颜色、字体、产品照片、
.glb格式的3D模型)。
在构建文件夹中编写 BRIEF.md,使用他们自己的话记录他们的答案,然后添加:
- 旅程: 四到七个节拍,每个节拍都代表访客所知或所感的变化。
- 情感曲线: 每个节拍一行,描述感觉以及屏幕上导致这种感觉的内容。相邻节拍不能相同。
- 峰值: 访客会用来描述它的那个句子,以及它位于哪一幕中。
- 这是一个___的网站: 填入一种体验,而非一种技术。
- 标志性动作: 一种仅在这个网站上存在、被编码在页面中的交互。使用套件设备加上新数字不算。
- 任何有意的留白, 进行标记,以便检查时能够将其与死滚动区分开。
第1步:结构、记录日志,然后评分
按此顺序做三件事。所有三件事都在任何代码之前完成。
从 references/structures.md 中选择一个结构: 一个世界、章节、产品舞台、展览、游乐场、带有插图的编辑页、广播。导航、开场和结尾都由此决定。在 BRIEF.md 中说明为什么选择这个而不是其他的。
运行指纹记录日志。 读取保存你构建的文件夹中的 FINGERPRINTS.md(如果不存在则创建;初始为空)。你的计划必须在以下至少四个方面与所有现有行不同:结构、导航、英雄设备、幕序列、结尾、标志性动作。如果不符合要求,则修改计划,而不是日志。
进行评分。 首先是情感曲线,然后在 BRIEF.md 中以表格形式列出每个节拍的设备:
| 节拍 | 幕 | 感觉 | 设备 | 跨度 | 为什么选择这个设备 |
|---|---|---|---|---|---|
| 识别 | 英雄 | 好奇 | 玻璃物体 + 推拉 | 2 | 产品在文字被阅读之前就活生生地展现在眼前 |
| 转变 | 变形 | 期待 | 粒子变形 | 3 | 噪声变为形状,再变为名称 |
| 峰值 | 轨道 | 敬畏 | 摄像机轨道 | 3.5 | 穿过它,意味着里面有很多内容 |
| 证明 | 分解 | 信任 | 分解视图 | 2.5 | 展示部件,这正是其主张 |
| 承诺 | 结尾 | 平静 | 平静保持 | 1.5 | 页面停止并等待点击 |
构建前的检查:
- 结构的禁令得以遵守。
- 来自 references/scene-kit.md 的四个或更多设备系列,且连续两次不使用相同的。
- 没有两个相邻的幕共享同一种感觉。
- 峰值拥有明显最大的跨度,且其前的一幕更为平静。
- 结尾是解决并保持,而不是淡入页脚。
- 跨度以屏幕高度为单位。一部电影般的页面通常在8到14之间;编辑和游乐场页面可以更短。永远不要为了达到数字而填充。
第2步:构建
mkdir -p <构建目录> && cp <技能>/engine/stage.js <技能>/engine/stage.css <构建目录>/
从 templates/starter/index.html 开始构建结构(导入映射、画布、章节、一个模块脚本),并借用你评过分的幕模式。永远不要交付起始模板或其Orbis副本。 每个页面都应基于其自身的简报来编写。
引擎的工作原理(engine/stage.js,阅读头部注释):
- 页面是一个
<section data-act="name" data-span="2">的堆栈。每个部分持有一个.frame,该帧在该部分持续期间保持固定。 stage.act(name, { scene, camera, update(p, s), render(renderer, s), resize(w, h) })注册一个场景。p在0到1之间横跨整个幕。s包含time、dt、pointer(平滑后的值,范围为-1到1)、velocity(滚动速度)、width、height、reduced、coarse。- 哪个幕占据屏幕中央,哪个就渲染。共享同一个
scene对象的幕会一起更新,因此单个连续世界仅仅是多个幕指向同一个场景。 - 一个幕需要跨度大于1才能使
p移动。p是在帧保持固定的距离上测量的,因此跨度恰好为1时没有移动:p会从0直接跳到1,任何与其绑定的内容都不会显示。请使用1.25或更大的值。 - 每个部分都会获得
--p作为CSS变量,因此标题可以在与3D相同的时间线上移动。 data-reveal属性可以使任何元素在进入时淡入;使用style="--i:2"进行交错。- 使用
seg(p, a, b)将一个幕拆分为多个节拍,并使用ease.inOut及其同类函数来塑造它们。 - 无WebGL时:
html.no-webgl会显示每个幕的.poster。为每个幕提供一个海报(图片或渐变)。
使用 stage.css 顶部的令牌(画布、表面、墨水、柔和墨水、强调色、强调色墨水、两种字体)设计主题。永远不要为单个项目编辑引擎;特定行为应放在页面自身的脚本中。
Three.js 来自导入映射中固定的CDN版本(jsdelivr上的 [email protected])。保持固定。如果你需要更新的版本,选择至少两周前的版本并重新运行检查。
在编写标记之前阅读 references/design.md,在添加第二个场景之前阅读 references/performance.md。
第3步:证明
cd <构建目录> && npm i playwright-core # 每个构建文件夹执行一次;需要安装 Google Chrome
node <技能>/scripts/serve.mjs --root . --port 4600 &
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/desktop
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/phone --width 390 --height 844 --touch
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/reduced --reduced-motion --positions 0,1
该脚本会将每一幕滚动到五个位置,等待平滑效果稳定,截取每个位置的截图,并写入 sheet.png。脚本在以下情况下会失败:页面错误、请求失败、无WebGL、某个幕绘制了空白内容、以及横向滚动。通过意味着脚本可以运行,但并不代表效果良好。
然后打开每个 sheet.png 并查看。 对于每个幕的每个位置:每行文字都能被阅读吗?场景是否展示了节拍所说的内容?在手机上,是否有任何内容被裁剪、遮挡或过小?峰值看起来像峰值吗?结尾是否解决?修复,再次截图,再次查看。
然后是感觉检查(references/feel.md):冷启动滚动,对每一幕用一个词描述你的感觉,然后与 BRIEF.md 中的曲线进行比较。如果两者不一致,则修复页面。
坦言哪些内容没有被覆盖:无头Chrome以软件方式渲染WebGL,因此它报告的帧率并非真实设备的情况,并且它无法告诉你滚动在实际手机上的感觉。在宣布完成之前,请要求用户在手机上打开它。
硬性规则
| 绝不 | 而是 |
|---|---|
| 整个页面只使用一种场景设备 | 四个或更多系列,且连续两次不使用相同的 |
| 将文字烘焙到纹理或图像中 | 在画布上方使用真实的HTML |
| 滚动箭头、鼠标图标或“滚动探索” | 什么都不做。英雄部分本身就已足够 |
| 像 01/05 这样的章节计数器 | 删除它们 |
| 每个幕都居中排版 | 多样化:左、右、居中、拆分、顶部、底部 |
| 使用全屏深色覆盖层来制造对比 | 只在文本块后面使用 .scrim |
| 渐变文字、霓虹光晕 | 用字重和字号来强调 |
| 虚构的数字或统计数据 | 仅使用来自用户的真实数据 |
| 在可见文本中使用长破折号 | 使用句号、逗号、冒号 |
| 永不停止旋转的东西 | 运动跟随滚动或指针;静止时的运动应缓慢且微小 |
| 每个部分都使用全新的WebGL渲染器 | 一个画布、一个渲染器、多个场景(引擎已实现) |
| 交付起始页面 | 根据简报编写页面 |
| 在结构、日志和评分完成之前进行构建 | 执行第1步,全部三件事 |
| 两个峰值,或没有峰值 | 一个,拥有最大空间,且前一个幕较为平静 |
| 计划与之前的构建在日志的三列或更多列上匹配 | 修改计划,永不修改日志 |
| 未完成第3步就宣布完成 | 执行第3步,查看截图表格,进行感觉检查 |
输出
构建文件夹,然后是一份简短报告:结构和原因、针对每一行的指纹结果、旅程、情感曲线和峰值、评分表格、标志性动作、shoot.mjs 在所有三次运行中的报告、你在截图上看到的内容以及所做的修复、感觉检查(预期感觉与实际感觉的对比),以及你无法检查的内容。提供本地URL。然后将构建的行添加到 FINGERPRINTS.md 中。