1
Fork 0
keyswirl/layout-lens/src/render.ts

125 lines
3.2 KiB
TypeScript
Raw Normal View History

2023-10-22 16:10:53 +02:00
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"),
);
}