You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
29 lines
942 B
TypeScript
29 lines
942 B
TypeScript
/** Deterministic identity visuals: initials + a stable hue from the name. */
|
|
|
|
export function initials(name: string): string {
|
|
const words = name.trim().split(/\s+/).filter((w) => w !== '')
|
|
if (words.length === 0) return '?'
|
|
const first = words[0]!.charAt(0)
|
|
const second = words.length > 1 ? words[1]!.charAt(0) : ''
|
|
return (first + second).toUpperCase()
|
|
}
|
|
|
|
/** FNV-1a over the name → hue bucket; same name always gets the same colour. */
|
|
export function avatarHue(name: string): number {
|
|
let h = 0x811c9dc5
|
|
for (let i = 0; i < name.length; i++) {
|
|
h ^= name.charCodeAt(i)
|
|
h = Math.imul(h, 0x01000193)
|
|
}
|
|
return (h >>> 0) % 360
|
|
}
|
|
|
|
/** Soft tinted background + readable foreground for both themes. */
|
|
export function avatarColors(name: string): { bg: string; fg: string } {
|
|
const h = avatarHue(name)
|
|
return {
|
|
bg: `hsl(${h} 42% 50% / 0.16)`,
|
|
fg: `light-dark(hsl(${h} 45% 34%), hsl(${h} 45% 74%))`,
|
|
}
|
|
}
|