-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
308 additions
and
293 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
async function adjustBrightness(r, g, b, adjustment) { | ||
const adjustedR = Math.max(0, Math.min(255, r + adjustment)); | ||
const adjustedG = Math.max(0, Math.min(255, g + adjustment)); | ||
const adjustedB = Math.max(0, Math.min(255, b + adjustment)); | ||
|
||
return [adjustedR, adjustedG, adjustedB]; | ||
} | ||
|
||
module.exports = { adjustBrightness }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const { getColorFromURL } = require('color-thief-node'); | ||
const { rgbToHex } = require('./rgbToHex'); | ||
const { adjustBrightness } = require('./adjustBrightness'); | ||
|
||
async function colorFetch(color, brightness, thumbnail) { | ||
if (color === 'auto') { | ||
try { | ||
const dominantColor = await getColorFromURL(thumbnail); | ||
|
||
const red = dominantColor[0]; | ||
const green = dominantColor[1]; | ||
const blue = dominantColor[2]; | ||
|
||
const adjustedPalette = await adjustBrightness(red, green, blue, brightness); | ||
const hexColor = await rgbToHex(...adjustedPalette); | ||
|
||
return hexColor.replace('#', ''); | ||
} catch { | ||
return '03fc7f'; | ||
} | ||
} | ||
} | ||
|
||
module.exports = { colorFetch }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
async function rgbToHex(r, g, b) { | ||
const toHex = (value) => { | ||
const hex = value.toString(16); | ||
return hex.length === 1 ? '0' + hex : hex; | ||
}; | ||
|
||
const hexR = toHex(r); | ||
const hexG = toHex(g); | ||
const hexB = toHex(b); | ||
|
||
return `#${hexR}${hexG}${hexB}`; | ||
} | ||
|
||
module.exports = { rgbToHex }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,14 @@ | ||
declare module 'musicard' { | ||
class musicCard { | ||
constructor(); | ||
export declare class musicCard { | ||
constructor(); | ||
|
||
setName(name: string): this; | ||
setAuthor(author: string): this; | ||
setColor(color: string): this; | ||
setBrightness(brightness: number): this; | ||
setThumbnail(thumbnail: string): this; | ||
setProgress(progress: number): this; | ||
setStartTime(starttime: string): this; | ||
setEndTime(endtime: string): this; | ||
public setName(name: string): this; | ||
public setAuthor(author: string): this; | ||
public setColor(color: string): this; | ||
public setBrightness(brightness: number): this; | ||
public setThumbnail(thumbnail: string): this; | ||
public setProgress(progress: number): this; | ||
public setStartTime(starttime: string): this; | ||
public setEndTime(endtime: string): this; | ||
|
||
build(): Promise<Buffer>; | ||
} | ||
|
||
export { musicCard }; | ||
public build(): Promise<Buffer>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,269 +1,3 @@ | ||
const devmod = false; | ||
|
||
const { Canvas } = require('canvas-constructor/napi-rs'); | ||
const canvas = require("@napi-rs/canvas"); | ||
const { getColorFromURL } = require('color-thief-node'); | ||
|
||
// Register fonts | ||
canvas.GlobalFonts.registerFromPath(`${devmod ? "" : "node_modules/musicard/"}res/momcakebold.ttf`, 'momcakebold'); | ||
|
||
// Create music card class | ||
class musicCard { | ||
constructor() { | ||
this.name = null; | ||
this.author = null; | ||
this.color = null; | ||
this.brightness = null; | ||
this.thumbnail = null; | ||
this.progress = null; | ||
this.starttime = null; | ||
this.endtime = null; | ||
} | ||
|
||
setName(name) { | ||
this.name = name; | ||
return this; | ||
} | ||
|
||
setAuthor(author) { | ||
this.author = author; | ||
return this; | ||
} | ||
|
||
setColor(color) { | ||
this.color = color; | ||
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; | ||
} | ||
|
||
async rgbToHex(r, g, b) { | ||
const toHex = (value) => { | ||
const hex = value.toString(16); | ||
return hex.length === 1 ? '0' + hex : hex; | ||
}; | ||
|
||
const hexR = toHex(r); | ||
const hexG = toHex(g); | ||
const hexB = toHex(b); | ||
|
||
return `#${hexR}${hexG}${hexB}`; | ||
} | ||
|
||
async adjustBrightness(r, g, b, adjustment) { | ||
const adjustedR = Math.max(0, Math.min(255, r + adjustment)); | ||
const adjustedG = Math.max(0, Math.min(255, g + adjustment)); | ||
const adjustedB = Math.max(0, Math.min(255, b + adjustment)); | ||
|
||
return [adjustedR, adjustedG, adjustedB]; | ||
} | ||
|
||
async build() { | ||
if (!this.name) { throw new Error('Missing name parameter'); } | ||
if (!this.author) { throw new Error('Missing author parameter'); } | ||
|
||
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; | ||
} | ||
|
||
const thumbnailURL = this.thumbnail || `${devmod ? "" : "node_modules/musicard/"}res/noimage.jpg`; | ||
const validatedStartTime = this.starttime || '0:00'; | ||
const validatedEndTime = this.endtime || '0:00'; | ||
const validatedBrightness = parseInt(this.brightness) || 0; | ||
|
||
let validatedColor = this.color || 'ff0000'; | ||
|
||
if (validatedColor === 'auto') { | ||
try { | ||
const dominantColor = await getColorFromURL(thumbnailURL); | ||
|
||
const red = dominantColor[0]; | ||
const green = dominantColor[1]; | ||
const blue = dominantColor[2]; | ||
|
||
const adjustedPalette = await this.adjustBrightness(red, green, blue, validatedBrightness); | ||
const hexColor = await this.rgbToHex(...adjustedPalette); | ||
|
||
validatedColor = hexColor.replace('#', ''); | ||
} catch { | ||
validatedColor = 'ff0000'; | ||
} | ||
} | ||
|
||
const progressBarWidth = (validatedProgress / 100) * 670; | ||
const circleX = progressBarWidth + 60; | ||
|
||
const progressBarCanvas = canvas.createCanvas(670, 25); | ||
const progressBarCtx = progressBarCanvas.getContext('2d'); | ||
const cornerRadius = 10; | ||
progressBarCtx.beginPath(); | ||
progressBarCtx.moveTo(cornerRadius, 0); | ||
progressBarCtx.lineTo(670 - cornerRadius, 0); | ||
progressBarCtx.arc(670 - cornerRadius, cornerRadius, cornerRadius, 1.5 * Math.PI, 2 * Math.PI); | ||
progressBarCtx.lineTo(670, 25 - cornerRadius); | ||
progressBarCtx.arc(670 - cornerRadius, 25 - cornerRadius, cornerRadius, 0, 0.5 * Math.PI); | ||
progressBarCtx.lineTo(cornerRadius, 25); | ||
progressBarCtx.arc(cornerRadius, 25 - cornerRadius, cornerRadius, 0.5 * Math.PI, Math.PI); | ||
progressBarCtx.lineTo(0, cornerRadius); | ||
progressBarCtx.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, 1.5 * Math.PI); | ||
progressBarCtx.closePath(); | ||
progressBarCtx.fillStyle = '#ababab'; | ||
progressBarCtx.fill(); | ||
progressBarCtx.beginPath(); | ||
progressBarCtx.moveTo(cornerRadius, 0); | ||
progressBarCtx.lineTo(progressBarWidth - cornerRadius, 0); | ||
progressBarCtx.arc( | ||
progressBarWidth - cornerRadius, | ||
cornerRadius, | ||
cornerRadius, | ||
1.5 * Math.PI, | ||
2 * Math.PI, | ||
); | ||
progressBarCtx.lineTo(progressBarWidth, 25); | ||
progressBarCtx.lineTo(cornerRadius, 25); | ||
progressBarCtx.arc(cornerRadius, 25 - cornerRadius, cornerRadius, 0.5 * Math.PI, Math.PI); | ||
progressBarCtx.lineTo(0, cornerRadius); | ||
progressBarCtx.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, 1.5 * Math.PI); | ||
progressBarCtx.closePath(); | ||
progressBarCtx.fillStyle = `#${validatedColor}`; | ||
progressBarCtx.fill(); | ||
|
||
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 img = await canvas.loadImage(`${devmod ? "" : "node_modules/musicard/"}res/background.png`); | ||
|
||
const thumbnailCanvas = canvas.createCanvas(564, 564); | ||
const thumbnailCtx = thumbnailCanvas.getContext('2d'); | ||
|
||
let thumbnailImage; | ||
|
||
try { | ||
thumbnailImage = await canvas.loadImage(thumbnailURL, { | ||
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 Edg/116.0.1938.62', | ||
} | ||
} | ||
}); | ||
} catch { | ||
thumbnailImage = await canvas.loadImage(`${devmod ? "" : "node_modules/musicard/"}res/noimage.jpg`); | ||
} | ||
|
||
const thumbnailSize = Math.min(thumbnailImage.width, thumbnailImage.height); | ||
const thumbnailX = (thumbnailImage.width - thumbnailSize) / 2; | ||
const thumbnailY = (thumbnailImage.height - thumbnailSize) / 2; | ||
|
||
thumbnailCtx.beginPath(); | ||
const cornerRadius2 = 45; | ||
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, | ||
); | ||
|
||
if (this.name.length > 15) this.name = `${this.name.slice(0, 15)}...`; | ||
if (this.author.length > 15) this.author = `${this.author.slice(0, 15)}...`; | ||
|
||
const image = new Canvas(1280, 450) | ||
.setColor(`#${validatedColor}`) | ||
.printImage(img, 0, 0, 1280, 450) | ||
.setTextFont('80px momcakebold') | ||
.printText(`${this.name}`, 70, 120) | ||
|
||
.setColor('#fff') | ||
.setTextFont('60px momcakebold') | ||
.printText(`${this.author}`, 70, 180) | ||
|
||
.setColor('#fff') | ||
.setTextFont('35px momcakebold') | ||
.printText(`${validatedStartTime}`, 70, 410) | ||
|
||
.setColor('#fff') | ||
.setTextFont('35px momcakebold') | ||
.printText(`${validatedEndTime}`, 675, 410) | ||
|
||
.printImage(thumbnailCanvas, 837, 8, 435, 435) | ||
|
||
.printImage(progressBarCanvas, 70, 340, 670, 25) | ||
.printImage(circleCanvas, 10, 255, 1000, 1000); | ||
|
||
return image.pngAsync() | ||
} | ||
} | ||
const { musicCard } = require("./structures/musicCard"); | ||
|
||
module.exports = { musicCard }; |
Oops, something went wrong.