1实现原理 · 为什么它能做到
投影先行:先在两套约定(true isometric 轴 ±30° / 2:1 dimetric 轴 ~26.57°)里选一套,之后绝不混用——轴系错了后面全错。
Two conventions — pick one and never mix:
用 CSS 3D 变换把任意平面推成 iso 地面:rotateX(60deg) rotateZ(45deg) 是标准 true-iso 组合,任何扁平 SVG/DOM(平面图、UI 稿、网格)放上去即成 iso 面,子元素用 translateZ 抬升。
.iso-plane { transform: rotateX(60deg) rotateZ(45deg); }
立体感靠每面独立着色:顶面最亮、左面中等、右面最暗,且全场光向固定——文中称之为让 iso 深度可信的最关键技巧。
.block .top { background:#3a9bff; } /* lit */
场景由四种可复用构件搭出:堆叠 Z 层(卡片/楼层)、挤出块(面 + 着色)、iso 网格、爆炸视图(共享 --gap 变量统一开合)。
Keep one shared `--gap` variable so the whole stack opens/closes together.
运动规则被写成禁令以维持 iso 可信度:抬升只能沿 Z(禁缩放假高度)、相机漂移必须小而慢、错峰必须按物理位置(自底向上)而非 DOM 顺序。
**Lift along Z, never scale** to fake height — scaling breaks parallel projection.
需要真遮挡、真阴影或 3D 旋转时升级到 Three.js OrthographicCamera:等值 position 给出经典 30° 视角,正交相机保持远处不缩小;PerspectiveCamera 明确不是 iso。
cam.position.set(10, 10, 10); // equal X,Y,Z → classic iso vantage
交付 = 单文件 HTML + 一条主时间轴 + ?t=N 冻结;验证要检的是投影本身(轴角是否对、Z 序与遮挡、有无 z-fighting、有无意外透视缩小),而不是「有没有动起来」。
**INSPECT the projection, not just "did it animate":
平行投影纪律贯穿全文:CSS 场景必须 perspective:none(或极大),Three.js 必须用正交相机——否则小 perspective 会被读成倾斜 3D 卡片而非 iso。
Keep `perspective` OFF (or very large) — iso is parallel projection, so far objects must NOT shrink.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | npx / Playwright(无头截图) |
| cli | ffmpeg(contact-sheet.sh 拼图) |
| cli | npx -y playwright(仓库根 seek-shot.sh 内部) |
| network | jsDelivr CDN:three.js(reference 里钉的是 0.160 具体版本) |
| network | jsDelivr CDN:gsap ESM(未钉版本,走 +esm 浮动入口) |
| package | 第三方库/能力:Three.js、GSAP;CSS 3D 与内联 SVG 路线零依赖 |
4风险提醒 风险提醒:橙色 · 评估后使用
- 复核回路引入远程包与浏览器二进制 — 跑一次验证即从 npm 拉 playwright 并下载 Chromium;离线/内网环境会失败,且属供应链接触面。可改用本地已装的 Playwright/浏览器或人工截图完成同一回路。
- gsap 走浮动 CDN 入口 — 交付 HTML 里 `gsap/+esm` 未钉版本(three.js 已钉 0.160),上游发新版可能改变成品行为;建议把两者都钉到具体版本或内联进单文件。
- CSS 3D 的 Z 序陷阱 — 文档自己承认 CSS 3D 会 z-fighting 并建议大量小块改用 SVG 绘制顺序;但选择判据(「多少块算多」)仍需使用者自行拿捏,块数上升时容易踩到闪烁/穿插。
- 跨目录引用悬空 — `scripts/` 在仓库根;只安装 skills/isometric-animation 时截图/拼图辅助不可用,需装整个 repo。
- 投影数学需人工核对 — 轴角与 matrix3d 常量无自动化断言,验证仍靠冻结帧肉眼比对;批量产出时应自加几何校验(如取两条地面线量角度)。
5第二遍独立确认
- [ok] 外部依赖调用点复核(npx playwright / ffmpeg / three.js / gsap) — SKILL.md Verify loop 内确有 `npx playwright screenshot --wait-for-timeout=500 "file://$PWD/iso.html?t=1.2" frame-mid.png`;仓库根 scripts/seek-shot.sh 与 contact-sheet.sh 分别为 npx playwright 与 ffmpeg;reference 第 7 节确有 `import * as THREE from "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js";` 与 `import gsap from "https://cdn.jsdelivr.net/npm/gsap/+esm";`。四条均落地。
- [ok] 投影主张与代码对账 — `rotateX(60deg) rotateZ(45deg)` 与 reference 给出的 matrix3d 预乘常量(0.707 / 0.409 / 0.816)自洽:cos30≈0.866…、sin30=0.5 与 0.707/0.409 的推导一致,能把地面轴压到屏幕 ±30°;Three.js 用的确为 OrthographicCamera 且 position 三分量相等(10,10,10)→ 经典 iso 视角。未见「用 PerspectiveCamera 冒充 iso」的自相矛盾。
- [ok] 无凭证 / 无 env / 无业务 API 反查 — 两个文档与三个仓库脚本中无 API_KEY/token/secret/.env 读取、无 curl/wget、无 fetch 到业务端点;唯一远程动作是包管理器与 CDN 静态资源。判 orange 的依据是「远程包/镜像」,不含凭据读取。
- [ok] 目录资产面清点 — skills/isometric-animation/ 下仅 SKILL.md(178 行)、references/ 一份 253 行 cookbook、0 字节 README.md;无 scripts/、无模板、无数据文件——「纯指令 + 内联代码片段」结论成立。
- [discrepancy] CDN 依赖的版本纪律差异 — 同一份 reference 内两种取法并存:three.js 钉到 0.160(可复现),gsap 走 `+esm` 浮动入口(上游发新版本即变)。这不是错误,但使「同一份 HTML 长期行为一致」的保证只覆盖 three.js 一侧;已在 verdict.risks 中标注。
- [discrepancy] 跨引用可解析性 — SKILL.md 引用的 `scripts/seek-shot.sh`、`scripts/contact-sheet.sh` 位于仓库根,单装本 skill 目录会悬空(需装整个 repo);正文把「成为视频的一部分」的路径交回同 repo 的 Remotion 路线(remotion still 验证),该技法的归属 skill(remotion-video)不在本 repo 的 5 个 skill 中。
- [ok] 功能声明 vs 实际能力 — frontmatter 宣称覆盖 CSS 3D transforms / SVG iso planes / Three.js OrthographicCamera 且强调 no build step;正文 Build-tool choice 与 reference 第 1–7 节逐条兑现,交付确为单文件 HTML(CDN 方式),无夸大。
6结论
0e7ea0aa5a9ac077…3e2d411b72