import { CollageModes } from "../src/common/collages.ts"; import { init, CanvasRenderingContext2D, EmulatedCanvas2D, Image, } from "https://deno.land/x/canvas@v1.3.0/mod.ts"; import { CollageImage } from "../src/common/types.ts"; const canvasKit = await init(); export class ProxyImage implements CollageImage { private filepath: string | null; private _image: Image | undefined; constructor(input: string | Image) { if (typeof input === "string") { this.filepath = input; } else { this.filepath = null; this._image = input; } } public get path(): string | null { return this.filepath; } public get image(): Image { if (!this._image) { const image = canvasKit.MakeImageFromEncoded( Deno.readFileSync(this.filepath!) ); if (!image) { throw Error(`Failed loading ${this.filepath}!`); } this._image = image; } return this._image; } public get width(): number { return this.image.width(); } public get height(): number { return this.image.height(); } } declare module "https://deno.land/x/canvas@v1.3.0/mod.ts" { interface HTMLCanvasElement { width: number; height: number; getContext(x: "2d"): CanvasRenderingContext2D; } } export class DenoCollageModes extends CollageModes< CanvasRenderingContext2D, ProxyImage, EmulatedCanvas2D > { createCanvas(w: number, h: number): EmulatedCanvas2D { const canvas = canvasKit.MakeCanvas(Math.round(w), Math.round(h)); if (!canvas) { throw Error("Error initializing canvas."); } return canvas; } canvasToImage(canvas: EmulatedCanvas2D): PromiseLike { const image = canvasKit.MakeImageFromEncoded(canvas.toBuffer()); if (!image) { throw Error("Something went wrong converting canvas to image."); } return Promise.resolve(new ProxyImage(image)); } drawImage( ctx: CanvasRenderingContext2D, image: ProxyImage, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number ): void { ctx.drawImage(image.image, sx, sy, sw, sh, dx, dy, dw, dh); } fillText( ctx: CanvasRenderingContext2D, text: string, fontSize: number, x: number, y: number, maxWidth: number ): void { ctx.globalCompositeOperation = "difference"; ctx.fillStyle = "white"; ctx.font = `bold ${fontSize}px sans-serif`; ctx.fillText(text, x, y, maxWidth); } } export const denoCollageModes = new DenoCollageModes();