42 lines
2.5 KiB
TypeScript
42 lines
2.5 KiB
TypeScript
/**
|
||
* 主播头像/封面占位:用 SVG 数据 URL 避免裂图,与主播管理、大屏共用
|
||
*/
|
||
|
||
/** 取名字首字(中文)或前两字符(英文)用于占位图 */
|
||
export function getInitials(name: string): string {
|
||
if (!name || !name.trim()) return "主"
|
||
const s = name.trim()
|
||
if (/[\u4e00-\u9fa5]/.test(s)) return s.slice(0, 1)
|
||
return s.slice(0, 2).toUpperCase()
|
||
}
|
||
|
||
/** 生成头像占位图(方形,带首字),返回 data URL,永不裂图 */
|
||
export function getAvatarPlaceholderUrl(name: string, size = 96): string {
|
||
const text = getInitials(name)
|
||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect width="100%" height="100%" fill="#6366f1"/><text x="50%" y="50%" dominant-baseline="central" text-anchor="middle" fill="white" font-size="${Math.round(size * 0.4)}" font-family="system-ui,sans-serif">${text}</text></svg>`
|
||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||
}
|
||
|
||
/** 生成封面占位图(宽图,带游戏/名称文字) */
|
||
export function getCoverPlaceholderUrl(label: string, width = 400, height = 200): string {
|
||
const text = (label || "电竞").slice(0, 6)
|
||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#1e293b"/><stop offset="100%" style="stop-color:#0f172a"/></linearGradient></defs><rect width="100%" height="100%" fill="url(#g)"/><text x="50%" y="50%" dominant-baseline="central" text-anchor="middle" fill="#94a3b8" font-size="${Math.round(height * 0.2)}" font-family="system-ui,sans-serif">${text}</text></svg>`
|
||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||
}
|
||
|
||
/**
|
||
* 返回用于展示的头像 URL:有有效 avatar 用 avatar,否则用首字占位(不请求外链,不裂图)
|
||
*/
|
||
export function getStreamerAvatarUrl(name: string, avatar?: string | null, size = 96): string {
|
||
if (avatar && typeof avatar === "string" && avatar.trim().length > 0) return avatar.trim()
|
||
return getAvatarPlaceholderUrl(name, size)
|
||
}
|
||
|
||
/**
|
||
* 返回用于展示的封面 URL:有有效 cover 用 cover,否则用占位
|
||
*/
|
||
export function getStreamerCoverUrl(gameOrName: string, cover?: string | null, width = 400, height = 200): string {
|
||
if (cover && typeof cover === "string" && cover.trim().length > 0) return cover.trim()
|
||
return getCoverPlaceholderUrl(gameOrName, width, height)
|
||
}
|