feat: integrate html-to-image library for enhanced image generation and QR code rendering
This commit is contained in:
@@ -7,11 +7,38 @@ import LinkedingBlueD from "@/components/icons/LinkedingBlueD";
|
||||
|
||||
// Packages
|
||||
import { useState } from "react";
|
||||
import { toPng } from "html-to-image";
|
||||
import html2canvas from "html2canvas";
|
||||
import jsPDF from "jspdf";
|
||||
import { Button } from "@mui/material";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
const VAZIR_WEIGHTS = [
|
||||
[400, "Vazirmatn-RD-FD-Regular.ttf"],
|
||||
[500, "Vazirmatn-RD-FD-Medium.ttf"],
|
||||
[600, "Vazirmatn-RD-FD-SemiBold.ttf"],
|
||||
[700, "Vazirmatn-RD-FD-Bold.ttf"],
|
||||
[800, "Vazirmatn-RD-FD-ExtraBold.ttf"],
|
||||
];
|
||||
|
||||
let vazirEmbedCssPromise;
|
||||
const getVazirEmbedCss = () => {
|
||||
vazirEmbedCssPromise ??= Promise.all(
|
||||
VAZIR_WEIGHTS.map(async ([weight, file]) => {
|
||||
const res = await fetch(`/fonts/vazir/${file}`);
|
||||
const blob = await res.blob();
|
||||
const dataUrl = await new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
return `@font-face{font-family:vazir;src:url(${dataUrl});font-weight:${weight};}`;
|
||||
})
|
||||
).then((faces) => faces.join("\n"));
|
||||
return vazirEmbedCssPromise;
|
||||
};
|
||||
|
||||
const waitForImages = async (element) => {
|
||||
const imgs = Array.from(element.querySelectorAll("img"));
|
||||
await Promise.all(
|
||||
@@ -43,18 +70,35 @@ function List({ hiddenRef, data, qrReady }) {
|
||||
try {
|
||||
await waitForImages(element);
|
||||
|
||||
const canvas = await html2canvas(element, {
|
||||
backgroundColor: "#ffffff",
|
||||
useCORS: true,
|
||||
scale: 2,
|
||||
imageTimeout: 15000,
|
||||
});
|
||||
let imgData;
|
||||
let pxWidth;
|
||||
let pxHeight;
|
||||
|
||||
const imgData = canvas.toDataURL("image/png");
|
||||
try {
|
||||
const fontEmbedCSS = await getVazirEmbedCss();
|
||||
imgData = await toPng(element, {
|
||||
pixelRatio: 2,
|
||||
backgroundColor: "#ffffff",
|
||||
style: { opacity: "1" },
|
||||
fontEmbedCSS,
|
||||
});
|
||||
pxWidth = element.offsetWidth * 2;
|
||||
pxHeight = element.offsetHeight * 2;
|
||||
} catch {
|
||||
const canvas = await html2canvas(element, {
|
||||
backgroundColor: "#ffffff",
|
||||
useCORS: true,
|
||||
scale: 2,
|
||||
imageTimeout: 15000,
|
||||
});
|
||||
imgData = canvas.toDataURL("image/png");
|
||||
pxWidth = canvas.width;
|
||||
pxHeight = canvas.height;
|
||||
}
|
||||
|
||||
const imgWidth = 210;
|
||||
const pxPerMm = canvas.width / imgWidth;
|
||||
const imgHeight = canvas.height / pxPerMm;
|
||||
const pxPerMm = pxWidth / imgWidth;
|
||||
const imgHeight = pxHeight / pxPerMm;
|
||||
|
||||
const pdf = new jsPDF({
|
||||
orientation: "portrait",
|
||||
|
||||
Reference in New Issue
Block a user