104 lines
No EOL
2.9 KiB
JavaScript
104 lines
No EOL
2.9 KiB
JavaScript
// shamelessly stolen from tobleronecord
|
|
|
|
const { createCanvas, loadImage } = require("canvas");
|
|
|
|
function canvasToBuffer(canvas) {
|
|
return new Promise(resolve => {
|
|
canvas.toBuffer((err, buffer) => {
|
|
if (!err) {
|
|
resolve(buffer);
|
|
} else {
|
|
throw new Error(err);
|
|
}
|
|
}, "image/png");
|
|
});
|
|
}
|
|
|
|
function wrapText(context, text, x, y, maxWidth, lineHeight, preparingSentence, lines) {
|
|
const words = text.split(" ");
|
|
for (let i = 0; i < words.length; i++) {
|
|
const workSentence = preparingSentence.join(" ") + " " + words[i];
|
|
|
|
if (context.measureText(workSentence).width > maxWidth) {
|
|
lines.push(preparingSentence.join(" "));
|
|
preparingSentence = [words[i]];
|
|
} else {
|
|
preparingSentence.push(words[i]);
|
|
}
|
|
}
|
|
|
|
lines.push(preparingSentence.join(" "));
|
|
|
|
lines.forEach(element => {
|
|
const lineWidth = context.measureText(element).width;
|
|
const xOffset = (maxWidth - lineWidth) / 2;
|
|
|
|
y += lineHeight;
|
|
context.fillText(element, x + xOffset, y);
|
|
});
|
|
}
|
|
|
|
function fixUpQuote(quote, userStore) {
|
|
const emojiRegex = /<a?:(\w+):(\d+)>/g;
|
|
quote = quote.replace(emojiRegex, "");
|
|
|
|
const mentionRegex = /<@(.*)>/;
|
|
let result = quote;
|
|
|
|
mentionRegex.exec(quote)?.forEach(match => {
|
|
result = result.replace(match, `@${userStore.get(match.replace("<@", "").replace(">", "")).username}`);
|
|
})
|
|
|
|
return result;
|
|
}
|
|
|
|
var preparingSentence = [];
|
|
const lines = [];
|
|
|
|
module.exports = {
|
|
async createQuoteImage(avatarUrl, name, quoteOld, grayScale, userStore) {
|
|
const quote = fixUpQuote(quoteOld, userStore);
|
|
|
|
const cardWidth = 1200;
|
|
const cardHeight = 600;
|
|
|
|
const canvas = createCanvas(cardWidth, cardHeight);
|
|
const ctx = canvas.getContext("2d");
|
|
|
|
ctx.fillStyle = "#000";
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
const avatar = await loadImage(avatarUrl);
|
|
const fade = await loadImage("https://files.catbox.moe/54e96l.png");
|
|
|
|
ctx.drawImage(avatar, 0, 0, cardHeight, cardHeight);
|
|
|
|
if (grayScale) {
|
|
ctx.globalCompositeOperation = "saturation";
|
|
ctx.fillStyle = "#fff";
|
|
ctx.fillRect(0, 0, cardWidth, cardHeight);
|
|
ctx.globalCompositeOperation = "source-over";
|
|
}
|
|
|
|
ctx.drawImage(fade, cardHeight - 400, 0, 400, cardHeight);
|
|
|
|
ctx.fillStyle = "#fff";
|
|
ctx.font = "italic 20px Georgia";
|
|
const quoteWidth = cardWidth / 2 - 50;
|
|
const quoteX = ((cardWidth - cardHeight));
|
|
const quoteY = cardHeight / 2 - 10;
|
|
wrapText(ctx, `"${quote}"`, quoteX, quoteY, quoteWidth, 20, preparingSentence, lines);
|
|
|
|
const wrappedTextHeight = lines.length * 25;
|
|
|
|
ctx.font = "bold 16px Georgia";
|
|
const authorNameX = (cardHeight * 1.5) - (ctx.measureText(`- ${name}`).width / 2) - 30;
|
|
const authorNameY = quoteY + wrappedTextHeight + 30;
|
|
|
|
ctx.fillText(`- ${name}`, authorNameX, authorNameY);
|
|
preparingSentence.length = 0;
|
|
lines.length = 0;
|
|
|
|
return await canvasToBuffer(canvas);
|
|
}
|
|
} |