@elara-services/leveling
Version:
A package for XP/Leveling on Discord.
165 lines (164 loc) • 6.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.arcane = void 0;
const tslib_1 = require("tslib");
const utils_1 = require("@elara-services/utils");
const Canvas = tslib_1.__importStar(require("skia-canvas"));
const utils_2 = require("../../utils");
const defs = {
progress: {
first: "#008cff",
second: "#ffffff",
},
username: "#008cff",
background: {
first: "#36393f",
second: "#008cff",
},
};
async function arcane(user, db, rank) {
const { xp, level } = (0, utils_2.getData)(db);
return createArcaneRankProfile({
username: user.username,
level,
rank,
xp: {
current: xp.current,
max: xp.required,
},
avatar: (0, utils_2.getUserAvatar)(user),
background: db.background,
foreground: db.foreground,
colors: {
progress: {
first: utils_2.colors.get(db, "arcane.progress.first", true),
second: utils_2.colors.get(db, "arcane.progress.second"),
},
background: {
first: utils_2.colors.get(db, "arcane.background.first"),
second: utils_2.colors.get(db, "arcane.background.second", true),
},
username: utils_2.colors.get(db, "arcane.username", true),
},
});
}
exports.arcane = arcane;
async function createArcaneRankProfile(user) {
const canvas = new Canvas.Canvas(800, 200);
const ctx = canvas.getContext("2d");
if (user.background) {
await rectangle(ctx, 0, 0, canvas.width, canvas.height, 10, user.background);
}
else {
// Draw the background.
ctx.fillStyle = user.colors?.background?.first || defs.background.first;
await rectangle(ctx, 0, 0, canvas.width, canvas.height, 10, true);
ctx.fillStyle =
user.colors?.background?.second || defs.background.second;
await rectangle(ctx, 700, 0, 100, canvas.height, 10, true);
ctx.save();
ctx.beginPath();
ctx.moveTo(530, 0);
ctx.lineTo(canvas.width - 50, 0);
ctx.lineTo(canvas.width - 50, canvas.height);
ctx.lineTo(680, canvas.height);
ctx.lineTo(530, 0);
ctx.closePath();
ctx.fill();
ctx.restore();
}
// Draw progress bar.
ctx.fillStyle = user.colors?.progress?.second || defs.progress.second;
await rectangle(ctx, 20, 150, 600, 30, 5, true);
ctx.fillStyle = user.colors?.progress?.first || defs.progress.first;
await rectangle(ctx, 20, 150, (user.xp.current * 600) / user.xp.max, 30, 5, true);
// Draw user info.
await rectangle(ctx, 20, 20, 120, 120, 70, user.avatar ||
"https://cdn.discordapp.com/emojis/1081469562106691655.png");
ctx.lineWidth = 7;
ctx.strokeStyle = "#36393f";
ctx.font = "40px Raleway";
// Draw spacer.
ctx.fillStyle = user.colors?.username || defs.username;
await rectangle(ctx, 150, 80, width(user.username), 2, 1, true);
// Write user stats.
ctx.fillStyle = "#fefefe";
ctx.strokeText(user.username, 150, 76);
ctx.fillText(user.username, 150, 76);
ctx.font = "20px Raleway";
ctx.globalAlpha = 0.4;
if (user.background) {
ctx.fillStyle = "#000000";
}
else {
ctx.fillStyle = "#ffffff";
}
await rectangle(ctx, 150, 100, width(`Level ${user.level}`, 10), 25, 5, true);
await rectangle(ctx, width(`Level ${user.level}`, 155, 15), 100, width(`Rank ${user.rank}`, 10), 25, 5, true);
await rectangle(ctx, width(`Level ${user.level}`, `Rank ${user.rank}`, 155, 35), 100, width(`${user.xp.current} / ${user.xp.max} XP`, 10), 25, 5, true);
ctx.globalAlpha = 1;
ctx.fillStyle = "#fefefe";
ctx.fillText(`Level ${user.level}`, 155, 120);
ctx.fillText(`Rank ${user.rank}`, width(`Level ${user.level}`, 155, 20), 120);
ctx.fillText(`${user.xp.current} / ${user.xp.max} XP`, width(`Level ${user.level}`, `Rank ${user.rank}`, 155, 40), 120);
if (user.foreground) {
await rectangle(ctx, 0, 0, canvas.width, canvas.height, 10, user.foreground);
}
function width(...params) {
let width = 0;
for (const param of params) {
width +=
typeof param === "string"
? ctx.measureText(param).width
: param;
}
return width;
}
return {
status: true,
image: await canvas.toBuffer("png"),
};
}
function rectangle(ctx, x, y, width, height, radius, background, stroke) {
return new Promise(async (resolve) => {
const img = typeof background === "string";
if (utils_1.is.undefined(stroke)) {
stroke = false;
}
if (utils_1.is.undefined(radius)) {
radius = 5;
}
radius = utils_1.is.number(radius)
? { tl: radius, tr: radius, br: radius, bl: radius }
: { tl: 0, tr: 0, br: 0, bl: 0 };
if (img) {
ctx.save();
}
ctx.beginPath();
ctx.moveTo(x + radius.tl, y);
ctx.lineTo(x + width - radius.tr, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
ctx.lineTo(x + width, y + height - radius.br);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
ctx.lineTo(x + radius.bl, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
ctx.lineTo(x, y + radius.tl);
ctx.quadraticCurveTo(x, y, x + radius.tl, y);
ctx.closePath();
if (img) {
ctx.clip();
const image = await Canvas.loadImage(background).catch(() => null);
if (image) {
ctx.drawImage(image, x, y, width, height);
}
ctx.restore();
}
else if (!img && background) {
ctx.fill();
}
if (stroke) {
ctx.stroke();
}
resolve(void 0);
});
}