Canvacord
Easily generate images on-the-fly with node.js using wide range of templates.
Documentation
https://canvacord.js.org
Features
- image generation (wip)
- image manipulation (wip)
- image templates (wip)
- image filters (wip)
- complex layouts (wip)
- templates api (wip)
- builder api (wip)
Example
Image Generation
Using built-in templates (New "Legacy api")
import { canvacord } from 'canvacord';
import fs from 'node:fs';
const triggered = await canvacord.triggered(image);
triggered.pipe(fs.createWriteStream('triggered.gif'));
const beautiful = await canvacord.beautiful(img);
const facepalm = await canvacord.facepalm(img);
const filtered = await canvacord
.filters(512, 512)
.drawImage(image)
.hueRotate(90)
.invert(2)
.sepia(1)
.opacity(0.5)
.saturate(2)
.encode();
const filtered = await canvacord(image, 512, 512)
.hueRotate(90)
.invert(2)
.sepia(1)
.opacity(0.5)
.saturate(2)
.encode();
fs.writeFileSync('filtered.png', filtered);
XP Card
import { Font, RankCardBuilder } from "canvacord";
import { writeFile } from "fs/promises";
Font.loadDefault();
const card = new RankCardBuilder()
.setUsername("Lost Ctrl")
.setDisplayName("thearchaeopteryx")
.setAvatar("...")
.setCurrentXP(3800)
.setRequiredXP(2500)
.setLevel(54)
.setRank(32)
.setStatus("online");
const image = await card.build({
format: "png",
});
await writeFileSync("./card.png", data);
Creating images using custom template
import {
createTemplate,
ImageFactory,
TemplateImage,
createImageGenerator,
} from "canvacord";
const AffectedMeme = createTemplate((image: ImageSource) => {
return {
steps: [
{
image: [
{
source: new TemplateImage(ImageFactory.AFFECT),
x: 0,
y: 0,
},
],
},
{
image: [
{
source: new TemplateImage(image),
x: 180,
y: 383,
width: 200,
height: 157,
},
],
},
],
};
});
const photo = await getPhotoForMemeSomehow();
const generator = createImageGenerator(AffectedMeme(photo));
await generator.render();
const affectedMeme = await generator.encode("png");
Result
Creating images using custom builder
This is an advanced method of creating images. Canvacord builder api allows you to create your own image generator using JSX elements and a subset of tailwind class names. This is also possible without JSX, you can find an example here.
Note
It does not support many css features such as grid layout. You can use flexbox instead.
If you want to use JSX with typescript, you need to add the following options to your tsconfig.json
:
{
"compilerOptions": {
// other options
"jsx": "react",
"jsxFactory": "JSX.createElement",
"jsxFragmentFactory": "JSX.Fragment"
}
// other options
}
You can also use pragma comments to define JSX factory and fragment factory:
import { JSX, Builder, Font } from "canvacord";
import { writeFile } from "fs/promises";
interface Props {
text: string;
}
class Design extends Builder<Props> {
constructor() {
super(500, 500);
this.bootstrap({ text: "" });
}
setText(text: string) {
this.options.set("text", text);
return this;
}
async render() {
return (
<div className="flex items-center justify-center h-full w-full bg-teal-500">
<h1 className="text-white font-bold text-7xl">
{this.options.get("text")}
</h1>
</div>
);
}
}
Font.loadDefault();
const design = new Design().setText("Hello World");
const image = await design.build({ format: "png" });
await writeFile("./test.png", image);
Result