/** * Draws each favicon face as an SVG. This is the source artwork the served * PNGs are rendered from, and the artwork the parity tests check those PNGs * against; what the dashboard serves is the generated raster, never this. */ import type { FaviconFace } from "./favicon-types.ts"; import { STATUS_COLOR } from "./palette.ts"; const FAVICON_COLORS: Record = { good: STATUS_COLOR.good, warn: STATUS_COLOR.warn, bad: STATUS_COLOR.bad, "bad-crying": STATUS_COLOR.bad, }; const OCTAGON = ``; const FAVICON_SHAPES: Record = { good: ``, warn: ``, bad: OCTAGON, "bad-crying": OCTAGON, }; const FAVICON_EYES: Record = { good: [12, 20], warn: [13, 19], bad: [12, 20], "bad-crying": [12, 20], }; // Downward shift of the eyes, mouth, and any extra features, in canvas units. // The warning face drops by ten percent of the 32-unit canvas height, which // puts its features in the wide part of the triangle rather than near the apex. const FAVICON_FACE_DROPS: Record = { good: 0, warn: 3.2, bad: 0, "bad-crying": 0, }; const SMILE = "M11 19c2.8 2.6 7.2 2.6 10 0"; const FAVICON_MOUTHS: Record = { good: SMILE, warn: "M11 20h10", bad: "M11 21c2.8-2.6 7.2-2.6 10 0", "bad-crying": "M10.5 22c3-4 8-4 11 0", }; const FAVICON_DETAILS: Record = { good: "", warn: "", bad: "", "bad-crying": ` `, }; export function faviconSvg(status: FaviconFace): string { const color = FAVICON_COLORS[status]; const shape = FAVICON_SHAPES[status]; const [leftEye, rightEye] = FAVICON_EYES[status]; const mouth = FAVICON_MOUTHS[status]; const details = FAVICON_DETAILS[status]; const drop = FAVICON_FACE_DROPS[status]; const shift = drop === 0 ? "" : ` transform="translate(0 ${drop})"`; return ` ${shape} ${details} `; }