diff --git a/.gitignore b/.gitignore
index 25c8fdb..16acd49 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
node_modules
-package-lock.json
\ No newline at end of file
+dist
+package-lock.json
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..53ec92c
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,6 @@
+/node_modules
+/src
+/tests
+
+tsconfig.json
+tsup.config.ts
\ No newline at end of file
diff --git a/README.md b/README.md
index 90126a8..5e3cf32 100644
--- a/README.md
+++ b/README.md
@@ -1,72 +1,135 @@
-# **About**
-**Greetify** is futuristic welcome card canvas library
+
-# **Installation**
+
Futuristic welcome card canvas library
+
+
+ Github •
+ Support
+
+
+
+
+[![NPM Version](https://img.shields.io/npm/v/greetify?style=flat-square&color=%2300D684)](https://www.npmjs.com/package/greetify)
+[![NPM Downloads](https://img.shields.io/npm/dw/greetify?style=flat-square&color=%2300D684)](https://www.npmjs.com/package/greetify)
+[![NPM License](https://img.shields.io/npm/l/greetify?style=flat-square&color=%2300D684)](https://github.com/unburn/greetify/blob/main/LICENCE)
+[![GitHub Repo stars](https://img.shields.io/github/stars/unburn/greetify?style=flat-square&color=%2300D684)](https://github.com/unburn/greetify)
+
+
+
+
+
+
+
+# Installation
```
-npm i greetify
+npm install greetify
```
-# **Example Usage**
-This example code will create a welcome card and save it as a png.
-```js
-(async () => {
- // Importing modules
- const { welcomeCard } = require("greetify");
- const fs = require("fs")
-
- // Card details here
- const card = new welcomeCard()
- .setName("FlameFace")
- .setAvatar("https://s6.imgcdn.dev/ZFQlq.png")
- .setMessage("YOU ARE 688 MEMBER")
- .setBackground("https://s6.imgcdn.dev/ZqH2S.png")
- .setColor("00FF38") // without #
- .setTitle("Welcome")
-
- // Building process
- const output = await card.build();
-
- // Save as image
- fs.writeFileSync("card.png", output);
- console.log("Done");
-})()
+# Usage
+
+## Using File System (FS)
+```javascript
+import { Panorama } from "greetify";
+import fs from "fs";
+
+// OR
+
+const { Panorama } = require("greetify");
+const fs = require('fs')
+
+Panorama({
+ avatar: "https://cdn.discordapp.com/avatars/786504767358238720/f65e8322c0c290e7fc1d9ad20322256b.webp",
+ name: "FLAMEFACE",
+ type: "WELCOME",
+}).then(x => {
+ fs.writeFileSync("greetify.png", x)
+})
```
-This example is of **Discord Bot** using discord.js
-```js
-// Importing modules
-const { welcomeCard } = require("greetify");
-const { AttachmentBuilder } = require("discord.js")
-
-// Make sure to define client
-client.on('guildMemberAdd', async (member) => {
- // Card details here
- const card = new welcomeCard()
- .setName("FlameFace")
- .setAvatar("https://s6.imgcdn.dev/ZFQlq.png")
- .setMessage("YOU ARE 688 MEMBER")
- .setBackground("https://s6.imgcdn.dev/ZqH2S.png")
- .setColor("00FF38") // without #
- .setTitle("Welcome")
-
- // Building process
- const output = await card.build()
-
- // Fetch channel from members guild using ID
- const channel = member.guild.channels.cache.get("0000000000000000000");
-
- // Sends card to the "channel"
- await channel.send({
+## In Discord Bot
+```javascript
+// Assuming you defined client
+const { Minimal } = require("greetify");
+
+client.on("guildMemberAdd", async member => {
+ const message = `YOU ARE ${member.guild.memberCount}TH MEMBER`
+
+ const card = await Minimal({
+ name: member.user.username,
+ avatar: member.user.displayAvatarURL({
+ size: 4096 // For High Res Avatar
+ }),
+ type: "WELCOME",
+ message: message
+ })
+
+ const channel = member.guild.channels.cache.get("1201155869610627212");
+
+ return channel.send({
files: [{
- attachment: output,
- name: `${member.id}.png`
+ attachment: card
}]
})
})
```
-### **Output**
-![welcome-preview](https://s6.imgcdn.dev/ZFifB.png)
+# Themes
+## Minimal
+![minimal](https://ik.imagekit.io/unburn/minimal.svg)
+
+```javascript
+const { Minimal } = require("greetify");
+const fs = require('fs')
+
+Minimal({
+ avatar: "https://cdn.discordapp.com/avatars/786504767358238720/f65e8322c0c290e7fc1d9ad20322256b.webp",
+ name: "FLAMEFACE",
+ type: "WELCOME"
+}).then(x => {
+ fs.writeFileSync("greetify.png", x)
+})
+```
+
+### Minimal Options
+| Parameters | Types | Default |
+| --------------- | ------- | -------------------------------------------------- |
+| avatar* | string | none |
+| backgroundImage | string | https://ik.imagekit.io/unburn/greetify-default.png |
+| circleBorder | boolean | false |
+| message* | string | none |
+| messageColor | string | #FFFFFF |
+| name* | string | none |
+| nameColor | string | #00FF9E |
+| type | string | WELCOME |
+| typeColor | string | #FFFFFF |
+
+
+## Panorama
+![panorama](https://ik.imagekit.io/unburn/panorama.svg)
+
+```javascript
+const { Panorama } = require("greetify");
+const fs = require('fs')
+
+Panorama({
+ avatar: "https://cdn.discordapp.com/avatars/786504767358238720/f65e8322c0c290e7fc1d9ad20322256b.webp",
+ name: "FLAMEFACE",
+ type: "WELCOME"
+}).then(x => {
+ fs.writeFileSync("greetify.png", x)
+})
+```
+
+### Panorama Options
+| Parameters | Types | Default |
+| --------------- | ------- | -------------------------------------------------- |
+| avatar* | string | none |
+| backgroundImage | string | https://ik.imagekit.io/unburn/greetify-default.png |
+| circleBorder | boolean | false |
+| name* | string | none |
+| nameColor | string | #00FF9E |
+| type | string | WELCOME |
+| typeColor | string | #FFFFFF |
-# **Help**
-If you need help or want some features to be added, join our official **[burnxpofficial](https://discord.gg/qDysF95NWh)** community.
\ No newline at end of file
+# Licence
+[GPL](https://github.com/unburn/greetify/blob/main/LICENCE)
\ No newline at end of file
diff --git a/build/index.d.ts b/build/index.d.ts
deleted file mode 100644
index f77cbab..0000000
--- a/build/index.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export declare class welcomeCard {
- constructor(options?: {
- username?: string;
- avatar?: string;
- title?: string;
- color?: string;
- message?: string;
- background: string;
- });
-
- public setName(name: string): this;
- public setAvatar(image: string): this;
- public setTitle(title: string): this;
- public setColor(color: string): this;
- public setMessage(message: string): this;
- public setBackground(background: string): this;
-
- public build(): Promise;
-}
diff --git a/build/index.js b/build/index.js
deleted file mode 100644
index 278746b..0000000
--- a/build/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const { welcomeCard } = require("./structures/welcomeCard");
-
-module.exports = { welcomeCard }
\ No newline at end of file
diff --git a/build/structures/font/Montserrat-Black.ttf b/build/structures/font/Montserrat-Black.ttf
deleted file mode 100644
index 7af9fb4..0000000
Binary files a/build/structures/font/Montserrat-Black.ttf and /dev/null differ
diff --git a/build/structures/font/Montserrat-ExtraLight.ttf b/build/structures/font/Montserrat-ExtraLight.ttf
deleted file mode 100644
index 8aa56c1..0000000
Binary files a/build/structures/font/Montserrat-ExtraLight.ttf and /dev/null differ
diff --git a/build/structures/welcomeCard.js b/build/structures/welcomeCard.js
deleted file mode 100644
index bc5874b..0000000
--- a/build/structures/welcomeCard.js
+++ /dev/null
@@ -1,159 +0,0 @@
-const { createCanvas, loadImage, GlobalFonts } = require("@napi-rs/canvas");
-
-// GlobalFonts.registerFromPath("build/structures/font/Montserrat-Black.ttf", "montserrat-black")
-// GlobalFonts.registerFromPath("build/structures/font/Montserrat-ExtraLight.ttf", "montserrat-extra-light")
-
-GlobalFonts.registerFromPath("node_modules/greetify/build/structures/font/Montserrat-Black.ttf", "montserrat-black")
-GlobalFonts.registerFromPath("node_modules/greetify/build/structures/font/Montserrat-ExtraLight.ttf", "montserrat-extra-light")
-
-const defaultAssets = {
- background: "https://s6.imgcdn.dev/ZqH2S.png",
- shadow: "https://s6.imgcdn.dev/Zqmpi.png",
- gradient: "https://s6.imgcdn.dev/ZqFsH.png"
-}
-
-class welcomeCard {
- constructor(options) {
- this.username = options?.username;
- this.avatar = options?.avatar;
- this.title = options?.title;
- this.color = options?.color;
- this.message = options?.message;
- this.background = options?.background;
- }
-
- setName(name) {
- this.username = name;
- return this;
- }
-
- setAvatar(image) {
- this.avatar = image;
- return this;
- }
-
- setTitle(title) {
- this.title = title;
- return this;
- }
-
- setColor(color) {
- this.color = color;
- return this;
- }
-
- setMessage(message) {
- this.message = message;
- return this;
- }
-
- setBackground(background) {
- this.background = background
- return this;
- }
-
- async build() {
- if (!this.username) throw new Error("Provide username to display on card");
- if (!this.avatar) throw new Error("Provide valid avatar url of user");
- if (!this.title) this.setTitle("WELCOME");
- if (!this.color) this.setColor("00FF38")
- if (!this.message) throw new Error("Provide message to display on card");
- if (!this.background) this.setBackground(defaultAssets.background)
-
- if(this.username.length >= 16) {
- throw new Error(`The username is too long to display on card [less than equal to 15]`);
- }
-
- if(this.title.length >= 16) {
- throw new Error(`The title is too long to display on card [less than equal to 15]`);
- }
-
- if (this.message.length >= 36) {
- throw new Error(`The message is too long to display on card [less than equal to 35]`);
- }
-
- const canvasWidth = 1280;
- const canvasHeight = 720;
-
- const centerX = canvasWidth / 2;
- const centerY = canvasHeight / 2;
-
- const canvas = createCanvas(canvasWidth, canvasHeight);
- const ctx = canvas.getContext("2d");
-
- // BACKGROUND
- await loadImage(this.background).then(async (image) => {
- const scale = Math.max(canvasWidth / image.width, canvasHeight / image.height);
-
- const imageWidth = image.width * scale;
- const imageHeight = image.height * scale;
- const imageX = (canvasWidth - imageWidth) / 2;
- const imageY = (canvasHeight - imageHeight) / 2;
-
- ctx.drawImage(image, imageX, imageY, imageWidth, imageHeight);
-
- // ADD GRADIENT EFFECT
- await loadImage(defaultAssets.gradient).then((image) => {
- ctx.drawImage(image, imageX, imageY, imageWidth, imageHeight);
- })
-
- const svgString = `
-
-`;
-
- // Create a data URI from the SVG string
- const dataUri = `data:image/svg+xml;base64,${Buffer.from(svgString).toString('base64')}`;
-
- await loadImage(dataUri).then((image) => {
- ctx.drawImage(image, 0, 0, 1280, 538);
- })
- });
-
- // NAME OF USER
- ctx.fillStyle = `#${this.color}`
- ctx.font = `91px montserrat-black`
- ctx.textAlign = 'center';
- ctx.fillText(`${this.username}`.toUpperCase(), centerX, centerY + 30)
-
- const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
- gradient.addColorStop(0, '#ffffff');
- gradient.addColorStop(0.5, '#ffffff');
- gradient.addColorStop(1, '#494949');
-
- ctx.fillStyle = gradient
- ctx.font = `76px montserrat-black`
- ctx.textAlign = 'center';
- ctx.fillText(`${this.title}`.toUpperCase(), centerX, centerY + 100)
-
- ctx.fillStyle = gradient
- ctx.font = `41px montserrat-extra-light`
- ctx.textAlign = 'center';
- ctx.fillText(`${this.message}`.toUpperCase(), centerX, centerY + 250);
-
- // SHADOW OF AVATAR (FIRST)
- await loadImage(defaultAssets.shadow).then((image) => {
- ctx.drawImage(image, 466, 48, 348, 348);
- });
-
- // AVATAR OF USER
- await loadImage(this.avatar).then((image) => {
- ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
- ctx.shadowBlur = 10;
- ctx.shadowOffsetX = 509
- ctx.shadowOffsetY = 92
-
- ctx.beginPath();
- ctx.arc(510 + 130, 92 + 130, 130, 0, Math.PI * 2);
- ctx.closePath();
- ctx.clip();
-
- ctx.drawImage(image, 510, 92, 260, 260);
- })
-
- return canvas.toBuffer("image/png");
- }
-}
-
-module.exports = { welcomeCard }
\ No newline at end of file
diff --git a/example/card.png b/example/card.png
deleted file mode 100644
index fd42e66..0000000
Binary files a/example/card.png and /dev/null differ
diff --git a/example/index.js b/example/index.js
deleted file mode 100644
index 7fc7258..0000000
--- a/example/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-(async () => {
- // Importing modules
- const { welcomeCard } = require("greetify");
- const fs = require("fs")
-
- // Card details here
- const card = new welcomeCard()
- .setName("FlameFace")
- .setAvatar("https://s6.imgcdn.dev/ZFQlq.png")
- .setMessage("YOU ARE 688 MEMBER")
- .setBackground("https://s6.imgcdn.dev/ZqH2S.png")
- .setColor("00FF38") // without #
- .setTitle("Welcome")
-
- // Building process
- const output = await card.build();
-
- // Save as image
- fs.writeFileSync("card.png", output);
- console.log("Done");
-})()
\ No newline at end of file
diff --git a/fonts/PlusJakartaSans-Bold.ttf b/fonts/PlusJakartaSans-Bold.ttf
new file mode 100644
index 0000000..386d3a6
Binary files /dev/null and b/fonts/PlusJakartaSans-Bold.ttf differ
diff --git a/fonts/PlusJakartaSans-ExtraBold.ttf b/fonts/PlusJakartaSans-ExtraBold.ttf
new file mode 100644
index 0000000..a67cafd
Binary files /dev/null and b/fonts/PlusJakartaSans-ExtraBold.ttf differ
diff --git a/fonts/PlusJakartaSans-ExtraLight.ttf b/fonts/PlusJakartaSans-ExtraLight.ttf
new file mode 100644
index 0000000..bb43929
Binary files /dev/null and b/fonts/PlusJakartaSans-ExtraLight.ttf differ
diff --git a/fonts/PlusJakartaSans-Light.ttf b/fonts/PlusJakartaSans-Light.ttf
new file mode 100644
index 0000000..215db16
Binary files /dev/null and b/fonts/PlusJakartaSans-Light.ttf differ
diff --git a/fonts/PlusJakartaSans-Medium.ttf b/fonts/PlusJakartaSans-Medium.ttf
new file mode 100644
index 0000000..1e58066
Binary files /dev/null and b/fonts/PlusJakartaSans-Medium.ttf differ
diff --git a/fonts/PlusJakartaSans-Regular.ttf b/fonts/PlusJakartaSans-Regular.ttf
new file mode 100644
index 0000000..1e77059
Binary files /dev/null and b/fonts/PlusJakartaSans-Regular.ttf differ
diff --git a/fonts/PlusJakartaSans-SemiBold.ttf b/fonts/PlusJakartaSans-SemiBold.ttf
new file mode 100644
index 0000000..49817ef
Binary files /dev/null and b/fonts/PlusJakartaSans-SemiBold.ttf differ
diff --git a/package.json b/package.json
index 81883d2..9724012 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,28 @@
{
"name": "greetify",
- "description": "Greetify is futuristic welcome card canvas library",
- "version": "1.0.1",
- "main": "build/index.js",
- "types": "build/index.d.ts",
+ "version": "2.0.0",
+ "description": "Futuristic welcome card canvas library",
+ "main": "./dist/index.js",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.ts",
+ "exports": {
+ ".": {
+ "require": "./dist/index.js",
+ "import": "./dist/index.mjs",
+ "types": "./dist/index.d.ts"
+ }
+ },
"files": [
- "build"
+ "dist",
+ "fonts"
],
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "build": "tsup",
+ "build:watch": "tsup --watch",
+ "deploy": "npm publish",
+ "deploy:beta": "npm publish --tag beta",
+ "test:m": "cd tests && node index.mjs",
+ "test:c": "cd tests && node --watch index.js"
},
"keywords": [
"welcome-card",
@@ -19,24 +33,22 @@
"discord-canvas",
"discord.js"
],
- "dependencies": {
- "@napi-rs/canvas": "^0.1.44"
- },
+ "author": "flameface",
+ "license": "GPL-3.0-only",
"devDependencies": {
- "@types/node": "^20.4.5",
- "typescript": "^5.1.6"
+ "@types/node": "^20.11.28",
+ "tsup": "^8.0.2",
+ "typescript": "^5.4.2"
},
- "license": "GPL-3.0",
- "author": "FlameFace",
"repository": {
"type": "git",
- "url": "https://github.com/burnxpofficial/greetify.git"
+ "url": "https://github.com/unburn/greetify.git"
},
"bugs": {
- "url": "https://github.com/burnxpofficial/greetify/issues"
+ "url": "https://github.com/unburn/greetify/issues"
},
- "funding": {
- "type": "githubsponser",
- "url": "https://github.com/sponsors/flameface"
+ "dependencies": {
+ "@napi-rs/canvas": "^0.1.51",
+ "cropify": "latest"
}
}
\ No newline at end of file
diff --git a/src/functions/generateSvg.ts b/src/functions/generateSvg.ts
new file mode 100644
index 0000000..475948c
--- /dev/null
+++ b/src/functions/generateSvg.ts
@@ -0,0 +1,5 @@
+const generateSvg = (svgContent: string) => {
+ return `data:image/svg+xml;base64,${Buffer.from(svgContent).toString('base64')}`;
+}
+
+export { generateSvg }
diff --git a/src/functions/registerFont.ts b/src/functions/registerFont.ts
new file mode 100644
index 0000000..76b08c4
--- /dev/null
+++ b/src/functions/registerFont.ts
@@ -0,0 +1,19 @@
+import { GlobalFonts } from "@napi-rs/canvas";
+import path from "path";
+import fs from "fs";
+
+function registerFont(fontPath: string, fontName: string) {
+ const rootFontsPath = path.join(__dirname, "../fonts", fontPath);
+ if (fs.existsSync(rootFontsPath)) {
+ GlobalFonts.registerFromPath(rootFontsPath, fontName);
+ } else {
+ const srcFontsPath = path.join(__dirname, "../fonts", fontPath);
+ if (fs.existsSync(srcFontsPath)) {
+ GlobalFonts.registerFromPath(srcFontsPath, fontName);
+ } else {
+ throw new Error(`Font file not found at ${rootFontsPath} or ${srcFontsPath}`);
+ }
+ }
+}
+
+export { registerFont };
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..891da42
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,3 @@
+export * from "./themes/minimal"
+export * from "./themes/panorama"
+export * from "./typings/types"
\ No newline at end of file
diff --git a/src/themes/minimal.ts b/src/themes/minimal.ts
new file mode 100644
index 0000000..588c394
--- /dev/null
+++ b/src/themes/minimal.ts
@@ -0,0 +1,83 @@
+import { createCanvas, loadImage } from "@napi-rs/canvas"
+import { cropImage } from "cropify"
+import { registerFont } from "../functions/registerFont";
+import { minimalType } from "../typings/types";
+
+registerFont("PlusJakartaSans-Bold.ttf", "pjs-bold")
+registerFont("PlusJakartaSans-ExtraBold.ttf", "pjs-ebold")
+registerFont("PlusJakartaSans-ExtraLight.ttf", "pjs-elight")
+registerFont("PlusJakartaSans-Light.ttf", "pjs-light")
+registerFont("PlusJakartaSans-Medium.ttf", "pjs-medium")
+registerFont("PlusJakartaSans-Regular.ttf", "pjs-regular")
+registerFont("PlusJakartaSans-SemiBold.ttf", "pjs-sbold")
+
+const Minimal = async (option: minimalType) => {
+ if (!option.backgroundImage) {
+ option.backgroundImage = "https://ik.imagekit.io/unburn/greetify-default.png"
+ }
+
+ if (!option.name) throw new Error("Invalid parameters: missing name paramter")
+ if (!option.nameColor) option.nameColor = "#00FF9E"
+ if (!option.message) throw new Error("Invalid parameters: missing message paramter")
+ if (!option.messageColor) option.messageColor = "#FFFFFF"
+ if (!option.type) option.type = "WELCOME"
+ if (!option.typeColor) option.typeColor = "#FFFFFF"
+ if (!option.circleBorder) option.circleBorder = false
+
+ if (option.name.length > 13) {
+ option.name = option.name.slice(0, 13) + ".."
+ }
+
+ if (option.type.length > 22) {
+ option.type = option.type.slice(0, 22) + ".."
+ }
+
+ if (option.message.length > 30) {
+ option.message = option.message.slice(0, 30) + ".."
+ }
+
+ const canvas = createCanvas(1280, 720)
+ const ctx = canvas.getContext("2d")
+
+ const centerX = 1280 / 2;
+
+ const background = await cropImage({
+ imagePath: option.backgroundImage,
+ borderRadius: 100,
+ cropCenter: true,
+ width: 1280,
+ height: 720
+ })
+
+ ctx.drawImage(await loadImage(background), 0, 0)
+
+ const avatar = await cropImage({
+ imagePath: option.avatar,
+ circle: option.circleBorder ? true : false,
+ borderRadius: 100,
+ cropCenter: true,
+ width: 270,
+ height: 270
+ })
+
+ ctx.drawImage(await loadImage(avatar), 505, 56)
+
+ ctx.fillStyle = option.nameColor
+ ctx.font = "100px pjs-ebold"
+ ctx.textAlign = 'center';
+ ctx.fillText(option.name.toUpperCase(), centerX, 440)
+
+ ctx.fillStyle = option.typeColor
+ ctx.font = "65px pjs-bold"
+ ctx.textAlign = 'center';
+ ctx.fillText(option.type.toUpperCase(), centerX, 530)
+
+ ctx.fillStyle = option.messageColor
+ ctx.font = "40px pjs-light"
+ ctx.textAlign = 'center';
+ ctx.fillText(option.message.toUpperCase(), centerX, 655)
+
+ return canvas.toBuffer("image/png")
+}
+
+export { Minimal }
\ No newline at end of file
diff --git a/src/themes/panorama.ts b/src/themes/panorama.ts
new file mode 100644
index 0000000..ae5fc40
--- /dev/null
+++ b/src/themes/panorama.ts
@@ -0,0 +1,70 @@
+import { createCanvas, loadImage } from "@napi-rs/canvas"
+import { cropImage } from "cropify"
+import { registerFont } from "../functions/registerFont";
+import { panoramaType } from "../typings/types";
+
+registerFont("PlusJakartaSans-Bold.ttf", "pjs-bold")
+registerFont("PlusJakartaSans-ExtraBold.ttf", "pjs-ebold")
+registerFont("PlusJakartaSans-ExtraLight.ttf", "pjs-elight")
+registerFont("PlusJakartaSans-Light.ttf", "pjs-light")
+registerFont("PlusJakartaSans-Medium.ttf", "pjs-medium")
+registerFont("PlusJakartaSans-Regular.ttf", "pjs-regular")
+registerFont("PlusJakartaSans-SemiBold.ttf", "pjs-sbold")
+
+const Panorama = async (option: panoramaType) => {
+ if (!option.backgroundImage) {
+ option.backgroundImage = "https://ik.imagekit.io/unburn/greeti`fy-default.png"
+ }
+
+ if (!option.name) throw new Error("Invalid parameters: missing name paramter")
+ if (!option.nameColor) option.nameColor = "#00FF9E"
+ if (!option.type) option.type = "WELCOME"
+ if (!option.typeColor) option.typeColor = "#FFFFFF"
+ if (!option.circleBorder) option.circleBorder = false
+
+ if (option.name.length > 13) {
+ option.name = option.name.slice(0, 13) + ".."
+ }
+
+ if (option.type.length > 15) {
+ option.type = option.type.slice(0, 15) + ".."
+ }
+
+ const canvas = createCanvas(1280, 410)
+ const ctx = canvas.getContext("2d")
+
+ const background = await cropImage({
+ imagePath: option.backgroundImage,
+ borderRadius: 100,
+ cropCenter: true,
+ width: 1280,
+ height: 410
+ })
+
+ ctx.drawImage(await loadImage(background), 0, 0)
+
+ const avatar = await cropImage({
+ imagePath: option.avatar,
+ borderRadius: 100,
+ circle: option.circleBorder ? true : false,
+ cropCenter: true,
+ width: 290,
+ height: 290
+ })
+
+ const centerY = 410 / 2
+
+ ctx.drawImage(await loadImage(avatar), 90, 60)
+
+ ctx.fillStyle = option.nameColor
+ ctx.font = "80px pjs-ebold"
+ ctx.fillText(option.name.toUpperCase(), 420, centerY + 75)
+
+ ctx.fillStyle = option.typeColor
+ ctx.font = "65px pjs-light"
+ ctx.fillText(option.type.toUpperCase(), 420, centerY - 25)
+
+ return canvas.toBuffer("image/png")
+}
+
+export { Panorama }
\ No newline at end of file
diff --git a/src/typings/types.ts b/src/typings/types.ts
new file mode 100644
index 0000000..38d8f43
--- /dev/null
+++ b/src/typings/types.ts
@@ -0,0 +1,21 @@
+export type minimalType = {
+ backgroundImage?: string;
+ avatar: string;
+ name: string;
+ nameColor?: string;
+ message: string;
+ messageColor?: string;
+ type?: string;
+ typeColor?: string;
+ circleBorder?: boolean;
+}
+
+export type panoramaType = {
+ backgroundImage?: string;
+ avatar: string;
+ name: string;
+ nameColor?: string;
+ type?: string;
+ typeColor?: string;
+ circleBorder?: boolean;
+}
\ No newline at end of file
diff --git a/tests/greetify.png b/tests/greetify.png
new file mode 100644
index 0000000..f1979c8
Binary files /dev/null and b/tests/greetify.png differ
diff --git a/tests/index.js b/tests/index.js
new file mode 100644
index 0000000..c674cbf
--- /dev/null
+++ b/tests/index.js
@@ -0,0 +1,8 @@
+const { Minimal } = require("../dist/index");
+const fs = require('fs')
+
+Minimal({
+
+}).then(x => {
+ fs.writeFileSync("greetify.png", x)
+})
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..309c0ae
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "ES2016",
+ "module": "CommonJS",
+ "esModuleInterop": true,
+ "strict": true,
+ "outDir": "dist",
+ "declaration": true,
+ "noImplicitAny": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ },
+ "include": [
+ "src"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/tsup.config.ts b/tsup.config.ts
new file mode 100644
index 0000000..042915f
--- /dev/null
+++ b/tsup.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsup';
+
+export default defineConfig({
+ format: ['cjs', 'esm'],
+ entry: ['./src/index.ts'],
+ dts: true,
+ shims: true,
+ skipNodeModulesBundle: true,
+ clean: ['./src/index.ts']
+});
\ No newline at end of file