68 lines
1.9 KiB
TypeScript
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),
|
|
});
|
|
}
|