forked from
tangled.org/core
Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
1import type { VNode } from "preact";
2import { initSatori, initResvg, loadFonts } from "@tangled/ogre-runtime";
3import type { ResvgClass } from "@tangled/ogre-runtime/types";
4
5let satoriFn: typeof import("satori").default | null = null;
6let Resvg: ResvgClass | null = null;
7let fontsLoaded = false;
8let cachedFonts: Awaited<ReturnType<typeof loadFonts>> | null = null;
9
10export interface RenderResult {
11 svg: string;
12 png: Uint8Array;
13}
14
15export async function renderCard(component: VNode): Promise<RenderResult> {
16 if (!satoriFn) {
17 satoriFn = await initSatori();
18 }
19
20 if (!Resvg) {
21 Resvg = await initResvg();
22 }
23
24 if (!fontsLoaded) {
25 cachedFonts = await loadFonts();
26 fontsLoaded = true;
27 }
28
29 const svg = await satoriFn(component as any, {
30 width: 1200,
31 height: 630,
32 fonts: cachedFonts!,
33 embedFont: true,
34 });
35
36 const resvg = new Resvg!(svg, {
37 fitTo: { mode: "width", value: 1200 },
38 });
39
40 const pngData = resvg.render();
41
42 return {
43 svg,
44 png: pngData.asPng(),
45 };
46}