discord-canvas-easy
Version:
Simple canvas with discord-canvas-easy
223 lines (171 loc) • 10.9 kB
JavaScript
const Canvas = require("canvas")
const Discord = require("discord.js")
const calculXp = require("../Functions/calculXp")
module.exports = class Leaderboard {
constructor() {
this.bot = null;
this.guild = null;
this.background = null;
this.colorFont = null;
this.users = [];
}
/**
* @param {Discord.Client} value
*/
setBot(value) {
this.bot = value;
return this;
}
/**
* @param {Discord.Guild} value
*/
setGuild(value) {
this.guild = value;
return this;
}
/**
* @param {string} value
*/
setBackground(value) {
this.background = value;
return this;
}
/**
* @param {string} value
*/
setColorFont(value) {
this.colorFont = value;
return this;
}
/**
* @param {Discord.User} user
* @param {number} level
* @param {number} xp
* @param {number} need
*/
addUser(user, level, xp, need) {
this.users.push({user, level, xp, need})
return this;
}
async toLeaderboard() {
let count = this.users.length;
if(this.bot === null || this.bot.token === undefined || this.bot.token === null || typeof this.bot !== "object") throw new Error("The .setBot must be a Discord Client !")
if(this.guild === null || this.guild.id === undefined || this.guild.id === null || typeof this.guild !== "object") throw new Error("The .setGuild must be a Discord Guild !")
if(this.background === null || typeof this.background !== "string") throw new Error("The .setBackground must be a string !")
if(count <= 0) throw new Error("The number of users must be greater than 1 !")
if(count > 10) throw new Error("The number of users must be less than 10 !")
if(this.colorFont === null || !this.colorFont.match(new RegExp(/^#[0-9a-f]{6}/i))) this.colorFont = "#ffffff";
for(let i = 0; i < count; i++) {
if(this.users[i].user === null || this.users[i].user.id === undefined || this.users[i].user.id === null || typeof this.users[i].user !== "object") throw new Error("The user of the .addUser must be a Discord User !")
if(this.users[i].level === null || typeof this.users[i].level !== "number") throw new Error("The level of the .addUser must be a number !")
if(this.users[i].xp === null || typeof this.users[i].xp !== "number") throw new Error("The xp of the .addUser must be a number !")
if(this.users[i].need === null || typeof this.users[i].need !== "number") throw new Error("The need of the .addUser must be a number !")
}
const leaderboard = this.users.sort(async (a, b) => (await calculXp(b.xp, b.level)) - (await calculXp(a.xp, a.level)))
const canvas = Canvas.createCanvas(1280, 700);
const ctx = canvas.getContext("2d");
const background = await Canvas.loadImage(this.background)
ctx.drawImage(background, 0, 0, canvas.width, canvas.height)
const opacity = await Canvas.loadImage(`${__dirname}/../Assets/leaderboard_black.png`)
ctx.drawImage(opacity, 0, 0, canvas.width, canvas.height)
if(count <= 5) {
for(let i = 0; i < count; i++) {
const member = this.guild.members.cache.get(leaderboard[i].user.id)
const status = member ? member.presence ? member.presence.status : "offline" : "offline";
ctx.beginPath();
ctx.arc(104, (74 + (i * 128)), 47, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.fillStyle = status === "online" ? "#3ba55c" : status === "dnd" ? "#ed4245" : status === "stream" ? "#593695" : status === "idle" ? "#faa61a" : status === "offline" ? "#747f8d" : ""
ctx.fill();
ctx.font = '12px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`, (104 - (ctx.measureText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`).width / 2)), (135 + (i * 128)));
ctx.font = '28px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`Rang : ${i + 1 === 1 ? "1er" : `${i + 1}ème`}`, 200, (65 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Level : ${leaderboard[i].level}`, 200, (95 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Expérience : ${leaderboard[i].xp} / ${leaderboard[i].need}`, 200, (125 + ((i <= 4 ? i : i - 5) * 128)));
}
ctx.beginPath();
for(let i = 0; i < count; i++) {
ctx.arc(104, (74 + ((i) * 128)), 42.5, 0, Math.PI * 2, true);
}
ctx.closePath();
ctx.clip();
for(let i = 0; i < count; i++) {
const user = await this.bot.users.fetch(leaderboard[i].user.id);
const member = this.guild.members.cache.get(leaderboard[i].user.id)
if(user) {
const avatar = await Canvas.loadImage(member ? member.avatar ? member.avatarURL({extension: "jpg"}) : user.displayAvatarURL({ extension: "jpg" }) : user.displayAvatarURL({ extension: "jpg" }))
ctx.drawImage(avatar, 62, (32 + (i * 128)), 85, 85);
}
}
} else {
for(let i = 0; i < count; i++) {
if(i <= 4) {
const member = this.guild.members.cache.get(leaderboard[i].user.id)
const status = member ? member.presence ? member.presence.status : "offline" : "offline";
ctx.beginPath();
ctx.arc(104, (84 + (i <= 4 ? i : i - 5) * 128), 47, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.fillStyle = status === "online" ? "#3ba55c" : status === "dnd" ? "#ed4245" : status === "stream" ? "#593695" : status === "idle" ? "#faa61a" : status === "offline" ? "#747f8d" : ""
ctx.fill();
ctx.font = '12px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`, (104 - (ctx.measureText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`).width / 2)), (145 + ((i <= 4 ? i : i - 5) * 128)));
ctx.font = '28px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`Rang : ${i + 1 === 1 ? "1er" : `${i + 1}ème`}`, 200, (65 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Level : ${leaderboard[i].level}`, 200, (95 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Expérience : ${leaderboard[i].xp} / ${leaderboard[i].need}`, 200, (125 + ((i <= 4 ? i : i - 5) * 128)));
} else {
const member = this.guild.members.cache.get(leaderboard[i].user.id)
const status = member ? member.presence ? member.presence.status : "offline" : "offline";
ctx.beginPath();
ctx.arc(744, ((84 + (i <= 4 ? i : i - 5) * 128)), 47, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.fillStyle = status === "online" ? "#3ba55c" : status === "dnd" ? "#ed4245" : status === "stream" ? "#593695" : status === "idle" ? "#faa61a" : status === "offline" ? "#747f8d" : ""
ctx.fill();
ctx.font = '12px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`, (744 - (ctx.measureText(`${leaderboard[i].user.tag.length > 20 ? leaderboard[i].user.tag.slice(0, 20) : leaderboard[i].user.tag}`).width / 2)), (145 + ((i <= 4 ? i : i - 5) * 128)));
ctx.font = '28px "Futura Book"';
ctx.fillStyle = this.colorFont;
ctx.fillText(`Rang : ${i + 1 === 1 ? "1er" : `${i + 1}ème`}`, 840, (65 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Level : ${leaderboard[i].level}`, 840, (95 + ((i <= 4 ? i : i - 5) * 128)));
ctx.fillText(`Expérience : ${leaderboard[i].xp} / ${leaderboard[i].need}`, 840, (125 + ((i <= 4 ? i : i - 5) * 128)));
}
}
ctx.beginPath();
ctx.arc(104, (84 + (0 * 128)), 42.5, 0, Math.PI * 2);
ctx.arc(744, (84 + (0 * 128)), 42.5, Math.PI * 1, Math.PI * 3);
ctx.arc(104, (84 + (1 * 128)), 42.5, 0, Math.PI * 2);
ctx.arc(744, (84 + (1 * 128)), 42.5, Math.PI * 1, Math.PI * 3);
ctx.arc(104, (84 + (2 * 128)), 42.5, 0, Math.PI * 2);
ctx.arc(744, (84 + (2 * 128)), 42.5, Math.PI * 1, Math.PI * 3);
ctx.arc(104, (84 + (3 * 128)), 42.5, 0, Math.PI * 2);
ctx.arc(744, (84 + (3 * 128)), 42.5, Math.PI * 1, Math.PI * 3);
ctx.arc(104, (84 + (4 * 128)), 42.5, 0, Math.PI * 2);
ctx.arc(744, (84 + (4 * 128)), 42.5, Math.PI * 1, Math.PI * 3);
ctx.closePath();
ctx.clip();
for(let i = 0; i < 5; i++) {
const user = await this.bot.users.fetch(leaderboard[i].user.id);
const member = await this.guild.members.cache.get(user.id)
if(user) {
const avatar = await Canvas.loadImage(member ? member.avatar ? member.avatarURL({extension: "jpg"}) : user.displayAvatarURL({ extension: "jpg" }) : user.displayAvatarURL({ extension: "jpg" }))
ctx.drawImage(avatar, 62, (42 + (i * 128)), 85, 85);
}
}
for(let i = 5; i < count; i++) {
const user = await this.bot.users.fetch(leaderboard[i].user.id);
const member = await this.guild.members.cache.get(user.id)
if(user) {
const avatar = await Canvas.loadImage(member ? member.avatar ? member.avatarURL({extension: "jpg"}) : user.displayAvatarURL({ extension: "jpg" }) : user.displayAvatarURL({ extension: "jpg" }))
ctx.drawImage(avatar, 702, (42 + ((i - 5) * 128)), 85, 85);
}
}
}
return canvas;
}
}