关于 exploded-view
exploded-view 是用于 three.js 的 JavaScript 技能,可在浏览器中制作带标签的交互式机械拆解视图,适合开发产品说明页面。它结合分阶段拆解、透视外壳、剖切和部件选择。
主要功能
- 01分阶段拆解部件
- 02带引导线的固定标签
- 03外壳 X-ray 视图
- 04外壳剖切
- 05悬停与点击选取部件
适用场景
- 01在产品说明中展示装配顺序
- 02透过外壳展示内部部件
- 03让浏览者识别并选择部件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ moh4696/ open-3d-skills --skill exploded-view安装后在 Claude Code 中输入/exploded-view确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/explode.jsassets/demo/index.htmlmotor.js详细介绍
爆炸图
人们看到机器按照组装时的顺序拆开,并且每个零件在对应位置都标有名称时,就能理解机器的构造。这个技能在浏览器中实现了这一效果:零件沿着合理的方向滑开,外壳变得半透明或被剖开,标签始终跟随对应零件,且不会遮挡模型。
工具
| 文件 | 功能 |
|---|---|
assets/explode.js | Exploder(分阶段爆炸图)、Labels(带引导线的固定标签)、Xray、Section(穿过外壳的裁剪平面)、Picker(悬停和点击) |
assets/demo/ | 完整页面:一个通过代码构建并拆解的感应电机,带有滑块、X 光和剖切功能。?explode=1、?cut=1、?xray=1 可设置状态 |
需要 three.js(演示的导入映射中使用 r169)。使用 threejs-scene 技术构建模型,或加载 GLB。
构建
1. 将模型拆分为零件
爆炸图的基本单位是零件:一个作为整体移动的 Group。将每个零件设为同一装配组的直接子级,并为每个零件指定独立的材质(X 光和悬停效果会改变材质;如果共用材质,一次操作就会同时改变所有零件)。
对于 GLB,加载时重新分组:遍历场景,根据节点名称将网格放入命名的零件组中。重新设置父级时保留世界变换(group.attach(mesh))。
2. 确定每个零件的移动方式
每个零件的设置放在 userData 上:
housing.userData = { shell: true, stage: 0, explode: [0, 0.32, 0] }; // lifts off first
rotor.userData = { stage: 2, explode: [0.42, 0, 0] }; // slides out along the shaft last
explode: [x, y, z]是完全展开时的偏移量。如果未设置,零件会远离装配中心移动(如果向Exploder传入了axis,则沿该轴移动),移动距离按其离中心的距离缩放。stage用于控制移动顺序:阶段 0 最先移动,之后每个阶段在前一阶段完成一半时开始。按照机械师拆解机器的方式安排顺序:先拆盖板和外壳,再拆紧固件和端盖,最后拆内部零件。shell: true将外壳标记为 X 光和剖切的对象。
像技术插图那样布置爆炸状态:设定一个主轴(轴杆、堆叠方向),让零件彼此留有足够间距,并将大型外壳移到轴外侧(向上),以便看清核心。
const ex = new Exploder(assembly);
ex.set(t); // 0 assembled .. 1 exploded; ease toward a target each frame for slider input
3. 为零件添加标签
const labels = new Labels(document.querySelector(".labels"), camera, canvas);
labels.add(rotor, "Rotor", { note: "turns in the magnetic field", anchor: [0.03, 0.07, 0] });
// every frame, after renderer.render():
labels.update();
标签分列放置在屏幕两侧,保持锚点的垂直顺序,并在可能重叠时彼此错开;引导线从每个标签连接到其锚点。标签会随零件一起移动,并在零件隐藏或位于相机后方时隐藏。将每个标签锚定在从主视角看始终可见的零件位置(例如顶部边缘或轴杆末端),并使用零件的局部坐标。
在 CSS 中设置 .label、.label b、.label span、.leader 及其 .focus 变体的样式。在较窄的手机屏幕上,隐藏标签,并在单个说明中显示悬停或点击的零件名称:在宽度为 390 px 的屏幕上,模型旁放不下两列标签。
4. X 光和剖切
const xray = new Xray(assembly); xray.set(true); // shells to 14% opacity, no depth write
renderer.localClippingEnabled = true;
const section = new Section(assembly, [0, 0, -1]); section.set(0); // cut the shells' front half away; null = off
剖切平面只切割外壳,因此打开外壳后,内部仍保持完整,就像剖视图所示的那样。剖切材质会设为双面材质,以便看清外壳内侧。
5. 拾取
new Picker(canvas, camera, assembly.children, {
onHover: (part) => highlightLabelOf(part),
onPick: (part) => focusOn(part),
});
悬停时会稍微提高零件的自发光颜色,并切换指针光标。点击后可以单独显示该零件、将相机移向该零件,或打开其说明。
相机和取景
- 根据当前屏幕形状调整相机,使装配体完整入镜,并让相机距离随爆炸程度变化(演示中的
autoDistance):组装状态时拉近,爆炸状态时拉远。访客缩放或环绕视角后,就停止自动调整。 - 将
OrbitControls.maxDistance设得高于适配后的距离,否则控件会在不提示的情况下限制距离,手机屏幕上就会出现裁切。 - 从略高处以四分之三角度观察(演示使用的方向为 0.42、0.34、1),可以同时看到圆柱形机器的端面和侧面。
通过滚动驱动
像 scroll-film 控制帧那样,通过带停留时间的关键帧将滚动进度映射到 ex.set():在介绍文字出现时逐步组装,按阶段逐步爆炸拆解,并为每个阶段配上说明文字;完全拆解后停留,最后进行剖切。模型是实时渲染的,因此访客可以随时停下来旋转查看。
渲染
对于讲解内容,产品摄影式布光比天空环境更合适:使用 RoomEnvironment PMREM 生成反射,用一盏柔和的主灯将阴影投射到 ShadowMaterial 地面上,采用 ACES 色调映射,并将页面本身的背景色设为清除颜色(不透明画布默认显示为黑色)。金属材质的粗糙度设为 0.3 到 0.45、金属度设为 0.8 到 0.95,效果更易辨识;喷漆部件则使用清漆层。
准确性
如果主题是真实产品,请使用真实的部件名称和真实的组装顺序,并在页面文案中说明哪些内部细节仅供示意。错误的讲解会让人确信地学到错误知识。