Package Exports
- canvacord
- canvacord/dist/index.js
- canvacord/dist/index.mjs
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (canvacord) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Canvacord
Easily generate images on-the-fly with node.js using wide range of templates.
Documentation
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';
// triggered gif
const triggered = await canvacord.triggered(image);
triggered.pipe(fs.createWriteStream('triggered.gif'));
// image generation
const beautiful = await canvacord.beautiful(img);
const facepalm = await canvacord.facepalm(img);
// filters
const filtered = await canvacord
.filters(512, 512)
.drawImage(image)
.hueRotate(90)
.invert(2)
.sepia(1)
.opacity(0.5)
.saturate(2)
.encode();
// alternative syntax
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";
// load default font
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,
},
],
},
],
};
});
// get target photo to use on "affected" meme image
const photo = await getPhotoForMemeSomehow();
const generator = createImageGenerator(AffectedMeme(photo));
// render out the image
await generator.render();
// get the resulting image in png format
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:
/** @jsx JSX.createElement */
/** @jsxFrag JSX.Fragment */// JSX import is required if you want to use JSX syntax
// Builder is a base class to create your own builders
// Font is a utility class to load fonts
import { JSX, Builder, Font } from "canvacord";
import { writeFile } from "fs/promises";
// declare props types
interface Props {
text: string;
}
class Design extends Builder<Props> {
constructor() {
// set width and height
super(500, 500);
// initialize props
this.bootstrap({ text: "" });
}
// define custom methods for your builder
setText(text: string) {
this.options.set("text", text);
return this;
}
// this is where you have to define how the resulting image should look like
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>
);
}
}
// usage
// load font
Font.loadDefault();
// create design
const design = new Design().setText("Hello World");
const image = await design.build({ format: "png" });
// do something with generated image
await writeFile("./test.png", image);