// 票 15 取证(六):主画板几何(顶栏 / 筛选条 / 面板 / 栏宽 / 内边距) import { readFileSync } from 'node:fs' const dir = '.scratch/lanhu-cockpit-asset-replacement/research/raw-v2' const load = (n) => JSON.parse(readFileSync(`${dir}/desktop-${String(n).padStart(2, '0')}.json`, 'utf8')).artboard for (const n of [6, 2, 5]) { const ab = load(n) console.log(`\n########## ${ab.name} ${ab.frame.width}x${ab.frame.height}`) for (const l of ab.layers || []) { console.log(` 顶层 ${l.type}:${l.name} @(${Math.round(l.frame.left)},${Math.round(l.frame.top)}) ${Math.round(l.frame.width)}x${Math.round(l.frame.height)}`) } // nav 及其子项 const nav = (ab.layers || []).find((l) => l.name === 'nav') if (nav) { console.log(' nav 子项:') for (const c of nav.layers || []) console.log(` ${c.type}:${c.name} @(${Math.round(c.frame.left)},${Math.round(c.frame.top)}) ${Math.round(c.frame.width)}x${Math.round(c.frame.height)}`) } // 面板几何:Panel 节点的位置、尺寸与内部 Header 高度、内边距 const panels = [] ;(function walk(node) { if (/^Panel$/.test(node.name) && node.frame?.width >= 300) panels.push(node) for (const c of node.layers || []) walk(c) })(ab) for (const p of panels.slice(0, 4)) { const header = (p.layers || []).find((c) => /Header/.test(c.name)) const container = (p.layers || []).find((c) => /Container/.test(c.name)) console.log( ` Panel @(${Math.round(p.frame.left)},${Math.round(p.frame.top)}) ${Math.round(p.frame.width)}x${Math.round(p.frame.height)}` + ` | Header ${header ? `${Math.round(header.frame.width)}x${Math.round(header.frame.height)}` : '-'}` + ` | Container ${container ? `${Math.round(container.frame.left - p.frame.left)},${Math.round(container.frame.top - p.frame.top)} ${Math.round(container.frame.width)}x${Math.round(container.frame.height)}` : '-'}`, ) } // 栏:面板按 left 值分组,看栏宽与栏间距 const xs = [...new Set(panels.map((p) => Math.round(p.frame.left)))].sort((a, b) => a - b) console.log(` Panel left 取值: ${xs.join(', ')}`) }