53 lines
1.7 KiB
JavaScript
53 lines
1.7 KiB
JavaScript
/**
|
||
* 🤖 bottts 机器人头像生成共享逻辑(预览页与 PNG 渲染共用,保证 seed 序列一致)
|
||
* - 过滤负面表情变体:eyes.dizzy(眩晕)、mouth.bite(龇牙)
|
||
* - 确定性 seed(agent-N),负面/重复时自动追加后缀重试
|
||
*/
|
||
'use strict';
|
||
|
||
/** 负面变体特征字符串(来自 dicebear-bottts.js 定义,命中即视为负面表情) */
|
||
const NEG_MARKERS = [
|
||
'M30.5 15.3c.4-.4', // eyes.dizzy(眩晕旋转眼)
|
||
'6-8H10z' // mouth.bite(咬合龇牙)
|
||
];
|
||
|
||
function isNegative(svg) {
|
||
return NEG_MARKERS.some(m => svg.includes(m));
|
||
}
|
||
|
||
/**
|
||
* 生成 count 个不重复、非负面表情的头像
|
||
* @param {(seed:string)=>{svg:string}} render 渲染函数(同 seed 同输出)
|
||
* @param {number} count 数量
|
||
* @returns {{seed:string, svg:string}[]}
|
||
*/
|
||
function generateSeeds(render, count) {
|
||
const out = [];
|
||
let n = 1;
|
||
let guard = 0;
|
||
const MAX_GUARD = count * 120 + 5000;
|
||
while (out.length < count) {
|
||
if (++guard > MAX_GUARD) {
|
||
throw new Error(`[bot-common] 生成 ${count} 个唯一头像失败:该风格可能渲染无变化(n=${n}, 已有 ${out.length})`);
|
||
}
|
||
let seed = 'agent-' + n;
|
||
let svg = render(seed).svg;
|
||
if (!svg) { n++; continue; } // 空渲染直接跳过
|
||
let attempt = 0;
|
||
while (isNegative(svg) || out.some(o => o.svg === svg)) {
|
||
attempt++;
|
||
if (attempt > 60) break; // 保护
|
||
seed = 'agent-' + n + '-' + attempt;
|
||
svg = render(seed).svg;
|
||
if (!svg) { n++; break; }
|
||
}
|
||
if (!isNegative(svg) && !out.some(o => o.svg === svg)) {
|
||
out.push({ seed, svg });
|
||
}
|
||
n++;
|
||
}
|
||
return out;
|
||
}
|
||
|
||
module.exports = { generateSeeds, isNegative };
|