关于 isometric-animation
用于制作独立 HTML 等距 2.5D 动画场景的技能,面向设计师和开发者,涵盖投影、深度、运动设计及逐帧视觉验证。
主要功能
- 01真等距与 2:1 斜等轴投影
- 02CSS、SVG 或 Three.js 场景方案
- 03堆叠图层与爆炸视图
- 04深度着色与动画指导
- 05可定位时间线和截图检查
- 06减少动态效果支持
适用场景
- 01制作等距产品讲解动画
- 02构建堆叠楼层或技术图层
- 03制作爆炸视图信息图
- 04为静态等距插画添加轻微动效
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ explainer-video-skills --skill isometric-animation安装后在 Claude Code 中输入/isometric-animation确认已加载。
附带文件README.mdreferences/isometric-recipes.md
详细介绍
等距(2.5D)动画
等距场景无需真实透视,就能为讲解视频、UI 演示和信息图带来构造感与立体感:轴线缩短比例一致、Z 轴层叠、方块挤出、爆炸图。这种风格几何感十足、设计严谨——深度来自一致的轴线和逐面着色,动感则来自逐层展现结构。
适用场景
- 用于讲解视频、产品 UI 或“工作原理”信息图的 2.5D 场景。
- 自下而上搭建的层叠图层、楼层或技术栈塔。
- 挤出方块、等距网格、等距城市或服务器机架场景。
- 沿 Z 轴拆分并重新组装的爆炸图。
- 需要增添柔和动感的静态等距插画:镜头漂移、视差、悬停抬升。
投影:先把轴线弄对
两种约定——选一种,切勿混用:
- 真正的等距投影 — 三条轴彼此相隔 120°;在屏幕上,X/Y 地面轴与水平线分别呈 ±30°。这是数学上正确的等距投影。适用于 CSS/Three.js。
- 2:1 二测投影(“像素画等距投影”) — 瓷砖的宽高比为 2:1,因此轴线角度约为 26.57°(
atan(0.5))。像素更规整,是游戏美术的默认选择。适用于瓷砖/精灵场景。
对于 DOM/SVG,最快创建真正等距平面的方式是在 perspective: none(呈正交投影效果)的容器上使用 CSS 3D 变换:
.scene { transform-style: preserve-3d; }
/* rotate a flat plane onto the iso ground */
.iso-plane { transform: rotateX(60deg) rotateZ(45deg); }
rotateX(60deg) rotateZ(45deg) 会让平面元素向后倾斜 60°,再旋转 45°——这是标准的“真正等距”组合,可使地面轴线在屏幕上呈 ±30°。将任意平面 SVG/DOM(平面图、UI 模型或网格)放在 .iso-plane 上,它就会成为等距表面;使用 translateZ() 将子元素朝摄像机方向抬起。
使用代码放置瓷砖时(2:1 二测投影),对应的网格到屏幕坐标转换公式如下:
// tile (col, row) → screen pixels, TILE = full tile width
const screenX = (col - row) * (TILE / 2);
const screenY = (col + row) * (TILE / 4);
关闭 perspective(或将其设为很大的值)——等距投影是平行投影,因此远处物体绝不能缩小。较小的 perspective 会让画面看起来像倾斜的 3D 卡片,而不是等距投影。
构建场景
Z 轴层叠(卡片/楼层)
每一层都是等距平面上形状相同的平面,沿 Z 轴分隔。后续图层抬高一些;按自下而上的顺序逐层显示。
<div class="scene"><div class="iso-plane">
<div class="layer" style="--z:0"> </div>
<div class="layer" style="--z:40"> </div>
<div class="layer" style="--z:80"> </div>
</div></div>
.layer { transform: translateZ(calc(var(--z) * 1px)); }
挤出方块(面 + 逐面着色 = 深度)
实心方块由一个顶面和两个可见侧面组成。按面着色,让眼睛感受到体积——顶面最亮、左面中等、右面最暗(光线方向固定)。这是营造可信等距深度最重要的技巧。
.block .top { background:#3a9bff; } /* lit */
.block .left { background:#2c78c8; transform: rotateY(-90deg); transform-origin:left; }
.block .right { background:#1f5896; transform: rotateX(90deg); transform-origin:bottom; } /* shade */
SVG 也遵循相同的着色规则:绘制三个多边形(顶部菱形、左右平行四边形),并分别填充亮色、中间色和暗色。绘制多个小方块时,SVG 通常比 3D CSS 更简单(参见参考资料)。
等距网格
地面网格只需在 .iso-plane 上绘制两组平行线(先平面绘制,再通过旋转呈现等距效果)。在 SVG 中以平面形式绘制,将其放到平面上,然后使用 stroke-dashoffset 动画绘制线条。
爆炸图
与层叠图层相同,但静止状态下图层沿 Z 轴彼此分开;组装时,将每一层的 translateZ 动画移动到对应的就位值。爆炸时反向播放。使用同一个 --gap 变量,让整个堆叠结构一起展开/闭合。
动效
| 目标 | 实现方式 | 缓动 |
|---|---|---|
| 图层显现(构建) | 每层从下方通过 opacity 和 translateZ 显现,并依次错开 | back.out(1.4),错开 0.12s |
| 炸开 / 组装 | 补间共享的 --gap(或每个图层的 translateZ) | power3.inOut,0.7–1s |
| 塔楼 / 堆叠构建 | 图层从底部到顶部依次落下 | back.out(1.5),错开 0.15s |
| 摄像机漂移 | 对 .scene 缓慢执行 rotateZ / translate,循环往返 | sine.inOut,6–12s |
| 视差 | 图层根据深度随指针 / 滚动移动(--z ∝ 位移) | power2.out |
| 悬停抬升 | 单个方块 translateZ(+12px),并添加柔和阴影 | power2.out,0.25s |
保持等距视觉效果的规则:
- 沿 Z 轴抬升,绝不要缩放来模拟高度——缩放会破坏平行投影。
- 摄像机漂移必须幅度极小且速度缓慢(几度 / 像素)。大幅移动会暴露场景是一个平面。
- 按物理位置错开构建顺序(先构建底层),不要按 DOM 顺序,这样结构的组装过程才符合逻辑。
- 整个场景保持光线方向固定——每个方块的受光方式都应一致。
Three.js OrthographicCamera(真实 3D 等距视图)——替代方案
当方块必须正确遮挡、投射真实阴影或在 3D 中旋转时,使用正交摄像机下的真实几何体(平行投影 = 真正的等距视图;PerspectiveCamera 并非等距视图)。
const aspect = innerWidth / innerHeight, d = 8;
const cam = new THREE.OrthographicCamera(-d*aspect, d*aspect, d, -d, 0.1, 100);
cam.position.set(10, 10, 10); // equal X,Y,Z → classic iso vantage
cam.lookAt(0, 0, 0);
position 各分量相等时会呈现 30° 等距视图;OrthographicCamera 会让远处物体保持相同大小。使用单一方向的光源,启用阴影,并在构建时错开 mesh.position.y / 缩放进入。完整设置见参考资料。
构建工具选择
- CSS 3D transforms — 适用于少量方块 / 图层,能在面上清晰显示 DOM / 文本;只需一个 HTML 文件。
- Inline SVG(等距多边形) — 适用于大量小方块、网格和信息图;最容易用 GSAP/CSS 制作动效,也不会出现 3D 变换的 z-fighting。
- Three.js + OrthographicCamera — 适用于需要真实遮挡、阴影或 3D 旋转的场景;仍可通过 CDN 打包成一个 HTML 文件。
- 像素 / 瓷砖(2:1) — 适用于游戏美术或地图场景;使用
(col-row, col+row)投影。
输出检查清单
- 轴线角度正确(真正的等距视图为 ±30°,2:1 为 ~26.57°);没有意外的透视缩小。
- 所有方块都按照同一个固定光源呈现顶面亮、侧面中等亮度、另一侧较暗的效果。
- 图层堆叠具有可信的深度——没有 z-fighting、面闪烁或重叠错误。
- 按物理位置(从底部向上)错开构建,每个节拍表达一个想法。
- 摄像机漂移幅度小、速度慢;炸开 / 组装时每层都能准确就位。
prefers-reduced-motion下显示最终组装完成的场景,且没有循环漂移。
交付与验证(独立 HTML)
打包的辅助脚本(
scripts/):scripts/seek-shot.sh anim.html 0 1.5 3会冻结?t=N测试环境,并截取每个时刻的画面;scripts/contact-sheet.sh sheet.png frame-*.png会将这些画面拼成一张图,方便快速查看。参见scripts/README.md。
对于自包含的等距场景(堆叠构建、爆炸图、漂浮的信息图),交付物应是一个可直接在浏览器中打开的 HTML 文件——无需构建步骤、无需框架、无需渲染管线。单文件是网页动画的合适选择;只有在单个文件确实无法承载时,才使用打包工具。(如果场景属于渲染视频的一部分,则将其构建为 Remotion 组合,并用 remotion still 验证。)
输出约定:
- 一个
.html文件:包含 CSS 3D 变换或内嵌 SVG(也可以从 CDN 加载 Three.js)、标记,以及放在一个内嵌<script>中、沿着一条主时间线运行的所有动画(const tl = gsap.timeline())——一个可供跳转的播放头。 - 加入跳转测试环境,以便冻结任意时刻并截图。
跳转测试环境——冻结精确时刻并截图。 这是帧定位在 Web 上的对应方式:?t=N 会将主时间线跳转到第 N 秒并暂停,因此截图会得到确定的静帧。
<script>
// ... build your master timeline as `tl` (the layer build / explode / drift) ...
const t = new URLSearchParams(location.search).get("t");
if (t !== null) { tl.pause(); tl.seek(parseFloat(t)); } // frozen at t seconds
// no ?t → plays normally
window.__ready = true; // ready signal for headless wait
console.log("duration", tl.duration());
</script>
对于没有 GSAP 时间线的 Three.js 场景,使用单一的 clock/进度值驱动构建,并通过 ?t=N 设置该值,然后渲染一帧——原理相同,得到一张确定的静帧。
验证循环——渲染 → 冻结 → 截图 → 检查:
- 在三个时刻打开文件——开始、中间、结束:
…/iso.html?t=0、?t=<dur/2>、?t=<dur>(在控制台中读取tl.duration())。 - 对每个冻结的帧进行无头截图:
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/iso.html?t=1.2" frame-mid.png - 检查投影,而不只是“动画有没有动”:
- 坐标轴——地面线应保持预期角度(真正等距为 ±30° / 斜二测约为 26.57°);垂直线保持垂直;任何元素都不应像透视投影那样缩短。
- 深度——图层按正确的 Z 顺序堆叠,方块遮挡关系正确,各面阴影能体现体积;没有 Z-fighting(重合面闪烁),也没有重叠错误(后方方块穿透前方方块)。
- 构建——中间帧的堆叠应按实际顺序部分组装;结束时每一层都应准确就位(爆炸效果完全闭合),过渡动画结束后不留偏移。
- 瑕疵——表面文字被裁切或倾斜、方块超出画布、字体加载前出现 FOUC、网格接缝锯齿。
- 迭代:修正角度、阴影和 Z 顺序;重新冻结相同的
?t值并截图,直到画面呈现出扎实的等距效果。
完成前:
- 可在浏览器中独立打开——无控制台错误、无 CDN 缺失。
- 使用一条主时间线(或一个 Three.js 进度值);
?t=N可冻结为确定的静帧。 - 已截取开始 / 中间 / 结束时刻的画面——坐标轴正确、深度 / Z 顺序正确、无 Z-fighting,构建后的各层准确就位。
- 各面阴影来自同一个固定光源且保持一致;没有意外的透视缩小。
prefers-reduced-motion会显示最终组装完成的场景,且不会循环漂移。
参考文件
references/isometric-recipes.md— 更完整、可运行的代码:投影数学(真正等距与 2:1 斜二测、变换与矩阵)、将平面 SVG/DOM 转换为等距平面、带逐面阴影的挤出方块(CSS 和 SVG)、堆叠图层与爆炸图构建、等距网格、摄像机漂移 / 视差 / 悬停,以及完整的 Three.jsOrthographicCamera等距场景——包含缓动说明和减少动态效果的处理。