const { createCanvas, loadImage } = require('canvas'); const path = require('path'); /** * Calculates the XP required for the next level * @param {number} currentLevel - Current user level * @returns {number} XP required for next level */ function calculateNextLevelXP(currentLevel) { // Using the inverse of the level calculation formula from xpSystem.js // level = 0.47 * sqrt(xp) // Therefore, xp = (level/0.47)^2 return Math.ceil(Math.pow((currentLevel + 1) / 0.47, 2)); } /** * Generates a level card image for a user * @param {Object} user - User object containing id, username, xp, and level * @returns {Promise} - Returns a buffer containing the generated image */ async function generateLevelCard(user) { // Create canvas with dimensions matching the background image const canvas = createCanvas(1516, 662); const ctx = canvas.getContext('2d'); try { // Load background image const background = await loadImage(path.join(__dirname, '../../assets/level_clean.png')); ctx.drawImage(background, 0, 0, canvas.width, canvas.height); // Load progress bar fill image const progressFill = await loadImage(path.join(__dirname, '../../assets/progress_fill.png')); // Calculate XP progress using the same formula as xpSystem.js const currentLevelXP = Math.floor(Math.pow(user.level / 0.47, 2)); const nextLevelXP = Math.floor(calculateNextLevelXP(user.level)); const xpInLevel = user.xp - currentLevelXP; const xpForLevel = nextLevelXP - currentLevelXP; // Clamp progress between 0 and 1 const progress = Math.max(0, Math.min(1, xpInLevel / xpForLevel)); // Clamp displayed XP to not exceed xpForLevel const displayXP = Math.min(Math.max(0, xpInLevel), xpForLevel); // Draw username ctx.font = 'bold 60px Arial'; ctx.fillStyle = '#FFFFFF'; ctx.textAlign = 'left'; ctx.fillText(user.username, 420, 250); // Draw level ctx.font = 'bold 48px Arial'; ctx.fillStyle = '#FFD700'; // Gold color for level ctx.fillText(`Level ${user.level}`, 420, 330); // Progress bar dimensions and position const progressBarX = 472; const progressBarY = 388; const progressBarWidth = 800; const progressBarHeight = 60; // Draw progress bar fill ctx.drawImage( progressFill, progressBarX, progressBarY, progressBarWidth * progress, progressBarHeight ); // Draw XP progress text inside the bar, right-aligned ctx.font = 'bold 36px Arial'; ctx.fillStyle = '#FFFFFF'; ctx.textAlign = 'center'; ctx.fillText( `${displayXP}/${xpForLevel} XP`, progressBarX + progressBarWidth / 2, progressBarY + progressBarHeight / 2 + 12 // adjust as needed ); // Convert canvas to buffer return canvas.toBuffer('image/png'); } catch (error) { console.error('Error generating level card:', error); throw error; } } module.exports = generateLevelCard;