Skip to content

Commit

Permalink
discord-canvas greetings
Browse files Browse the repository at this point in the history
  • Loading branch information
twlite committed Jul 16, 2022
1 parent 1ac8496 commit 8f97638
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/Welcomer.js
@@ -1,4 +1,4 @@
const { Base } = require("discord-canvas");
const Base = require("./base/GreetingsCard");
const Util = require("./Util");

class Welcomer extends Base {
Expand Down Expand Up @@ -87,7 +87,7 @@ class Welcomer extends Base {
* @returns {Promise<Buffer>}
*/
async build() {
return (await this.toAttachment()).toBuffer();
return (await this.toAttachment()).encode("png");
}

}
Expand Down
175 changes: 175 additions & 0 deletions src/base/GreetingsCard.js
@@ -0,0 +1,175 @@
/*
* Original source: https://github.com/xixi52/discord-canvas/blob/15cea8f78c27178ff030db8d5c2c3b526dc337a2/src/greetings/Base.js
* Copyrighted to xixi52
*/

const Canvas = require("@napi-rs/canvas");
const assets = require("../Assets");

const formatVariable = (prefix, variable) => {
const formattedVariable = variable.toLowerCase()
.split("-").map((word) => word.charAt(0).toUpperCase() + word.substr(1, word.length).toLowerCase()).join("");
return prefix + formattedVariable;
}

const applyText = (canvas, text, defaultFontSize, width, font) => {
const ctx = canvas.getContext("2d");
do {
ctx.font = `${(defaultFontSize -= 1)}px ${font}`;
} while (ctx.measureText(text).width > width);
return ctx.font;
}

module.exports = class Greeting {

constructor() {
this.username = "Clyde";
this.guildName = "ServerName";
this.colorTitleBorder = "#000000";
this.colorMemberCount = "#ffffff";
this.textMemberCount = "- {count}th member !";
this.memberCount = "0";
this.backgroundImage = assets.image.get("GREETINGS_BACKGROUND");
this.avatar = null;
this.opacityBorder = "0.4";
this.colorBorder = "#000000";
this.colorUsername = "#ffffff";
this.colorUsernameBox = "#000000";
this.opacityUsernameBox = "0.4";
this.discriminator = "XXXX";
this.colorDiscriminator = "#ffffff";
this.opacityDiscriminatorBox = "0.4";
this.colorDiscriminatorBox = "#000000";
this.colorMessage = "#ffffff";
this.colorHashtag = "#ffffff";
this.colorBackground = "000000";
}

setAvatar(value) {
this.avatar = value;
return this;
}

setDiscriminator(value) {
this.discriminator = value;
return this;
}

setUsername(value) {
this.username = value;
return this;
}

setGuildName(value) {
this.guildName = value;
return this;
}

setMemberCount(value) {
this.memberCount = value;
return this;
}

setBackground(value) {
this.backgroundImage = value;
return this;
}

setColor(variable, value) {
const formattedVariable = formatVariable("color", variable);
if (this[formattedVariable]) this[formattedVariable] = value;
return this;
}

setText(variable, value) {
const formattedVariable = formatVariable("text", variable);
if (this[formattedVariable]) this[formattedVariable] = value;
return this;
}

setOpacity(variable, value) {
const formattedVariable = formatVariable("opacity", variable);
if (this[formattedVariable]) this[formattedVariable] = value;
return this;
}

async toAttachment() {
if (!this.avatar) throw new Error("avatar is required");
// Create canvas
const canvas = Canvas.createCanvas(1024, 450);
const ctx = canvas.getContext("2d");

const guildName = this.textMessage.replace(/{server}/g, this.guildName);
const memberCount = this.textMemberCount.replace(/{count}/g, this.memberCount);

// Draw background
ctx.fillStyle = this.colorBackground;
ctx.fillRect(0, 0, canvas.width, canvas.height);
let background = await Canvas.loadImage(this.backgroundImage);
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);

// Draw layer
ctx.fillStyle = this.colorBorder;
ctx.globalAlpha = this.opacityBorder;
ctx.fillRect(0, 0, 25, canvas.height);
ctx.fillRect(canvas.width - 25, 0, 25, canvas.height);
ctx.fillRect(25, 0, canvas.width - 50, 25);
ctx.fillRect(25, canvas.height - 25, canvas.width - 50, 25);
ctx.fillStyle = this.colorUsernameBox;
ctx.globalAlpha = this.opacityUsernameBox;
ctx.fillRect(344, canvas.height - 296, 625, 65);
ctx.fillStyle = this.colorDiscriminatorBox;
ctx.globalAlpha = this.opacityDiscriminatorBox;
ctx.fillRect(389, canvas.height - 225, 138, 65);
ctx.fillStyle = this.colorMessageBox;
ctx.globalAlpha = this.opacityMessageBox;
ctx.fillRect(308, canvas.height - 110, 672, 65);

// Draw username
ctx.globalAlpha = 1;
ctx.fillStyle = this.colorUsername;
ctx.font = applyText(canvas, this.username, 48, 600, "Bold");
ctx.fillText(this.username, canvas.width - 660, canvas.height - 248);

// Draw guild name
ctx.fillStyle = this.colorMessage;
ctx.font = applyText(canvas, guildName, 53, 600, "Bold");
ctx.fillText(guildName, canvas.width - 690, canvas.height - 62);

// Draw discriminator
ctx.fillStyle = this.colorDiscriminator;
ctx.font = "40px Bold";
ctx.fillText(this.discriminator, canvas.width - 623, canvas.height - 178);

// Draw membercount
ctx.fillStyle = this.colorMemberCount;
ctx.font = "22px Bold";
ctx.fillText(memberCount, 40, canvas.height - 35);

// Draw # for discriminator
ctx.fillStyle = this.colorHashtag;
ctx.font = "75px SketchMatch";
ctx.fillText("#", canvas.width - 690, canvas.height - 165);

// Draw title
ctx.font = "90px Bold";
ctx.strokeStyle = this.colorTitleBorder;
ctx.lineWidth = 15;
ctx.strokeText(this.textTitle, canvas.width - 620, canvas.height - 330);
ctx.fillStyle = this.colorTitle;
ctx.fillText(this.textTitle, canvas.width - 620, canvas.height - 330);

// Draw avatar circle
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = this.colorAvatar;
ctx.arc(180, 225, 135, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.clip();
const avatar = await Canvas.loadImage(this.avatar);
ctx.drawImage(avatar, 45, 90, 270, 270);

return canvas;
}
};

0 comments on commit 8f97638

Please sign in to comment.