refactor(renderer): create canvas in renderer

This commit is contained in:
Pihkaal
2024-10-12 18:44:12 +02:00
parent d0855dde8c
commit 43ecff853e
3 changed files with 35 additions and 36 deletions

View File

@@ -2,7 +2,6 @@
import { renderQRCodeToCanvas } from "@/utils/renderer"; import { renderQRCodeToCanvas } from "@/utils/renderer";
import { IMAGE_FORMATS, LOGOS } from "@/utils/settings"; import { IMAGE_FORMATS, LOGOS } from "@/utils/settings";
const canvas = ref(null);
const form = ref(null); const form = ref(null);
const qrCode = ref(undefined); const qrCode = ref(undefined);
@@ -49,9 +48,9 @@ const updateQRCode = async () => {
if (!isValidState.value) return; if (!isValidState.value) return;
const logoUrl = state.hasLogo ? `/logos/${state.logo}.png` : undefined; const logoUrl = state.hasLogo ? `/logos/${state.logo}.png` : undefined;
await renderQRCodeToCanvas(canvas.value, state.content, logoUrl); const canvas = await renderQRCodeToCanvas(state.content, logoUrl);
qrCode.value = canvas.value.toDataURL(`image/${state.format}`); qrCode.value = canvas.toDataURL(`image/${state.format}`);
}; };
const copyUrl = async () => { const copyUrl = async () => {
@@ -106,7 +105,6 @@ const arrayToUnion = (array: string[]) =>
<template> <template>
<div role="main" class="flex h-[100vh] items-center justify-center"> <div role="main" class="flex h-[100vh] items-center justify-center">
<NuxtRouteAnnouncer /> <NuxtRouteAnnouncer />
<canvas ref="canvas" class="hidden" />
<div <div
class="p-5 w-full max-w-[850px] flex flex-col justify-center space-y-4" class="p-5 w-full max-w-[850px] flex flex-col justify-center space-y-4"

View File

@@ -1,7 +1,6 @@
import { createCanvas } from "canvas";
import { resolve } from "path"; import { resolve } from "path";
import sharp from "sharp"; import sharp from "sharp";
import { CANVAS_SIZE, renderQRCodeToCanvas } from "~/utils/renderer"; import { renderQRCodeToCanvas } from "~/utils/renderer";
import { settingsSchema } from "~/utils/settings"; import { settingsSchema } from "~/utils/settings";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
@@ -21,9 +20,8 @@ export default defineEventHandler(async (event) => {
const { format, logo, content } = parsed.data; const { format, logo, content } = parsed.data;
const canvas = createCanvas(CANVAS_SIZE, CANVAS_SIZE);
const logoUrl = logo ? resolve("public", `logos/${logo}.png`) : undefined; const logoUrl = logo ? resolve("public", `logos/${logo}.png`) : undefined;
await renderQRCodeToCanvas(canvas, content, logoUrl); const canvas = await renderQRCodeToCanvas(content, logoUrl);
let image = canvas.toBuffer(); let image = canvas.toBuffer();
if (format !== "png") { if (format !== "png") {

View File

@@ -1,21 +1,23 @@
import { loadImage, type Canvas, type CanvasRenderingContext2D } from "canvas"; import { createCanvas, loadImage } from "canvas";
import QRCode from "qrcode"; import QRCode from "qrcode";
export const CANVAS_SIZE = 1000; const CANVAS_SIZE = 1000;
export const LOGO_PADDING = 1; const LOGO_PADDING = 1;
export const renderQRCodeToCanvas = async ( export const renderQRCodeToCanvas = async (
canvas: HTMLCanvasElement | Canvas,
content: string, content: string,
logoUrl: string | undefined, logoUrl: string | undefined,
) => { ) => {
const canvas = createCanvas(CANVAS_SIZE, CANVAS_SIZE);
await QRCode.toCanvas(canvas, content, { await QRCode.toCanvas(canvas, content, {
errorCorrectionLevel: "H", errorCorrectionLevel: "H",
width: CANVAS_SIZE, width: CANVAS_SIZE,
margin: 1, margin: 1,
}); });
if (logoUrl) { if (!logoUrl) return canvas;
const qrCode = QRCode.create(content, { errorCorrectionLevel: "H" }); const qrCode = QRCode.create(content, { errorCorrectionLevel: "H" });
const moduleCount = qrCode.modules.size + 2; const moduleCount = qrCode.modules.size + 2;
@@ -34,7 +36,7 @@ export const renderQRCodeToCanvas = async (
const logoSize = backgroundSize - LOGO_PADDING * 2; const logoSize = backgroundSize - LOGO_PADDING * 2;
const logoPosition = backgroundPosition + LOGO_PADDING; const logoPosition = backgroundPosition + LOGO_PADDING;
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; const ctx = canvas.getContext("2d");
ctx.fillStyle = "white"; ctx.fillStyle = "white";
ctx.fillRect( ctx.fillRect(
backgroundPosition, backgroundPosition,
@@ -43,5 +45,6 @@ export const renderQRCodeToCanvas = async (
backgroundSize, backgroundSize,
); );
ctx.drawImage(logoImage, logoPosition, logoPosition, logoSize, logoSize); ctx.drawImage(logoImage, logoPosition, logoPosition, logoSize, logoSize);
}
return canvas;
}; };