@nmmty/lazycanvas
Version:
A simple way to interact with @napi-rs/canvas in an advanced way!
110 lines (109 loc) • 4.77 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RenderManager = void 0;
const enum_1 = require("../../types/enum");
const Group_1 = require("../components/Group");
const LazyUtil_1 = require("../../utils/LazyUtil");
// @ts-ignore
const gifenc_1 = require("gifenc");
class RenderManager {
lazyCanvas;
debug;
constructor(lazyCanvas, debug = false) {
this.lazyCanvas = lazyCanvas;
this.debug = debug;
}
async renderLayer(layer) {
if (this.debug)
LazyUtil_1.LazyLog.log('info', `Rendering ${layer.id}...\nData:`, layer.toJSON());
if (layer.visible) {
if (layer instanceof Group_1.Group) {
for (const subLayer of layer.components) {
if (subLayer.visible) {
if ('globalComposite' in subLayer.props && subLayer.props.globalComposite)
this.lazyCanvas.ctx.globalCompositeOperation = subLayer.props.globalComposite;
else
this.lazyCanvas.ctx.globalCompositeOperation = 'source-over';
await subLayer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas, this.lazyCanvas.layers, this.debug);
}
}
}
else {
if ('globalComposite' in layer.props && layer.props.globalComposite)
this.lazyCanvas.ctx.globalCompositeOperation = layer.props.globalComposite;
else
this.lazyCanvas.ctx.globalCompositeOperation = 'source-over';
await layer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas, this.lazyCanvas.layers, this.debug);
}
this.lazyCanvas.ctx.shadowColor = 'transparent';
}
return this.lazyCanvas.ctx;
}
async renderStatic(exportType) {
if (this.debug)
LazyUtil_1.LazyLog.log('info', `Rendering static...`);
for (const layer of this.lazyCanvas.layers.toArray()) {
await this.renderLayer(layer);
}
switch (exportType) {
case enum_1.Export.Buffer:
case "buffer":
return this.lazyCanvas.canvas.toBuffer('image/png');
case enum_1.Export.CTX:
case "ctx":
return this.lazyCanvas.ctx;
case enum_1.Export.SVG:
case "svg":
// @ts-ignore
return this.lazyCanvas.canvas.getContent().toString('utf8');
default:
return this.lazyCanvas.canvas.toBuffer('image/png');
}
}
async renderAnimation() {
const encoder = new gifenc_1.GIFEncoder();
if (this.debug)
LazyUtil_1.LazyLog.log('info', `Rendering animation...\nData:`, this.lazyCanvas.animation.opts);
for (const layer of this.lazyCanvas.layers.toArray()) {
const ctx = await this.renderLayer(layer);
let { data, width, height } = ctx.getImageData(0, 0, this.lazyCanvas.width, this.lazyCanvas.height);
const palette = (0, gifenc_1.quantize)(data, this.lazyCanvas.animation.opts.maxColors, { format: this.lazyCanvas.animation.opts.colorSpace });
const index = (0, gifenc_1.applyPalette)(data, palette, this.lazyCanvas.animation.opts.colorSpace);
encoder.writeFrame(index, width, height, {
palette,
transparent: this.lazyCanvas.animation.opts.transparency,
delay: 1000 / this.lazyCanvas.animation.opts.frameRate,
loop: this.lazyCanvas.animation.opts.loop
});
if (this.lazyCanvas.animation.opts.clear)
ctx.clearRect(0, 0, this.lazyCanvas.width, this.lazyCanvas.height);
}
encoder.finish();
return encoder.bytesView();
}
/**
* This will render all the layers and return the rendered canvas buffer or ctx.
* @returns {Promise<Buffer | SKRSContext2D>}
*/
async render() {
switch (this.lazyCanvas.exportType) {
case enum_1.Export.Buffer:
case "buffer":
if (this.lazyCanvas.animation.animated) {
return await this.renderAnimation();
}
else {
return await this.renderStatic(enum_1.Export.Buffer);
}
case enum_1.Export.CTX:
case "ctx":
return this.lazyCanvas.ctx;
case enum_1.Export.SVG:
case "svg":
return this.renderStatic(enum_1.Export.SVG);
default:
return this.renderStatic(enum_1.Export.Buffer);
}
}
}
exports.RenderManager = RenderManager;