UNPKG

canvafy

Version:

Make configurable canvas easily with Canvafy

270 lines (226 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const { createCanvas, loadImage, GlobalFonts } = require('@napi-rs/canvas'); const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); const {otherImgs,otherBadges,nitroBadges,statusImgs,luppux} = require('../assets/images/profileFunc.json'); const badgesOrder = require('../plugins/badgesOrder.json'); /** * @typedef {object} Profile * @see {Profile} * @example const profileCard = await new canvafy.Profile() * @type {Class} */ module.exports = class Profile { constructor(options) { this.font = { name: options?.font?.name ?? "Poppins", path: options?.font?.path ?? `./assets/fonts/Poppins/Poppins-Regular.ttf` }; this.userid = "928259219038302258", this.activity = {}; this.border; } /** * .setBorder * @param {string} color "hexcolor" * @returns {Profile} * @example setBorder("#fff") */ setBorder(color) { if (color) { if (/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/.test(color)) { this.border = color; return this; } else { throw new Error("Invalid color for the argument in the setBorder method. You must give a hexadecimal color.") } } else { throw new Error("You must give a hexadecimal color as the argument of setBorder method."); } } /** * .setActivity * @param {activity} activity someone discord user activity index [1] * @returns {Profile} * @example setActivity(user.presence,user.presence.largeImage) */ setActivity({activity,largeImage}){ this.activity = activity; this.largeImage = largeImage; return this; } /** * .setUser * @param {number} id someone discord user id * @returns {Profile} * @example setUser("Someone User ID") */ setUser(id = 0) { if (id) { if(typeof id !== "string")throw new Error('You must add a parameter of String type setUser! Invalid user ID'); // const userRegex = new RegExp(/^([0-9]{17,20})$/); // if (!userRegex.test(id)) throw new Error('Invalid user ID'); this.userid = id; return this; } else { throw new Error("The setUser parameter cannot be left blank, please enter a user ID."); } } async build() { if (this.font.path) GlobalFonts.registerFromPath(this.font.path,this.font.name); const canvas = createCanvas(378, 536); const ctx = canvas.getContext("2d"); let userData = await fetch(`https://japi.rest/discord/v1/user/${this.userid}`) let { data } = await userData.json(); if(this.border){ ctx.beginPath(); ctx.lineWidth = 8; ctx.strokeStyle = this.border; ctx.moveTo(55, 15); ctx.lineTo(canvas.width - 55, 15); ctx.quadraticCurveTo(canvas.width - 20, 20, canvas.width - 15, 55); ctx.lineTo(canvas.width - 15, canvas.height - 55); ctx.quadraticCurveTo(canvas.width - 20, canvas.height - 20, canvas.width - 55, canvas.height - 15); ctx.lineTo(55, canvas.height - 15); ctx.quadraticCurveTo(20, canvas.height - 20, 15, canvas.height - 55); ctx.lineTo(15, 55); ctx.quadraticCurveTo(20, 20, 55, 15); ctx.lineTo(56, 15); ctx.stroke(); ctx.closePath(); } ctx.beginPath(); ctx.moveTo(65, 25); ctx.lineTo(canvas.width - 65, 25); ctx.quadraticCurveTo(canvas.width - 25, 25, canvas.width - 25, 65); ctx.lineTo(canvas.width - 25, canvas.height - 65); ctx.quadraticCurveTo(canvas.width - 25, canvas.height - 25, canvas.width - 65, canvas.height - 25); ctx.lineTo(65, canvas.height - 25); ctx.quadraticCurveTo(25, canvas.height - 25, 25, canvas.height - 65); ctx.lineTo(25, 65); ctx.quadraticCurveTo(25, 25, 65, 25); ctx.lineTo(66, 25); ctx.clip(); ctx.closePath(); ctx.beginPath(); ctx.globalAlpha = 1; ctx.fillStyle = "#232328"; ctx.fillRect(0, 0, canvas.width - 5, canvas.height - 5) ctx.closePath(); if (data?.bannerURL !== null) { let banner = `${data?.bannerURL}?size=512` try { ctx.drawImage(await loadImage(banner), 10, 10, 378, 140); } catch { ctx.beginPath(); ctx.fillStyle = data?.banner_color; ctx.fillRect(10, 10, 378, 140); ctx.closePath(); } } else { ctx.fillStyle = data?.banner_color; ctx.fillRect(10, 10, 378, 140); } let avatar = data?.avatarURL !== null ? `${data?.avatarURL}?size=512` : `${data?.defaultAvatarURL}?size=512` try { ctx.beginPath(); ctx.globalAlpha = 1; ctx.fillStyle = "#111214"; ctx.moveTo(75, 200); ctx.lineTo(canvas.width - 75, 200); ctx.quadraticCurveTo(canvas.width - 45, 200, canvas.width - 45, 200); ctx.lineTo(canvas.width - 45, 535 - 75); ctx.quadraticCurveTo(canvas.width - 45, 535 - 45, canvas.width - 75, 535 - 45); ctx.lineTo(75, 535 - 45); ctx.quadraticCurveTo(45, 535 - 45, 45, 535 - 75); ctx.lineTo(45, 200); ctx.quadraticCurveTo(200, 200, 75, 200); ctx.fill(); let badges = []; let flagsUser = data?.public_flags_array.sort((a, b) => badgesOrder[b] - badgesOrder[a]) if(["852800814808694814","379179073382907908","587564522009788426","136619876407050240","928259219038302258","341592492224806914","852103749228036136","331878061954039808","797096076330795018"].some(users => users == this.userid)) flagsUser.push('LUPPUX'); for (let i = 0; i < flagsUser?.length; i++) { if(flagsUser[i].startsWith('LUPPUX')){ const badge = await loadImage( Buffer.from(otherImgs['luppux'], 'base64') ); badges.push({ canvas: badge, x: 0, y: 165, w: 30 }); }else if (flagsUser[i].startsWith('BOOSTER')) { const badge = await loadImage( Buffer.from(nitroBadges[flagsUser[i]], 'base64') ); badges.push({ canvas: badge, x: 0, y: 165, w: 30 }); } else if (flagsUser[i].startsWith('NITRO')) { const badge = await loadImage( Buffer.from(otherBadges[flagsUser[i]], 'base64') ); badges.push({ canvas: badge, x: 0, y: 165, w: 30 }); } else { const badge = await loadImage( Buffer.from(otherBadges[flagsUser[i]], 'base64') ); badges.push({ canvas: badge, x: 0, y: 165, w: 30 }); } } let x = 300; badges.forEach(async (badge) => { const { canvas, x:bX, y, w } = badge; ctx.drawImage(canvas, x + bX, y, w, w); x -= 30; }); let globalNames = data?.global_name !== null ? data?.global_name : data?.username ctx.fillStyle = `WHITE`; ctx.font = `bold 20px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${globalNames.length > 16 ? globalNames.slice(0,16)+"..." : globalNames}`, 65, 235) ctx.fillStyle = `WHITE`; ctx.font = `bold 14px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`DISCORD MEMBER SINCE`, 65, 420) const createdDateString = new Date(data?.createdTimestamp).toLocaleDateString('en',{ month: 'long', day: 'numeric', year: 'numeric' }); ctx.fillStyle = `WHITE`; ctx.font = `normal 12px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${createdDateString}`, 65, 445) ctx.fillStyle = `WHITE`; ctx.font = `normal 15px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${data?.username.length > 18 ? data?.username.slice(0,18)+"..." : data?.username}`, 65, 255) if(this.activity && this.activity.name){ ctx.fillStyle = `WHITE`; ctx.font = `bold 12px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${this.activity.type == 0 ? "PLAYING A GAME" : this.activity.type == 2 ? `LISTENING TO ${this.activity.name.length > 8 ? this.activity.name.slice(0,11) : this.activity.name}` : this.activity.type == 3 ? `WATCHING ${this.activity.name.length > 8 ? this.activity.name.slice(0,11) : this.activity.name}`: this.activity.type == 1 ? `LIVE ON STREAM` : "PLAYING A GAME"}`, 65, 310) ctx.fillStyle = `WHITE`; ctx.font = `bold 10px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${this.activity.name !== null ? this.activity.name : "Anything"}`, 110, 333) ctx.fillStyle = `WHITE`; ctx.font = `normal 10px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${this.activity.details !== null ? `${this.activity.details}` : ""}`, 110, 345) ctx.fillStyle = `WHITE`; ctx.font = `normal 10px "${this.font.name}"`; ctx.globalAlpha = 1; ctx.fillText(`${this.activity.state !== null ? `${this.activity.state}` : ""}`, 110, 358) try { ctx.drawImage(await loadImage(this.activity.assets !== null ? this.largeImage !== null ? this.largeImage :"https://cdn.discordapp.com/attachments/1106235099743264768/1109156957182505010/2023-05-19_19-33-08.png" : "https://cdn.discordapp.com/attachments/1106235099743264768/1109156957182505010/2023-05-19_19-33-08.png"), 60, 320, 45, 45); } catch (error) { ctx.drawImage(await loadImage("https://cdn.discordapp.com/attachments/1106235099743264768/1109156957182505010/2023-05-19_19-33-08.png"), 60, 320, 45, 45); } } ctx.globalAlpha = 1; ctx.lineWidth = 12; ctx.strokeStyle = "#232328"; ctx.arc(90, 120, 55, 0, Math.PI * 2); ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.fill() ctx.lineWidth = 8; ctx.arc(90, 120, 50, 0, 2 * Math.PI); ctx.clip(); ctx.drawImage(await loadImage(avatar), 40, 70, 100, 100); ctx.closePath(); } catch(err) { } return canvas.toBuffer('image/png'); } };