import { tag, px } from "./svg"; import { KeyboardKey, KeySymbol, Layout, LayoutColorscheme, SpecialSymbols, VisualKey, } from "./types"; function textContents(input: KeySymbol): string { if (input === SpecialSymbols.TL || input === SpecialSymbols.TR) return "■"; return input; } function renderKey( visual: VisualKey, key: KeyboardKey, colorscheme: LayoutColorscheme, keySize: number, ) { const centerX = visual.position[0] + visual.size[0] / 2; const centerY = visual.position[1] + visual.size[1] / 2; const textAttribs = { "text-anchor": "middle", "dominant-baseline": "middle", "font-family": "Helvetica", }; const textColor = (input: KeySymbol, _default: string): string => { if (input === SpecialSymbols.TL) return colorscheme.tlLayerColor; if (input === SpecialSymbols.TR) return colorscheme.trLayerColor; return _default; }; return tag( "g", { transform: visual.angle && visual.angle !== 0 ? `rotate(${visual.angle}, ${centerX}, ${centerY})` : undefined, }, [ tag("rect", { width: px(visual.size[0]), height: px(visual.size[1]), x: visual.position[0], y: visual.position[1], fill: colorscheme.keyFill, stroke: colorscheme.keyStroke, "stroke-width": px(2), }), tag( "text", { x: centerX, y: centerY, textLength: px(keySize / 2), fill: textColor(key.main, colorscheme.mainLayerColor), ...textAttribs, }, textContents(key.main), ), tag( "text", { x: visual.position[0] + visual.size[0] / 6, y: visual.position[1] + visual.size[1] / 6, fill: textColor(key.tlLayer, colorscheme.tlLayerColor), "font-size": "66%", ...textAttribs, }, textContents(key.tlLayer), ), tag( "text", { x: visual.position[0] + (9 * visual.size[0]) / 10, y: visual.position[1] + visual.size[1] / 6, fill: textColor(key.trLayer, colorscheme.trLayerColor), "font-size": "66%", ...textAttribs, "text-anchor": "end", }, textContents(key.trLayer), ), tag( "text", { x: visual.position[0] + visual.size[0] / 10, y: visual.position[1] + (5 * visual.size[1]) / 6, fill: textColor(key.blLayer, colorscheme.blLayerColor), "font-size": "66%", ...textAttribs, "text-anchor": "start", }, textContents(key.blLayer), ), ].join("\n"), ); } export function renderLayout(layout: Layout) { return tag( "svg", { viewBox: [ -layout.imagePadding, -layout.imagePadding, 2 * layout.imagePadding + layout.size[0], 2 * layout.imagePadding + layout.size[1], ].join(" "), xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", }, layout.visual .map((key, index) => renderKey(key, layout.keys[index], layout.colorscheme, layout.keySize), ) .join("\n"), ); }