89 lines
3.1 KiB
JavaScript
89 lines
3.1 KiB
JavaScript
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<Buffer>} - 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;
|