Files
buzz-sheet/lib/image-export/render.ts
T

68 lines
1.9 KiB
TypeScript

import { fromJsx } from "takumi-js/helpers/jsx";
import type { Renderer } from "takumi-js/wasm/no-init";
import type { ExportRequest } from "./types";
import { exportTemplate } from "./templates";
import { exportStyles } from "./styles";
import { loadImageSources } from "./assets";
const stylesheets = new Map<string, Promise<string>>();
function stylesheet(origin: string) {
let css = stylesheets.get(origin);
if (!css) {
css = fetch(new URL("/takumi.css", origin), {
signal: AbortSignal.timeout(15000),
})
.then((response) => {
if (!response.ok) throw new Error("Unable to load export styles");
return response.text();
})
.catch((error) => {
stylesheets.delete(origin);
throw error;
});
stylesheets.set(origin, css);
}
return css;
}
export async function renderExport(
renderer: Renderer,
request: ExportRequest,
origin: string,
) {
const { node, css } = await fromJsx(exportTemplate(request), {
defaultStyles: {
div: { display: "block" },
section: { display: "block" },
header: { display: "block" },
h1: { display: "block" },
h2: { display: "block" },
p: { display: "block" },
img: { display: "block" },
},
});
const images = await loadImageSources(node, origin);
const options = {
width: request.width,
height: request.height,
format: request.format,
fontFamilies: [
"Anuphan",
"Kanit Overview",
"Kanit Poster",
"Genshin Overview",
],
css: [
await stylesheet(origin),
...css,
".export-root{font-family:Anuphan;font-size:16px;line-height:1.5;background:var(--background);color:var(--foreground)}",
exportStyles(request),
],
images,
};
const measured = await renderer.measure(node, options);
return renderer.render(node, {
...options,
height: request.height ?? Math.ceil(measured.height),
});
}