// 分析蓝湖 FigmaJSON:画板尺寸、切图(导出标记)、文本字体、图片引用、色板 import { readFileSync } from 'node:fs' const file = process.argv[2] const j = JSON.parse(readFileSync(file, 'utf8')) const ab = j.artboard const fonts = new Map() // name|postScript|size|weight -> {count, samples:Set} const slices = [] const images = [] const colors = new Map() function hex(c) { if (!c) return null const h = (v) => Math.round(v * 255).toString(16).padStart(2, '0') return `${h(c.r)}${h(c.g)}${h(c.b)}${c.a !== undefined && c.a < 1 ? h(c.a) : ''}` } function addFont(f, text) { if (!f || !f.name) return const key = `${f.name} | ${f.postScriptName || ''} | ${f.size}px | w${f.fontWeight ?? ''}${f.bold ? ' bold' : ''}` const cur = fonts.get(key) || { count: 0, samples: new Set() } cur.count += 1 if (text) cur.samples.add(String(text).slice(0, 12)) fonts.set(key, cur) } function walk(node, path) { const p = path ? `${path}/${node.name}` : node.name if (node.type === 'textLayer' && node.text) { addFont(node.text.style?.font, node.text.style?.content) for (const r of node.text.runs || node.text.styleRuns || []) addFont(r.font || r.style?.font, r.content || r.text) } if (node.hasExportImage || node.hasExportDDSImage) { slices.push({ path: p, type: node.type, w: Math.round(node.frame?.width ?? 0), h: Math.round(node.frame?.height ?? 0), dds: !!node.hasExportDDSImage }) } for (const f of node.style?.fills || []) { if (f.type === 'color' && f.color) { const c = hex(f.color) if (c) colors.set(c, (colors.get(c) || 0) + 1) } const url = f.ddsImage?.imageUrl || f.image?.imageUrl || f.imageUrl if (f.type === 'image' && url) { images.push({ path: p, url, w: Math.round(node.frame?.width ?? 0), h: Math.round(node.frame?.height ?? 0) }) } } for (const ch of node.layers || []) walk(ch, p) } for (const l of ab.layers || []) walk(l, '') const out = { artboard: ab.name, frame: { w: ab.frame.width, h: ab.frame.height }, sliceCount: slices.length, sliceLayers: slices, fonts: [...fonts.entries()].sort((a, b) => b[1].count - a[1].count).map(([k, v]) => ({ font: k, count: v.count, samples: [...v.samples].slice(0, 4) })), imageRefCount: images.length, imageRefs: images, topColors: [...colors.entries()].sort((a, b) => b[1] - a[1]).slice(0, 24).map(([k, v]) => ({ color: `#${k}`, count: v })), assetFiles: j.assets || [], } console.log(JSON.stringify(out, null, 1))