Files
drawlogo/scripts/gen-agent-avatars.js

98 lines
4.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 智能体头像批量生成(DiceBear bottts 机器人风)
* 从资源库 js/data/sources/dicebear-bottts.js 读取风格定义,
* 用确定性 seed 生成 10 套头像 SVG,输出到 output/agent-avatars/,
* 同时生成 preview.html 便于浏览器预览。
*
* 用法:node scripts/gen-agent-avatars.js
*/
'use strict';
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const ROOT = path.resolve(__dirname, '..');
const OUT_DIR = path.join(ROOT, 'output', 'agent-avatars');
// —— 模拟浏览器全局:DiceBear 风格文件写入 window.HGB_Dicebear_* ——
global.window = global;
// 1) 加载 29 种 DiceBear 风格定义中的 bottts(机器人)
const styleFile = path.join(ROOT, 'js', 'data', 'sources', 'dicebear-bottts.js');
const styleSrc = fs.readFileSync(styleFile, 'utf8');
vm.runInThisContext(styleSrc, { filename: styleFile }); // 定义 window.HGB_Dicebear_bottts
// 2) 加载 DiceBear 渲染引擎(const 声明经 vm 进入全局词法绑定,与 scripts/avatar-ai-smoke.js 一致)
const engineSrc = fs.readFileSync(path.join(ROOT, 'js', 'core', 'dicebear.js'), 'utf8');
vm.runInThisContext(engineSrc, { filename: 'js/core/dicebear.js' }); // 定义 HGB_Dicebear
// 3) 从资源库 tabler 源提取「房子属性」图标(smart-home 智能家居)用于叠加徽章
const tablerFile = path.join(ROOT, 'js', 'data', 'sources', 'tabler.js');
vm.runInThisContext(fs.readFileSync(tablerFile, 'utf8'), { filename: 'tabler.js' }); // 定义 window.HGB_Source_tabler
const tablerIcons = window['HGB_Source_tabler'].icons;
const houseIcon = tablerIcons.find(x => x.id === 'tabler:smart-home') || tablerIcons.find(x => x.id === 'tabler:home');
if (!houseIcon) { console.error('❌ 资源库未找到 smart-home/home 图标'); process.exit(1); }
const houseBody = houseIcon.svg; // 形如 <path .../><path .../>(tabler 为 stroke 风格)
// 徽章:圆形底 + 房子图标,右下角 (140,140),整体在 180 viewBox 圆形裁切内
const BADGE_CX = 140, BADGE_CY = 140, BADGE_R = 22, ICON_SIZE = 24, ICON_SCALE = 0.85;
const houseBadge = `<g transform="translate(${BADGE_CX} ${BADGE_CY})"><circle r="${BADGE_R}" fill="#5561d4"/><g transform="translate(${-ICON_SIZE / 2} ${-ICON_SIZE / 2}) scale(${ICON_SCALE})" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${houseBody}</g></g>`;
// 4) 生成 10 套:seed 用固定前缀 + 序号,保证可复现
const COUNT = 10;
const SEED_BASE = 'agent';
const seeds = [];
for (let i = 1; i <= COUNT; i++) seeds.push(SEED_BASE + '-' + i);
const cards = [];
for (let i = 0; i < seeds.length; i++) {
const { svg } = HGB_Dicebear.renderAvatar('bottts', seeds[i]);
// 叠加房子属性徽章(插到 </svg> 前)
const enriched = svg.replace(/<\/svg>$/, houseBadge + '</svg>');
const file = 'agent-' + String(i + 1).padStart(2, '0') + '.svg';
cards.push({ file, seed: seeds[i], svg: enriched });
}
// 4) 写文件
fs.mkdirSync(OUT_DIR, { recursive: true });
for (const c of cards) {
fs.writeFileSync(path.join(OUT_DIR, c.file), c.svg, 'utf8');
console.log('✅ ' + c.file + ' seed=' + c.seed);
}
// 5) 预览页(内联全部 SVG,浏览器直接查看)
const preview = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>智能体头像 · 10 套预览(DiceBear bottts · 房子属性)</title>
<style>
body { font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; background:#0f1115; color:#e8eaed; margin:0; padding:32px; }
h1 { font-size:20px; margin:0 0 4px; }
.sub { color:#9aa0a6; font-size:13px; margin-bottom:24px; }
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); gap:16px; max-width:1000px; }
.card { background:#1b1e26; border:1px solid #2a2f3a; border-radius:12px; padding:16px; text-align:center; }
.card svg { width:96px; height:96px; border-radius:50%; background:#fff; }
.card .name { margin-top:10px; font-size:12px; color:#bdc1c6; }
.card .seed { font-size:11px; color:#80868b; }
a.dl { display:inline-block; margin-top:6px; font-size:11px; color:#8ab4f8; text-decoration:none; }
</style>
</head>
<body>
<h1>🤖 智能体头像 · 10 套(带房子属性)</h1>
<div class="sub">DiceBear bottts(机器人)风格 + 房子属性徽章(资源库 tabler · smart-home)· 确定性 seed 生成</div>
<div class="grid">
${cards.map(c => `<div class="card">
${c.svg}
<div class="name">智能体 ${c.file.replace('.svg', '')}</div>
<div class="seed">seed: ${c.seed}</div>
<a class="dl" href="${c.file}" download>下载 SVG</a>
</div>`).join('\n')}
</div>
</body>
</html>`;
fs.writeFileSync(path.join(OUT_DIR, 'preview.html'), preview, 'utf8');
console.log('\n🎉 已生成 ' + cards.length + ' 套头像 → output/agent-avatars/');
console.log('预览:打开 output/agent-avatars/preview.html');