| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- // 对比同一画板的新旧 JSON:尺寸、导出标记数、切图文件、标题区结构、字体、色板
- import { readFileSync, readdirSync, existsSync } from 'node:fs'
- import { join } from 'node:path'
- const oldDir = '.scratch/lanhu-cockpit-asset-replacement/research/raw'
- const newDir = '.scratch/lanhu-cockpit-asset-replacement/research/raw-v2'
- function load(dir, file) {
- return JSON.parse(readFileSync(join(dir, file), 'utf8'))
- }
- function hex(c) {
- const h = (v) => Math.round(v * 255).toString(16).padStart(2, '0')
- return `#${h(c.r)}${h(c.g)}${h(c.b)}`
- }
- function summarize(j) {
- const ab = j.artboard
- let exportMarked = 0
- let ddsMarked = 0
- const exported = []
- const fonts = new Map()
- const colors = new Map()
- const images = []
- function walk(node, path) {
- const p = path ? `${path}/${node.name}` : node.name
- if (node.hasExportImage) {
- exportMarked += 1
- exported.push({ path: p, w: Math.round(node.frame?.width ?? 0), h: Math.round(node.frame?.height ?? 0), type: node.type })
- }
- if (node.hasExportDDSImage) ddsMarked += 1
- if (node.type === 'textLayer' && node.text?.style?.font?.name) {
- const f = node.text.style.font
- const k = `${f.name}|${f.size}`
- fonts.set(k, (fonts.get(k) || 0) + 1)
- }
- for (const f of node.style?.fills || []) {
- if (f.type === 'color' && f.color) {
- const c = hex(f.color)
- 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({ p, url })
- }
- for (const ch of node.layers || []) walk(ch, p)
- }
- for (const l of ab.layers || []) walk(l, '')
- const titleNode = (function find(n) {
- if (n.name === 'title') return n
- for (const c of n.layers || []) {
- const r = find(c)
- if (r) return r
- }
- return null
- })(ab)
- return {
- name: ab.name,
- frame: `${ab.frame.width}x${ab.frame.height}`,
- exportMarked,
- ddsMarked,
- assets: (j.assets || []).length,
- assetUrls: j.assets || [],
- fonts: fonts.size,
- fontList: [...fonts.keys()].slice(0, 8),
- colors: colors.size,
- topColors: [...colors.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([c]) => c),
- images: images.length,
- titleChildren: titleNode ? (titleNode.layers || []).map((c) => `${c.type}:${c.name} ${Math.round(c.frame?.width ?? 0)}x${Math.round(c.frame?.height ?? 0)}`) : [],
- exported: exported.slice(0, 40),
- }
- }
- const files = readdirSync(newDir).filter((f) => f.endsWith('.json'))
- for (const file of files) {
- const n = summarize(load(newDir, file))
- console.log(`\n=== NEW ${n.name} ${n.frame} | exportMarked=${n.exportMarked} dds=${n.ddsMarked} assets=${n.assets} fonts=${n.fonts} colors=${n.colors} images=${n.images}`)
- console.log(' fonts:', n.fontList.join(', '))
- console.log(' colors:', n.topColors.join(' '))
- console.log(' title:', n.titleChildren.join(' | '))
- console.log(' exported layers:')
- for (const e of n.exported) console.log(` ${e.w}x${e.h} ${e.type} | ${e.path}`)
- const oldPath = join(oldDir, file)
- if (existsSync(oldPath)) {
- const o = summarize(load(oldDir, file))
- console.log(` --- OLD ${o.name} ${o.frame} | exportMarked=${o.exportMarked} dds=${o.ddsMarked} assets=${o.assets} fonts=${o.fonts} colors=${o.colors} images=${o.images}`)
- console.log(' --- OLD title:', o.titleChildren.join(' | '))
- const oldSet = new Set(o.exported.map((e) => e.path))
- const added = n.exported.filter((e) => !oldSet.has(e.path))
- console.log(' --- NEW export layers (not in old):', added.length)
- for (const e of added) console.log(` + ${e.w}x${e.h} ${e.type} | ${e.path}`)
- }
- }
|