isometric-animation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseIsometric (2.5D) Animation
等距(2.5D)动画
Isometric scenes give explainers, UI walkthroughs, and infographics a built, dimensional feel without true perspective: equal-foreshortened axes, stacked Z layers, extruded blocks, exploded diagrams. The look is geometric and deliberate — depth comes from consistent axes and per-face shading, motion from revealing structure one layer at a time.
等距场景无需真实透视,就能为讲解动画、UI引导和信息图带来立体的构建感:等比例缩短的坐标轴、堆叠的Z轴图层、挤出块、爆炸图。这种风格几何感强且设计严谨——深度来自一致的坐标轴和逐面着色,动态效果则通过逐层展示结构来呈现。
When to use
适用场景
- 2.5D scenes for explainers, product UI, or "how it works" infographics.
- Stacked layers / floors / a tech-stack tower that builds bottom-up.
- Extruded blocks, isometric grids, isometric city/server-rack scenes.
- Exploded-view diagrams that pull apart along Z and reassemble.
- A static iso illustration that needs gentle life: camera drift, parallax, hover lift.
- 用于讲解动画、产品UI或「工作原理」信息图的2.5D场景。
- 自下而上构建的堆叠图层/楼层/技术栈塔。
- 挤出块、等距网格、等距城市/服务器机架场景。
- 沿Z轴拆分后重新组装的爆炸视图图。
- 需要增添细微生机的静态等距插画:相机漂移、视差效果、悬停抬升。
Projection: get the axes right first
投影:先确定正确的坐标轴
Two conventions — pick one and never mix:
- True isometric — all three axes 120° apart; on screen the X/Y ground axes run at ±30° from horizontal. This is the math-correct iso. Use for CSS/Three.js.
- 2:1 dimetric ("pixel-art iso") — tiles drawn 2 wide : 1 tall, so axes sit at ~26.57° (). Cleaner pixels, the game-art default. Use for tile/sprite scenes.
atan(0.5)
For DOM/SVG the fastest true-iso plane is a CSS 3D transform on a (orthographic-feeling) container:
perspective: nonecss
.scene { transform-style: preserve-3d; }
/* rotate a flat plane onto the iso ground */
.iso-plane { transform: rotateX(60deg) rotateZ(45deg); }rotateX(60deg) rotateZ(45deg).iso-planetranslateZ()Equivalent grid-to-screen math when you place tiles by code (2:1 dimetric):
js
// tile (col, row) → screen pixels, TILE = full tile width
const screenX = (col - row) * (TILE / 2);
const screenY = (col + row) * (TILE / 4);Keep OFF (or very large) — iso is parallel projection, so far objects must NOT shrink. A small reads as a tilted 3D card, not iso.
perspectiveperspective两种约定——选其一且切勿混用:
- 真等距——三个坐标轴彼此呈120°;在屏幕上X/Y地面坐标轴与水平线呈**±30°**。这是数学上准确的等距方式,适用于CSS/Three.js。
- 2:1斜二测(「像素艺术等距」)—— tiles绘制比例为2宽:1高,因此坐标轴与水平线呈~26.57°()。像素效果更清晰,是游戏美术的默认选择,适用于 tile/精灵场景。
atan(0.5)
对于DOM/SVG,最快实现真等距平面的方式是在(正交视觉)容器上应用CSS 3D变换:
perspective: nonecss
.scene { transform-style: preserve-3d; }
/* 将平面旋转至等距地面 */
.iso-plane { transform: rotateX(60deg) rotateZ(45deg); }rotateX(60deg) rotateZ(45deg).iso-planetranslateZ()通过代码放置tiles时(2:1斜二测),对应的网格转屏幕坐标公式:
js
// tile (列, 行) → 屏幕像素,TILE = tile完整宽度
const screenX = (col - row) * (TILE / 2);
const screenY = (col + row) * (TILE / 4);务必关闭(或设置为极大值)——等距是平行投影,因此远处物体绝对不能缩小。较小的会让场景看起来像倾斜的3D卡片,而非等距效果。
perspectiveperspectiveBuilding scenes
场景构建
Stacked Z layers (cards / floors)
堆叠Z轴图层(卡片/楼层)
Each layer is the same flat shape on the iso plane, separated along Z. Lift later layers higher; stagger reveals bottom-up.
html
<div class="scene"><div class="iso-plane">
<div class="layer" style="--z:0"> <!-- base --></div>
<div class="layer" style="--z:40"> <!-- mid --></div>
<div class="layer" style="--z:80"> <!-- top --></div>
</div></div>css
.layer { transform: translateZ(calc(var(--z) * 1px)); }每个图层都是等距平面上的相同平面形状,沿Z轴分隔。将上层图层抬升更高;交错展示实现自下而上构建的效果。
html
<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>css
.layer { transform: translateZ(calc(var(--z) * 1px)); }Extruded block (faces + per-face shading = depth)
挤出块(面+逐面着色=深度)
A solid block is a top + two visible side faces. Shade by face so the eye reads volume — top lightest, left mid, right darkest (a fixed light direction). This is the single most important trick for believable iso depth.
css
.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 */Same shading rule in SVG: draw three polygons (top rhombus, left + right parallelograms) and fill them light/mid/dark. SVG is often simpler than 3D-CSS for many small blocks (see references).
实心块由顶面+两个可见侧面组成。通过逐面着色让眼睛感知体积——顶面最亮,左侧中等亮度,右侧最暗(固定光源方向)。这是实现逼真等距深度最重要的技巧。
css
.block .top { background:#3a9bff; } /* 受光面 */
.block .left { background:#2c78c8; transform: rotateY(-90deg); transform-origin:left; }
.block .right { background:#1f5896; transform: rotateX(90deg); transform-origin:bottom; } /* 阴影面 */SVG中遵循相同的着色规则:绘制三个多边形(顶面菱形、左侧+右侧平行四边形)并填充亮/中等/暗色调。对于许多小方块,SVG通常比3D-CSS更简单(参见参考资料)。
Isometric grid
等距网格
A floor grid is just two sets of parallel lines on (drawn flat, the rotation makes them iso). Author it flat in SVG, drop it on the plane, animate lines drawing on with .
.iso-planestroke-dashoffset地面网格只是上的两组平行线(平面绘制,旋转后形成等距效果)。在SVG中平面绘制网格,将其放置在平面上,通过实现线条绘制动画。
.iso-planestroke-dashoffsetExploded-view diagram
爆炸视图图
Same as stacked layers but the resting state is pulled apart along Z; assemble = animate every layer's toward its seated value. Explode = reverse. Keep one shared variable so the whole stack opens/closes together.
translateZ--gap与堆叠图层原理相同,但静止状态是沿Z轴拆分;组装动画就是将每个图层的动画到其就位值。拆分则是反向动画。使用一个共享的变量,让整个堆叠同步展开/闭合。
translateZ--gapMotion
动效实现
| Goal | Mechanism | Easing |
|---|---|---|
| Layer reveal (build) | per-layer | |
| Explode / assemble | tween shared | |
| Tower / stack build | layers drop in bottom→top | |
| Camera drift | slow | |
| Parallax | layers shift by depth on pointer/scroll ( | |
| Hover lift | one block | |
Rules that keep it reading as iso:
- Lift along Z, never scale to fake height — scaling breaks parallel projection.
- Camera drift must be tiny and slow (a few degrees / pixels). Big moves expose that it's a flat plane.
- Stagger builds by physical position (bottom layer first), not DOM order, so the structure assembles logically.
- Keep the light direction fixed for the whole scene — every block shades the same way.
| 目标 | 实现方式 | 缓动函数 |
|---|---|---|
| 图层展示(构建) | 逐图层从下方应用 | |
| 拆分/组装 | 缓动共享变量 | |
| 塔/堆叠构建 | 图层自下而上落下 | |
| 相机漂移 | 在 | |
| 视差效果 | 图层随指针/滚动按深度偏移( | |
| 悬停抬升 | 单个方块应用 | |
保持等距视觉效果的规则:
- 沿Z轴抬升,切勿缩放来模拟高度——缩放会破坏平行投影。
- 相机漂移必须细微且缓慢(几度/几像素)。大幅移动会暴露场景是平面。
- 按物理位置(底层优先)交错构建,而非DOM顺序,确保结构组装逻辑合理。
- 整个场景保持固定光源方向——所有方块的着色方式一致。
Three.js OrthographicCamera (true 3D iso) — alternative
Three.js OrthographicCamera(真3D等距)——替代方案
When blocks must occlude correctly, cast real shadows, or rotate in 3D, use real geometry under an orthographic camera (parallel projection = genuine iso; a is NOT iso).
PerspectiveCamerajs
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);Equal components give the 30° iso view; keeps far objects the same size. Light from one direction, enable shadows, and stagger / scale-in for the build. Full setup in references.
positionOrthographicCameramesh.position.y当方块需要正确遮挡、投射真实阴影或进行3D旋转时,可在正交相机下使用真实几何体(平行投影=真正的等距效果;并非等距相机)。
PerspectiveCamerajs
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); // X,Y,Z值相等 → 经典等距视角
cam.lookAt(0, 0, 0);positionOrthographicCameramesh.position.yBuild-tool choice
构建工具选择
- CSS 3D transforms — best for a handful of blocks/layers with crisp DOM/text on faces; one HTML file.
- Inline SVG (iso polygons) — best for many small blocks, grids, and infographics; easiest to animate with GSAP/CSS, no 3D-transform z-fighting.
- Three.js + OrthographicCamera — when you need real occlusion, shadows, or 3D rotation; still shippable as one HTML file via CDN.
- Pixel/tile (2:1) — game-art or map scenes; use the projection.
(col-row, col+row)
- CSS 3D transforms——最适合少量带清晰DOM/text的方块/图层;单HTML文件即可实现。
- 内联SVG(等距多边形)——最适合大量小方块、网格和信息图;使用GSAP/CSS动画最简单,无3D变换的Z轴冲突问题。
- Three.js + OrthographicCamera——当需要真实遮挡、阴影或3D旋转时使用;仍可通过CDN打包为单HTML文件交付。
- 像素/tile(2:1)——游戏美术或地图场景;使用投影公式。
(col-row, col+row)
Output checklist
输出检查清单
- Axes land at the right angle (±30° true-iso, ~26.57° for 2:1); no accidental perspective shrink.
- Every block shaded top-light / side-mid / side-dark from one fixed light.
- Layers stack with believable depth — no z-fighting, no two faces flickering, no overlap errors.
- Build staggers by physical position (bottom-up), one idea per beat.
- Camera drift is small and slow; explode/assemble seats every layer exactly.
- shows the final assembled scene with no looping drift.
prefers-reduced-motion
- 坐标轴角度正确(真等距±30°,2:1斜二测~26.57°);无意外透视缩小。
- 每个方块都从固定光源出发,遵循顶面亮/侧面中等/侧面暗的着色规则。
- 图层堆叠具有逼真深度——无Z轴冲突、无两面闪烁、无重叠错误。
- 按物理位置(自下而上)交错构建,每一步展示一个元素。
- 相机漂移细微且缓慢;拆分/组装时每个图层都精准就位。
- 当开启时,展示最终组装完成的场景,无循环漂移。
prefers-reduced-motion
Deliver & verify (standalone HTML)
交付与验证(独立HTML)
Packaged helper ():scripts/freezes thescripts/seek-shot.sh anim.html 0 1.5 3harness and screenshots each moment;?t=Ntiles them for one-glance review. Seescripts/contact-sheet.sh sheet.png frame-*.png.scripts/README.md
For a self-contained iso scene (stack build, exploded diagram, drifting infographic) the deliverable is one HTML file that opens directly in a browser — no build step, no framework, no render pipeline. A single file is the right tier for web motion; reach for a bundler only when one file genuinely can't carry it. (If the scene is part of a rendered video, build it as a Remotion composition and verify with instead.)
remotion stillOutput contract:
- One file: CSS 3D transforms or inline SVG (or Three.js from CDN), markup, and all motion in one inline
.htmlon one master timeline (<script>) — a single playhead you can seek.const tl = gsap.timeline() - Include the seek harness so any moment can be frozen for a screenshot.
Seek harness — freeze an exact moment for screenshots. The web parallel of a frame-pin: seeks the master timeline to seconds and pauses, so a screenshot lands on a deterministic still.
?t=NNhtml
<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>For a Three.js scene with no GSAP timeline, drive the build from a single /progress value and set it from , then render one frame — same idea, one deterministic still.
clock?t=NVerify loop — render → freeze → screenshot → check:
- Open the file at three moments — start, mid, end:
,
…/iso.html?t=0,?t=<dur/2>(read?t=<dur>from the console).tl.duration() - Headless-screenshot each frozen frame:
bash
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/iso.html?t=1.2" frame-mid.png - INSPECT the projection, not just "did it animate":
- Axes — ground lines run at the intended angle (±30° true-iso / ~26.57° dimetric); verticals stay vertical; nothing is foreshortened like perspective.
- Depth — layers stack in the right Z order, blocks occlude correctly, per-face shading reads volume; no z-fighting (flickering coincident faces) and no overlap errors (a back block punching through a front one).
- Build — at mid-frame the stack is partway assembled in physical order; at end every layer is exactly seated (explode fully closed), no drift left mid-tween.
- Artifacts — clipped/skewed text on faces, off-canvas blocks, FOUC before fonts, jagged grid seams.
- Iterate: fix angle/shading/Z-order, re-freeze the same values, re-screenshot until it reads as solid iso.
?t
Before you finish:
- Opens standalone in a browser — no console errors, no missing CDN.
- One master timeline (or one Three.js progress value); freezes on a deterministic still.
?t=N - Screenshotted at start / mid / end — axes correct, depth/Z-order correct, no z-fighting, build seats exactly.
- Per-face shading consistent from one fixed light; no accidental perspective shrink.
- shows the final assembled scene without looping drift.
prefers-reduced-motion
打包工具(目录):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文件——无需构建步骤、无需框架、无需渲染流水线。单文件是Web动效的理想交付形式;仅当单文件确实无法承载内容时才使用打包工具。(如果场景是渲染视频的一部分,可将其构建为Remotion合成,并使用进行验证。)
remotion still输出规范:
- 单个文件:包含CSS 3D transforms或内联SVG(或通过CDN引入Three.js)、标记语言,以及所有动效都在一个内联
.html中的主时间线(<script>)——一个可定位的单一播放头。const tl = gsap.timeline() - 包含定位工具,以便冻结任意时刻进行截图。
定位工具——冻结精确时刻进行截图。相当于Web版的帧锁定:会将主时间线定位到第N秒并暂停,因此截图会得到确定的静态画面。
?t=Nhtml
<script>
// ... 将主时间线构建为`tl`(图层构建/拆分/漂移) ...
const t = new URLSearchParams(location.search).get("t");
if (t !== null) { tl.pause(); tl.seek(parseFloat(t)); } // 在t秒处冻结
// 无?t参数 → 正常播放
window.__ready = true; // 无头模式就绪信号
console.log("duration", tl.duration());
</script>对于没有GSAP时间线的Three.js场景,可通过单个/进度值驱动构建,并从设置该值,然后渲染一帧——原理相同,得到确定的静态画面。
clock?t=N验证流程——渲染→冻结→截图→检查:
- 在三个时刻打开文件——开始、中间、结束:
、
…/iso.html?t=0、?t=<dur/2>(从控制台读取?t=<dur>)。tl.duration() - 无头模式截取每个冻结帧的截图:
bash
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/iso.html?t=1.2" frame-mid.png - 检查投影效果,而非仅看「是否动起来」:
- 坐标轴——地面线条呈预期角度(真等距±30° / 斜二测~26.57°);垂直线保持垂直;无透视缩短效果。
- 深度——图层按正确Z轴顺序堆叠,方块正确遮挡,逐面着色体现体积;无Z轴冲突(重合面闪烁)和无重叠错误(后方方块穿透前方方块)。
- 构建过程——中间帧时堆叠按物理顺序部分组装;结束帧时每个图层都精准就位(拆分完全闭合),无中途漂移。
- ** artifacts**——面上的文本被裁剪/扭曲,方块超出画布,字体加载前的FOUC,网格接缝锯齿状。
- 迭代:修正角度/着色/Z轴顺序,重新冻结相同值,重新截图直到呈现稳定的等距效果。
?t
完成前检查:
- 可在浏览器中独立打开——无控制台错误,无CDN缺失。
- 单个主时间线(或单个Three.js进度值);可冻结在确定的静态画面。
?t=N - 已在开始/中间/结束时刻截图——坐标轴正确,深度/Z轴顺序正确,无Z轴冲突,构建精准就位。
- 逐面着色从固定光源出发保持一致;无意外透视缩小。
- 模式下展示最终组装完成的场景,无循环漂移。
prefers-reduced-motion
Reference files
参考文件
- — fuller runnable code: the projection math (true-iso vs 2:1 dimetric, transform vs matrix), flat-SVG/DOM → iso-plane conversion, extruded-block faces with per-face shading (CSS and SVG), stacked-layer and exploded-view builds, isometric grid, camera drift / parallax / hover, and a complete Three.js
references/isometric-recipes.mdiso scene — with easing notes and reduced-motion handling.OrthographicCamera
- ——更完整的可运行代码:投影数学(真等距vs2:1斜二测,变换vs矩阵)、平面SVG/DOM→等距平面转换、带逐面着色的挤出块面(CSS和SVG)、堆叠图层和爆炸视图构建、等距网格、相机漂移/视差/悬停效果,以及完整的Three.js
references/isometric-recipes.md等距场景——包含缓动说明和减少动效处理。OrthographicCamera