import { toPng } from "html-to-image";
import { API_URL } from "../consts";
const TRANSPARENT_PIXEL =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIABQAABjE+ibYAAAAASUVORK5CYII=";
export async function fetchAsBase64(url: string): Promise {
const res = await fetch(
`${API_URL}/proxy-image?url=${encodeURIComponent(url)}`,
);
if (!res.ok) throw new Error(`proxy-image failed: ${res.status}`);
const blob = await res.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
/** Inline remote images as data URLs: html-to-image can't read cross-origin
* pixels, so a capture would otherwise come out with blank artwork. */
export async function resolveImages(
urls: (string | undefined | null)[],
): Promise> {
const map: Record = {};
const unique = [
...new Set(
urls.filter((u): u is string => !!u && !u.endsWith("/@jpeg")),
),
];
await Promise.all(
unique.map((url) =>
fetchAsBase64(url)
.then((b64) => {
map[url] = b64;
})
.catch(() => {}),
),
);
return map;
}
export async function downloadNodeAsPng(node: HTMLElement, filename: string) {
await document.fonts.ready;
const dataUrl = await toPng(node, {
cacheBust: true,
pixelRatio: 2,
skipFonts: true,
imagePlaceholder: TRANSPARENT_PIXEL,
});
const link = document.createElement("a");
link.download = filename;
link.href = dataUrl;
link.click();
}