state / harness / camera / pick / ui / sheets / render / urlparams。 经典脚本的顶层 const/let 落在同一个全局词法作用域,所以切片本身不改变任何行为—— 这一步先让"文件边界"与"模块语义"两件事分离:翻 ESM 时若出问题,责任清楚在 import/export,而不是切片切错了行。 切片踩到并修掉的:urlparams.js 被切掉了 IIFE 的收尾 })();(我按 len-2 收边界), node --check 当场报 Unexpected end of input。 截图基线分级也在这一步收敛:工程图/装配向导视图带 feGaussianBlur 发光滤镜, 同一构建两轮就有 ±1 抖动(先前扫描那两轮碰巧逐字节相同,才漏进"稳定"清单, 于是随机假 FAIL)。把 8 张工程图/向导视图连同 3 张线束 x-ray、boss_p07、 p03_mount_loose 一起转像素容差(存参考像素,阈值 mean<=0.02、单像素<=32, 约实测 20x 余量),其余 92 张仍要求逐字节相同。 关卡:92 张逐字节一致 + 13 张在噪声阈内;数据哈希与 IK exact 段一致。
39 lines
1.5 KiB
JavaScript
39 lines
1.5 KiB
JavaScript
/* 查看器数据:单文件时代这些是 build_viewer 字符串替换进来的 const,
|
||
现在用顶层 await 取。ESM 保证本模块在所有 import 它的模块之前完成,
|
||
所以下游文件可以直接读 DATA.parts,不需要 init() 编排。
|
||
路径相对文档基址(/webapp/index.html),因此 ../data 与 /docs 都能命中。 */
|
||
|
||
async function json(url) {
|
||
const r = await fetch(url);
|
||
if (!r.ok) throw new Error('取数据失败 ' + r.status + ' ' + url);
|
||
return r.json();
|
||
}
|
||
|
||
async function text(url) {
|
||
const r = await fetch(url);
|
||
if (!r.ok) throw new Error('取文件失败 ' + r.status + ' ' + url);
|
||
return r.text();
|
||
}
|
||
|
||
const [DATA, TRAVEL, COLLIDE, SCREWS, sheetSvg] = await Promise.all([
|
||
json('../data/mesh_arm.json'),
|
||
json('/docs/travel.json'),
|
||
json('/docs/collide.json'),
|
||
json('/docs/screws.json'),
|
||
// 工程图是 4 个真 SVG 文件(draw_sheet.py 产出),不再维护第二份 jsdata 副本
|
||
Promise.all(['front', 'joint', 'exploded', 'side']
|
||
.map(n => text('/docs/sheet_' + n + '.svg'))),
|
||
]);
|
||
|
||
if (!DATA || !Array.isArray(DATA.parts) || !DATA.parts.length) {
|
||
throw new Error('mesh_arm.json 里没有零件数据,先跑 python -m arm.build_model');
|
||
}
|
||
if (sheetSvg.length !== 4 || sheetSvg.some(s => s.indexOf('<svg') < 0)) {
|
||
throw new Error('工程图 SVG 不完整(应有 4 张且各含 <svg>)');
|
||
}
|
||
|
||
export { DATA, TRAVEL, COLLIDE, SCREWS };
|
||
export const SHEETS = sheetSvg;
|
||
export const TL = {};
|
||
for (const t of TRAVEL) TL[t.axis] = t;
|