~james/core

core/avatar/src/gradient.js -rw-r--r-- 1.1 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 14 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { gradientFor, hashString } from "../../web/src/lib/avatarGradient.ts";

/**
 * Render an actor's placeholder as a self-contained SVG string.
 */
export const gradientSvg = (actor, size = 128) => {
  const { angle, stops, glow } = gradientFor(actor);
  const id = hashString(actor).toString(36);
  const stopMarkup = stops
    .map((s) => `<stop offset="${s.offset}%" stop-color="${s.color}"/>`)
    .join("");

  return (
    `<svg width="${size}" height="${size}" viewBox="0 0 100 100" ` +
    `preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">` +
    `<defs>` +
    `<linearGradient id="g${id}" x1="0" y1="0" x2="1" y2="1" ` +
    `gradientTransform="rotate(${angle} 0.5 0.5)">${stopMarkup}</linearGradient>` +
    `<radialGradient id="l${id}" cx="${glow.x}" cy="${glow.y}" r="${glow.r}">` +
    `<stop offset="0%" stop-color="${glow.color}" stop-opacity="${glow.opacity}"/>` +
    `<stop offset="100%" stop-color="${glow.color}" stop-opacity="0"/>` +
    `</radialGradient>` +
    `</defs>` +
    `<rect width="100" height="100" fill="url(#g${id})"/>` +
    `<rect width="100" height="100" fill="url(#l${id})"/>` +
    `</svg>`
  );
};