probe-v2-main-palette.mjs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // 票 15 取证(四):主画板(Desktop-6,总体概览/首页)单独色板与文字层级
  2. import { readFileSync } from 'node:fs'
  3. const dir = '.scratch/lanhu-cockpit-asset-replacement/research/raw-v2'
  4. const hex = (c) => `#${[c.r, c.g, c.b].map((v) => Math.round(v * 255).toString(16).padStart(2, '0')).join('')}`
  5. const alpha = (c) => (c.a === undefined || c.a > 0.999 ? '' : `@${c.a.toFixed(2)}`)
  6. for (const n of [6, 2]) {
  7. const ab = JSON.parse(readFileSync(`${dir}/desktop-${String(n).padStart(2, '0')}.json`, 'utf8')).artboard
  8. const fills = new Map()
  9. const textColors = new Map()
  10. const sizes = new Map()
  11. ;(function walk(node, path = '') {
  12. const p = path ? `${path}/${node.name}` : node.name
  13. for (const f of node.style?.fills || []) {
  14. if (f.type === 'color') {
  15. const k = hex(f.color) + alpha(f.color)
  16. const cur = fills.get(k) || { c: 0, sample: '' }
  17. cur.c += 1
  18. if (!cur.sample) cur.sample = p
  19. fills.set(k, cur)
  20. }
  21. }
  22. if (node.type === 'textLayer' && node.text?.style) {
  23. const c = node.text.style.color
  24. const f = node.text.style.font
  25. if (c) {
  26. const k = `${f?.size}px ${hex(c)}${alpha(c)}`
  27. const cur = textColors.get(k) || { c: 0, sample: '' }
  28. cur.c += 1
  29. if (!cur.sample) cur.sample = String(node.text.style.content || '').slice(0, 14)
  30. textColors.set(k, cur)
  31. }
  32. if (f?.name) sizes.set(`${f.name} ${f.size}px w${f.fontWeight}`, (sizes.get(`${f.name} ${f.size}px w${f.fontWeight}`) || 0) + 1)
  33. }
  34. for (const ch of node.layers || []) walk(ch, p)
  35. })(ab, '')
  36. console.log(`\n########## ${ab.name} ${ab.frame.width}x${ab.frame.height}`)
  37. console.log('--- 填充色 Top 20')
  38. console.log([...fills.entries()].sort((a, b) => b[1].c - a[1].c).slice(0, 20).map(([k, v]) => `${k} ×${v.c} ${v.sample}`).join('\n'))
  39. console.log('--- 文字色 Top 15')
  40. console.log([...textColors.entries()].sort((a, b) => b[1].c - a[1].c).slice(0, 15).map(([k, v]) => `${k} ×${v.c} 例:${v.sample}`).join('\n'))
  41. console.log('--- 字体/字号 Top 15')
  42. console.log([...sizes.entries()].sort((a, b) => b[1] - a[1]).slice(0, 15).map(([k, v]) => `${k} ×${v}`).join('\n'))
  43. }