| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // 票 15 取证(七):等级标签 / chip / 标题 / KPI 的精确配色与字号
- import { readFileSync } from 'node:fs'
- const dir = '.scratch/lanhu-cockpit-asset-replacement/research/raw-v2'
- const boards = [2, 3, 4, 5, 6, 7, 8, 9, 10]
- const hex = (c) => `#${[c.r, c.g, c.b].map((v) => Math.round(v * 255).toString(16).padStart(2, '0')).join('')}`
- const alpha = (c) => (c.a === undefined || c.a > 0.999 ? '' : `@${c.a.toFixed(2)}`)
- const load = (n) => JSON.parse(readFileSync(`${dir}/desktop-${String(n).padStart(2, '0')}.json`, 'utf8')).artboard
- function textOf(node) {
- return node.type === 'textLayer' && node.text?.style?.content ? String(node.text.style.content) : ''
- }
- // 1) 等级标签:文字命中 N级
- console.log('=== 等级标签(N级 / N 级)')
- const levels = new Map()
- for (const n of boards) {
- ;(function walk(node) {
- const t = textOf(node).trim()
- if (/^[1-4]\s*级$/.test(t)) {
- const f = node.text.style.font
- const c = node.text.style.color
- const k = `${t} → ${c ? hex(c) + alpha(c) : '-'} ${f.size}px ${f.name} w${f.fontWeight}`
- levels.set(k, (levels.get(k) || 0) + 1)
- }
- for (const ch of node.layers || []) walk(ch)
- })(load(n))
- }
- console.log([...levels.entries()].sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k} ×${v}`).join('\n') || '(无)')
- // 2) chip 文字:父节点名含 Chip 的文字
- console.log('\n=== Chip 内文字')
- const chips = new Map()
- for (const n of boards) {
- ;(function walk(node, inChip) {
- const here = inChip || /Chip/i.test(node.name)
- const t = textOf(node).trim()
- if (here && t) {
- const f = node.text.style.font
- const c = node.text.style.color
- const k = `"${t}" → ${c ? hex(c) + alpha(c) : '-'} ${f.size}px ${f.name}`
- chips.set(k, (chips.get(k) || 0) + 1)
- }
- for (const ch of node.layers || []) walk(ch, here)
- })(load(n), false)
- }
- console.log([...chips.entries()].sort((a, b) => b[1] - a[1]).slice(0, 30).map(([k, v]) => `${k} ×${v}`).join('\n') || '(无)')
- // 3) 面板标题:父节点名含 Heading 的文字
- console.log('\n=== 面板标题(Heading 内文字)')
- const heads = new Map()
- for (const n of boards) {
- ;(function walk(node, inHead) {
- const here = inHead || /Heading/i.test(node.name)
- const t = textOf(node).trim()
- if (here && t) {
- const f = node.text.style.font
- const c = node.text.style.color
- const k = `"${t}" → ${c ? hex(c) + alpha(c) : '-'} ${f.size}px ${f.name} w${f.fontWeight}`
- heads.set(k, (heads.get(k) || 0) + 1)
- }
- for (const ch of node.layers || []) walk(ch, here)
- })(load(n), false)
- }
- console.log([...heads.entries()].sort((a, b) => b[1] - a[1]).slice(0, 30).map(([k, v]) => `${k} ×${v}`).join('\n') || '(无)')
- // 4) KPI:父节点名含 Bold Text / KPI 的文字
- console.log('\n=== KPI 数值(Bold Text 内文字)')
- const kpis = new Map()
- for (const n of boards) {
- ;(function walk(node, inKpi) {
- const here = inKpi || /Bold Text|KPI/i.test(node.name)
- const t = textOf(node).trim()
- if (here && t) {
- const f = node.text.style.font
- const c = node.text.style.color
- const k = `"${t}" → ${c ? hex(c) + alpha(c) : '-'} ${f.size}px ${f.name} w${f.fontWeight}`
- kpis.set(k, (kpis.get(k) || 0) + 1)
- }
- for (const ch of node.layers || []) walk(ch, here)
- })(load(n), false)
- }
- console.log([...kpis.entries()].sort((a, b) => b[1] - a[1]).slice(0, 25).map(([k, v]) => `${k} ×${v}`).join('\n') || '(无)')
- // 5) 一级模式标签(nav 内文字)
- console.log('\n=== 一级模式标签(nav 内文字)')
- const navs = new Map()
- for (const n of boards) {
- ;(function walk(node, inNav) {
- const here = inNav || /^nav$/i.test(node.name)
- const t = textOf(node).trim()
- if (here && t) {
- const f = node.text.style.font
- const c = node.text.style.color
- const k = `"${t}" → ${c ? hex(c) + alpha(c) : '-'} ${f.size}px ${f.name} w${f.fontWeight}`
- navs.set(k, (navs.get(k) || 0) + 1)
- }
- for (const ch of node.layers || []) walk(ch, here)
- })(load(n), false)
- }
- console.log([...navs.entries()].sort((a, b) => b[1] - a[1]).slice(0, 20).map(([k, v]) => `${k} ×${v}`).join('\n') || '(无)')
|