mewcard
Version:
Experience your Discord bot's music in a visual format.
967 lines (774 loc) • 179 kB
JavaScript
const canvas = require("@napi-rs/canvas");
const { colorFetch } = require("../functions/colorFetch");
const { createCanvas, loadImage } = require("@napi-rs/canvas");
// canvas.GlobalFonts.registerFromPath(`build/structures/font/circularstd-black.otf`, "circular-std");
// canvas.GlobalFonts.registerFromPath(`build/structures/font/notosans-jp-black.ttf`, "noto-sans-jp");
// canvas.GlobalFonts.registerFromPath(`build/structures/font/notosans-black.ttf`, "noto-sans");
// canvas.GlobalFonts.registerFromPath(`build/structures/font/notoemoji-bold.ttf`, "noto-emoji");
// canvas.GlobalFonts.registerFromPath(`build/structures/font/notosans-kr-black.ttf`, "noto-sans-kr");
canvas.GlobalFonts.registerFromPath(`node_modules/mewcard/build/structures/font/circularstd-black.otf`, "circular-std");
canvas.GlobalFonts.registerFromPath(`node_modules/mewcard/build/structures/font/notosans-jp-black.ttf`, "noto-sans-jp");
canvas.GlobalFonts.registerFromPath(`node_modules/mewcard/build/structures/font/notosans-black.ttf`, "noto-sans");
canvas.GlobalFonts.registerFromPath(`node_modules/mewcard/build/structures/font/notoemoji-bold.ttf`, "noto-emoji");
canvas.GlobalFonts.registerFromPath(`node_modules/mewcard/build/structures/font/notosans-kr-black.ttf`, "noto-sans-kr");
canvas.GlobalFonts.registerFromPath(`node_modules/musicard-bun/build/structures/font/Chewy-Regular.ttf`, "chewy");
canvas.GlobalFonts.registerFromPath(`node_modules/musicard-bun/build/structures/font/Space.ttf`, "space");
class mewcard {
constructor(options) {
this.name = options?.name ?? null;
this.author = options?.author ?? null;
this.color = options?.color ?? null;
this.theme = options?.theme ?? null;
this.brightness = options?.brightness ?? null;
this.thumbnail = options?.thumbnail ?? null;
this.progress = options?.progress ?? null;
this.starttime = options?.startTime ?? null;
this.endtime = options?.endTime ?? null;
this.requester = options?.requester ?? null
}
setName(name) {
this.name = name;
return this;
}
setAuthor(author) {
this.author = author;
return this;
}
setColor(color) {
this.color = color;
return this;
}
setTheme(theme) {
this.theme = theme || 'mewwme';
return this;
}
setBrightness(brightness) {
this.brightness = brightness;
return this;
}
setThumbnail(thumbnail) {
this.thumbnail = thumbnail;
return this;
}
setProgress(progress) {
this.progress = progress;
return this;
}
setStartTime(starttime) {
this.starttime = starttime;
return this;
}
setEndTime(endtime) {
this.endtime = endtime;
return this;
}
setRequester(requester) {
this.requester = `${requester}`;
return this;
}
async build() {
if (!this.name) throw new Error('Missing name parameter');
if (!this.author) throw new Error('Missing author parameter');
if (!this.requester) throw new Error('Missing requester parameter');
if (!this.color) this.setColor('ff0000');
if (!this.theme) this.setTheme('mewwme');
if (!this.brightness) this.setBrightness(0);
if (!this.thumbnail) this.setThumbnail('https://mewassets.vercel.app/assets/thumbnail.png');
if (!this.progress) this.setProgress(0);
if (!this.starttime) this.setStartTime('0:00');
if (!this.endtime) this.setEndTime('0:00');
let validatedProgress = parseFloat(this.progress);
if (Number.isNaN(validatedProgress) || validatedProgress < 0 || validatedProgress > 100) throw new Error('Invalid progress parameter, must be between 0 to 100');
if (validatedProgress < 2) validatedProgress = 2;
if (validatedProgress > 99) validatedProgress = 99;
const validatedColor = await colorFetch(
this.color || 'ff0000',
parseInt(this.brightness) || 0,
this.thumbnail
);
if (this.name.replace(/\s/g, '').length > 15) this.name = `${this.name.slice(0, 15)}...`;
if (this.author.replace(/\s/g, '').length > 15) this.author = `${this.author.slice(0, 15)}`;
if (this.requester.replace(/\s/g, '').length > 12) this.requester = `${this.requester.slice(0, 10)}...`;
if (this.theme == 'mewwme') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
// Daftar URL gambar yang dapat dipilih secara acak
const imageUrls = [
"https://mewassets.vercel.app/mewwme/assets/card/1.png",
"https://mewassets.vercel.app/mewwme/assets/card/2.png",
"https://mewassets.vercel.app/mewwme/assets/card/3.png",
"https://mewassets.vercel.app/mewwme/assets/card/4.png",
"https://mewassets.vercel.app/mewwme/assets/card/5.png",
"https://mewassets.vercel.app/mewwme/assets/card/6.png",
"https://mewassets.vercel.app/mewwme/assets/card/7.png",
"https://mewassets.vercel.app/mewwme/assets/card/8.png",
"https://mewassets.vercel.app/mewwme/assets/card/9.png",
"https://mewassets.vercel.app/mewwme/assets/card/10.png",
"https://mewassets.vercel.app/mewwme/assets/card/11.png",
"https://mewassets.vercel.app/mewwme/assets/card/12.png",
"https://mewassets.vercel.app/mewwme/assets/card/13.png",
"https://mewassets.vercel.app/mewwme/assets/card/14.png",
"https://mewassets.vercel.app/mewwme/assets/card/15.png",
"https://mewassets.vercel.app/mewwme/assets/card/16.png",
"https://mewassets.vercel.app/mewwme/assets/card/17.png",
"https://mewassets.vercel.app/mewwme/assets/card/18.png",
"https://mewassets.vercel.app/mewwme/assets/card/19.png",
"https://mewassets.vercel.app/mewwme/assets/card/20.png",
"https://mewassets.vercel.app/mewwme/assets/card/21.png",
"https://mewassets.vercel.app/mewwme/assets/card/22.png",
];
// Fungsi untuk memilih URL gambar secara acak
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/mewwme/assets/card/thumbnail.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#f2d7b7'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#77797c', '#0641c7', '#967e58', '#628fa4', '#d34d52', '#f00c8f'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 50px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 103);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 143);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 143); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'listune') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
// Daftar URL gambar yang dapat dipilih secara acak
const imageUrls = [
"https://listune.app/assets/listune-card.png"
];
// Fungsi untuk memilih URL gambar secara acak
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://listune.app/assets/listune.png`); // Gunakan gambar default atau URL alternatif
}
// Atur area thumbnail agar pas dengan frame pada background card
const thumbX = 85;
const thumbY = 34;
const thumbWidth = 137;
const thumbHeight = 137;
const thumbRadius = 15;
const targetAspect = thumbWidth / thumbHeight;
const imageAspect = thumbnailImage.width / thumbnailImage.height;
let sourceX = 0;
let sourceY = 0;
let sourceWidth = thumbnailImage.width;
let sourceHeight = thumbnailImage.height;
if (imageAspect > targetAspect) {
sourceWidth = thumbnailImage.height * targetAspect;
sourceX = (thumbnailImage.width - sourceWidth) / 2;
} else {
sourceHeight = thumbnailImage.width / targetAspect;
sourceY = (thumbnailImage.height - sourceHeight) / 2;
}
// Rounded thumbnail
ctx.save();
ctx.beginPath();
ctx.moveTo(thumbX + thumbRadius, thumbY);
ctx.arcTo(thumbX + thumbWidth, thumbY, thumbX + thumbWidth, thumbY + thumbHeight, thumbRadius);
ctx.arcTo(thumbX + thumbWidth, thumbY + thumbHeight, thumbX, thumbY + thumbHeight, thumbRadius);
ctx.arcTo(thumbX, thumbY + thumbHeight, thumbX, thumbY, thumbRadius);
ctx.arcTo(thumbX, thumbY, thumbX + thumbWidth, thumbY, thumbRadius);
ctx.closePath();
ctx.clip();
ctx.drawImage(
thumbnailImage,
sourceX,
sourceY,
sourceWidth,
sourceHeight,
thumbX,
thumbY,
thumbWidth,
thumbHeight
);
ctx.restore();
const allowedColors = ['#77797c', '#0641c7', '#967e58', '#628fa4', '#d34d52', '#f00c8f'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 50px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 103);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 143);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 143); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'bebe') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
// Daftar URL gambar yang dapat dipilih secara acak
const imageUrls = [
"https://mewassets.vercel.app/assets/be/card/becard.png",
];
// Fungsi untuk memilih URL gambar secara acak
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/assets/be/card/thumbnail.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#f2d7b7'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#77797c', '#0641c7', '#967e58', '#628fa4', '#d34d52', '#f00c8f'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 50px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 103);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 143);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 34px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 143); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'kobokanaeru') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
const imageUrls = [
"https://mewassets.vercel.app/mewcard/KoboKanaeru/1.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/2.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/3.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/4.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/5.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/6.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/7.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/8.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/9.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/10.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/11.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/12.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/13.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/14.png",
"https://mewassets.vercel.app/mewcard/KoboKanaeru/15.png",
];
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/mewcard/KoboKanaeru/kobokanaeru.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#79b8d5'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#79b8d5', '#90979a', '#f89f96', '#d0cfcd', '#fcd0d1', '#fefefe'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 40px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 100);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 140);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 140); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'vestiazeta') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
const imageUrls = [
"https://mewassets.vercel.app/mewcard/VestiaZeta/1.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/2.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/3.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/4.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/5.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/6.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/7.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/8.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/9.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/10.png",
"https://mewassets.vercel.app/mewcard/VestiaZeta/11.png",
];
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/mewcard/VestiaZeta/vestiazeta.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#f2d7b7'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#b6b5ba', '#b2a085', '#747fa6', '#fef7f1', '#d6d5dd', '#b0c8ea'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 40px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 100);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 140);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 140); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'cute') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
const imageUrls = [
"https://mewassets.vercel.app/mewcard/Cute/1.png",
"https://mewassets.vercel.app/mewcard/Cute/2.png",
"https://mewassets.vercel.app/mewcard/Cute/3.png",
"https://mewassets.vercel.app/mewcard/Cute/4.png",
"https://mewassets.vercel.app/mewcard/Cute/5.png",
"https://mewassets.vercel.app/mewcard/Cute/6.png",
"https://mewassets.vercel.app/mewcard/Cute/7.png",
"https://mewassets.vercel.app/mewcard/Cute/8.png",
"https://mewassets.vercel.app/mewcard/Cute/9.png",
"https://mewassets.vercel.app/mewcard/Cute/10.png",
];
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/mewcard/VestiaZeta/vestiazeta.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#f4e0c7'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#96dcfc', '#b6b5ba', '#f4e0c7', '#e2b379', '#f9cfc2', '#ff4158'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 40px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 100);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 140);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 140); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'yui') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
// Daftar URL gambar yang dapat dipilih secara acak
const imageUrls = [
"https://mewassets.vercel.app/mewcard/mewwme/1.png",
"https://mewassets.vercel.app/mewcard/mewwme/2.png",
"https://mewassets.vercel.app/mewcard/mewwme/3.png",
"https://mewassets.vercel.app/mewcard/mewwme/4.png",
"https://mewassets.vercel.app/mewcard/mewwme/5.png",
"https://mewassets.vercel.app/mewcard/mewwme/6.png",
"https://mewassets.vercel.app/mewcard/mewwme/7.png",
"https://mewassets.vercel.app/mewcard/mewwme/8.png",
"https://mewassets.vercel.app/mewcard/mewwme/9.png",
"https://mewassets.vercel.app/mewcard/mewwme/10.png",
"https://mewassets.vercel.app/mewcard/mewwme/11.png",
"https://mewassets.vercel.app/mewcard/mewwme/12.png",
"https://mewassets.vercel.app/mewcard/mewwme/13.png",
"https://mewassets.vercel.app/mewcard/mewwme/14.png",
"https://mewassets.vercel.app/mewcard/mewwme/15.png",
"https://mewassets.vercel.app/mewcard/mewwme/16.png",
"https://mewassets.vercel.app/mewcard/mewwme/17.png",
"https://mewassets.vercel.app/mewcard/mewwme/18.png",
"https://mewassets.vercel.app/mewcard/mewwme/19.png",
"https://mewassets.vercel.app/mewcard/mewwme/20.png",
"https://mewassets.vercel.app/mewcard/mewwme/21.png",
"https://mewassets.vercel.app/mewcard/mewwme/22.png",
"https://mewassets.vercel.app/mewcard/mewwme/23.png",
"https://mewassets.vercel.app/mewcard/mewwme/24.png",
"https://mewassets.vercel.app/mewcard/mewwme/25.png",
"https://mewassets.vercel.app/mewcard/mewwme/26.png",
"https://mewassets.vercel.app/mewcard/mewwme/27.png",
"https://mewassets.vercel.app/mewcard/mewwme/28.png",
"https://mewassets.vercel.app/mewcard/mewwme/29.png",
"https://mewassets.vercel.app/mewcard/mewwme/30.png",
"https://mewassets.vercel.app/mewcard/mewwme/31.png",
"https://mewassets.vercel.app/mewcard/mewwme/32.png",
"https://mewassets.vercel.app/mewcard/mewwme/33.png",
"https://mewassets.vercel.app/mewcard/mewwme/34.png",
"https://mewassets.vercel.app/mewcard/mewwme/35.png",
];
// Fungsi untuk memilih URL gambar secara acak
function getRandomImageUrl() {
const randomIndex = Math.floor(Math.random() * imageUrls.length);
return imageUrls[randomIndex];
}
// Mengambil gambar secara acak
const backgroundUrl = getRandomImageUrl();
const background = await canvas.loadImage(backgroundUrl);
ctx.drawImage(background, 0, 0, frame.width, frame.height);
const thumbnailCanvas = canvas.createCanvas(800, 200); // Mengubah lebar kanvas
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported [Lofi & Radio]');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/assets/thumbnail.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
// Menggambar thumbnail
ctx.drawImage(thumbnailCanvas, 50, 40, 180, 130);
// Menambahkan border putih
ctx.strokeStyle = '#f2d7b7'; // Warna border putih
ctx.lineWidth = 5; // Lebar border (sesuaikan dengan preferensi Anda)
ctx.strokeRect(50, 40, 180, 130); // Koordinat dan ukuran border
// Fungsi untuk menghasilkan warna heksadesimal acak
// Array warna yang diizinkan
const allowedColors = ['#f2d7b7', '#fbc5f9', '#00ff2a', '#ff00a8', '#00ffe4', '#ff6000'];
// Fungsi untuk memilih warna secara acak dari array di atas
function getRandomColor() {
return allowedColors[Math.floor(Math.random() * allowedColors.length)];
}
// Mengatur warna teks secara acak dari array yang diizinkan
ctx.font = "bold 40px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.fillText(this.name, 250, 100);
// Teks "author" dengan warna dan ukuran font yang berbeda
const authorText = this.author;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(authorText, 250, 140);
// Mengukur lebar teks "author" untuk menentukan posisi teks "requester"
const authorTextWidth = ctx.measureText(authorText).width;
// Teks "requester" dengan warna dan ukuran font yang berbeda
const requesterText = this.requester;
ctx.fillStyle = getRandomColor(); // Menggunakan fungsi untuk warna acak dari array yang diizinkan
ctx.font = "bold 26px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr";
ctx.fillText(requesterText, 250 + authorTextWidth + 10, 140); // Mengatur posisi "requester" setelah "author"
return frame.toBuffer("image/png");
} else if (this.theme == 'themes1') {
const progressBarWidth = (validatedProgress / 100) * 670;
const circleX = progressBarWidth + 60;
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
circleCtx.beginPath();
circleCtx.arc(circleX, circleY, circleRadius, 0, 2 * Math.PI);
circleCtx.fillStyle = `#${validatedColor}`;
circleCtx.fill();
const background = await canvas.loadImage(`https://mewassets.vercel.app/mewcard/themes1/1.png`);
const thumbnailCanvas = canvas.createCanvas(650, 650);
const thumbnailCtx = thumbnailCanvas.getContext('2d');
let thumbnailImage;
try {
thumbnailImage = await canvas.loadImage(this.thumbnail, {
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
}
});
} catch (error) {
// Mengatasi kesalahan ketika gambar tidak dapat dimuat
console.error('MUSICARD: Thumbnail image failed to load, not supported');
thumbnailImage = await canvas.loadImage(`https://mewassets.vercel.app/mewcard/themes8/thumbnail.png`); // Gunakan gambar default atau URL alternatif
}
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height);
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2;
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2;
const cornerRadius2 = 45;
thumbnailCtx.beginPath();
thumbnailCtx.moveTo(0 + cornerRadius2, 0);
thumbnailCtx.arcTo(thumbnailCanvas.width, 0, thumbnailCanvas.width, thumbnailCanvas.height, cornerRadius2);
thumbnailCtx.arcTo(thumbnailCanvas.width, thumbnailCanvas.height, 0, thumbnailCanvas.height, cornerRadius2);
thumbnailCtx.arcTo(0, thumbnailCanvas.height, 0, 0, cornerRadius2);
thumbnailCtx.arcTo(0, 0, thumbnailCanvas.width, 0, cornerRadius2);
thumbnailCtx.closePath();
thumbnailCtx.clip();
thumbnailCtx.drawImage(thumbnailImage, thumbnailX, thumbnailY, thumbnailSize, thumbnailSize, 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
const image = canvas.createCanvas(1280, 450);
const ctx = image.getContext('2d');
// Draw the background
ctx.drawImage(background, 0, 0, 1280, 450);
ctx.fillStyle = `#${validatedColor}`;
ctx.font = `75px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr`;
ctx.fillText(this.name, 490, 180);
ctx.fillStyle = '#f40cb5';
ctx.font = `55px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr`;
ctx.fillText(this.author, 510, 260);
ctx.fillStyle = '#0cf4bb';
ctx.font = `50px circular-std, noto-emoji, noto-sans-jp, noto-sans, noto-sans-kr`;
ctx.fillText(this.requester, 520, 330);
ctx.drawImage(thumbnailCanvas, 70, 50, 350, 350);
return image.toBuffer('image/png');
} else if (this.theme == 'themes2') {
const frame = canvas.createCanvas(800, 200);
const ctx = frame.getContext("2d");
const circleCanvas = canvas.createCanvas(1000, 1000);
const circleCtx = circleCanvas.getContext('2d');
const circleRadius = 20;
const circleY = 97;
// Daftar URL gambar yang dapat dipilih secara acak
const imageUrls = [
"https://mewassets.vercel.app/mewcard/themes2/1.png",
"https://mewassets.vercel.app/mewcard/themes2/2.png",
"https://mewassets.vercel.app/mewcard/themes2/3.png",
"https://mewassets.vercel.app/mewcard/themes2/4.png",
"https://mewassets.vercel.app/mewcard/themes2/5.png",
"https://mewassets.vercel.app/mewcard/themes2/6.png",
"https://mewassets.vercel.app/mewcard/themes2/7.png",
"https://mewassets.vercel.app/mewcard/themes2/8.png",
"https://mewassets.vercel.app/mewcard/themes2/9.png",
"https://mewassets.vercel.app/mewcard/themes2/10.png",
"https://mewassets.vercel.app/mewcard/themes2/11.png",
"https://mewassets.vercel.app/mewcard/themes2/12.png",
"https://mewassets.vercel.app/mewcard/themes2/13.png",
"https://mewassets.vercel.app/mewcard/themes2/14.png",
"https://mewassets.vercel.app/mewcard/themes2/15.png",
"https://mewassets.vercel.app/mewcard/themes2/16.png",
"https://mewassets.vercel.app/mewcard/themes2/17.png",
"https://mewassets.vercel.app/mewcard/themes2/18.png",
"https:/