102 lines
3.1 KiB
JavaScript
102 lines
3.1 KiB
JavaScript
import {createCanvas, GlobalFonts, loadImage} from "@napi-rs/canvas";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
export class NameCardCreator {
|
|
constructor(templatePath) {
|
|
this.templatePath = templatePath;
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const fullPath = path.join(__dirname, "../../assets/fonts/Fredoka/static/Fredoka-Bold.ttf");
|
|
GlobalFonts.registerFromPath(
|
|
fullPath,
|
|
"Fredoka Bold"
|
|
);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param avatarPath
|
|
* @param name
|
|
* @returns {Promise<Buffer>}
|
|
*/
|
|
async getWelcomeCard(avatarPath, name) {
|
|
let canvas, ctx, smallCanvas, smallCtx;
|
|
try {
|
|
const canvasWidth = 3000;
|
|
const canvasHeight = 1000;
|
|
canvas = createCanvas(canvasWidth, canvasHeight);
|
|
ctx = canvas.getContext("2d");
|
|
|
|
const template = await loadImage(this.templatePath);
|
|
ctx.drawImage(template, 0, 0, canvasWidth, canvasHeight);
|
|
|
|
const avatarSize = 675;
|
|
const avatar = await loadImage(avatarPath);
|
|
const avatarX = 225;
|
|
const avatarY = (canvasHeight - avatarSize) / 2;
|
|
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.arc(
|
|
avatarX + avatarSize / 2,
|
|
avatarY + avatarSize / 2,
|
|
avatarSize / 2,
|
|
0,
|
|
Math.PI * 2,
|
|
true
|
|
);
|
|
ctx.closePath();
|
|
ctx.clip();
|
|
ctx.drawImage(avatar, avatarX, avatarY, avatarSize, avatarSize);
|
|
ctx.restore();
|
|
|
|
ctx.lineWidth = 8;
|
|
ctx.strokeStyle = "#ffffff";
|
|
ctx.beginPath();
|
|
ctx.arc(
|
|
avatarX + avatarSize / 2,
|
|
avatarY + avatarSize / 2,
|
|
avatarSize / 2,
|
|
0,
|
|
Math.PI * 2,
|
|
true
|
|
);
|
|
ctx.stroke();
|
|
|
|
const messageX = avatarX + 1525;
|
|
const messageY = (canvasHeight / 2) + 75;
|
|
ctx.fillStyle = "#ede6e6";
|
|
ctx.textAlign = "center";
|
|
ctx.textBaseline = "middle";
|
|
ctx.font = '115px "Fredoka Bold"';
|
|
|
|
const lines = [`Welcome ${name}, to the`, "Spicy Jail ~"];
|
|
const lineHeight = 130;
|
|
const startY = messageY - ((lines.length - 1) / 2) * lineHeight;
|
|
|
|
lines.forEach((line, i) => {
|
|
ctx.fillText(line, messageX, startY + i * lineHeight);
|
|
});
|
|
|
|
smallCanvas = createCanvas(1500, 500);
|
|
smallCtx = smallCanvas.getContext("2d");
|
|
smallCtx.drawImage(canvas, 0, 0, 1500, 500);
|
|
|
|
return smallCanvas.toBuffer("image/png");
|
|
} catch (err) {
|
|
console.error("Error creating name card:", err);
|
|
throw err;
|
|
} finally {
|
|
canvas.width = 0;
|
|
canvas.height = 0;
|
|
smallCanvas.width = 0;
|
|
smallCanvas.height = 0;
|
|
|
|
canvas = null;
|
|
smallCanvas = null;
|
|
ctx = null;
|
|
smallCtx = null;
|
|
}
|
|
}
|
|
}
|