AeThex-Bot-Master/aethex-bot/utils/welcomeCard.js
sirpiglr 0241e09e80 Add welcome card customization and seasonal event features
Introduces customizable welcome cards using the canvas library and enhances the XP tracking system to incorporate active seasonal events with multipliers and bonus XP. Also adds presets and custom creation for seasonal events.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 6d6bb71e-5e8e-4841-9c13-fd5e76c7d9e6
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/auRwRay
Replit-Helium-Checkpoint-Created: true
2025-12-13 00:45:03 +00:00

126 lines
3.9 KiB
JavaScript

const { createCanvas, loadImage, registerFont } = require('canvas');
const path = require('path');
const CARD_WIDTH = 900;
const CARD_HEIGHT = 300;
async function generateWelcomeCard(member, config = {}) {
const canvas = createCanvas(CARD_WIDTH, CARD_HEIGHT);
const ctx = canvas.getContext('2d');
const bgColor = config.background_color || '#1a1a2e';
const accentColor = config.accent_color || '#7c3aed';
const textColor = config.text_color || '#ffffff';
const subtextColor = config.subtext_color || '#a0a0a0';
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, CARD_WIDTH, CARD_HEIGHT);
const gradient = ctx.createLinearGradient(0, 0, CARD_WIDTH, 0);
gradient.addColorStop(0, hexToRgba(accentColor, 0.3));
gradient.addColorStop(0.5, hexToRgba(accentColor, 0.1));
gradient.addColorStop(1, 'transparent');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, CARD_WIDTH, CARD_HEIGHT);
ctx.strokeStyle = accentColor;
ctx.lineWidth = 4;
ctx.strokeRect(2, 2, CARD_WIDTH - 4, CARD_HEIGHT - 4);
for (let i = 0; i < 50; i++) {
const x = Math.random() * CARD_WIDTH;
const y = Math.random() * CARD_HEIGHT;
const size = Math.random() * 2;
ctx.fillStyle = hexToRgba(accentColor, Math.random() * 0.3);
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fill();
}
const avatarSize = 160;
const avatarX = 70;
const avatarY = (CARD_HEIGHT - avatarSize) / 2;
try {
const avatarURL = member.displayAvatarURL({ extension: 'png', size: 256 });
const avatar = await loadImage(avatarURL);
ctx.save();
ctx.beginPath();
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2 + 4, 0, Math.PI * 2);
ctx.fillStyle = accentColor;
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(avatar, avatarX, avatarY, avatarSize, avatarSize);
ctx.restore();
} catch (err) {
ctx.save();
ctx.beginPath();
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, Math.PI * 2);
ctx.fillStyle = accentColor;
ctx.fill();
ctx.restore();
ctx.fillStyle = textColor;
ctx.font = 'bold 60px Arial';
ctx.textAlign = 'center';
ctx.fillText(member.user.username[0].toUpperCase(), avatarX + avatarSize / 2, avatarY + avatarSize / 2 + 20);
}
const textX = avatarX + avatarSize + 50;
ctx.fillStyle = textColor;
ctx.font = 'bold 36px Arial';
ctx.textAlign = 'left';
const welcomeText = config.title || 'WELCOME';
ctx.fillText(welcomeText, textX, 80);
const username = member.user.username;
const maxUsernameWidth = CARD_WIDTH - textX - 50;
let fontSize = 48;
ctx.font = `bold ${fontSize}px Arial`;
while (ctx.measureText(username).width > maxUsernameWidth && fontSize > 24) {
fontSize -= 2;
ctx.font = `bold ${fontSize}px Arial`;
}
ctx.fillStyle = accentColor;
ctx.fillText(username, textX, 140);
ctx.fillStyle = subtextColor;
ctx.font = '22px Arial';
const serverName = member.guild.name;
ctx.fillText(`to ${serverName}`, textX, 175);
const memberCount = member.guild.memberCount;
ctx.fillStyle = textColor;
ctx.font = 'bold 28px Arial';
ctx.fillText(`Member #${memberCount.toLocaleString()}`, textX, 230);
const joinDate = new Date().toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
});
ctx.fillStyle = subtextColor;
ctx.font = '20px Arial';
ctx.fillText(`Joined: ${joinDate}`, textX, 265);
return canvas.toBuffer('image/png');
}
function hexToRgba(hex, alpha) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (result) {
const r = parseInt(result[1], 16);
const g = parseInt(result[2], 16);
const b = parseInt(result[3], 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
return `rgba(124, 58, 237, ${alpha})`;
}
module.exports = { generateWelcomeCard };