Tomáš Mládek
33603eabff
also use module augmentation to simplify types and all TODO: make web app also use the same recursive code
98 lines
2.2 KiB
TypeScript
98 lines
2.2 KiB
TypeScript
import { CollageModes } from "../src/common/collages.ts";
|
|
import {
|
|
CanvasRenderingContext2D,
|
|
EmulatedCanvas2D,
|
|
Image,
|
|
} from "https://deno.land/x/canvas/mod.ts";
|
|
import {
|
|
CollageImage,
|
|
} from "../src/common/types.ts";
|
|
import { init } from "https://deno.land/x/canvas@v1.3.0/mod.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 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/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<ProxyImage> {
|
|
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);
|
|
}
|
|
}
|
|
|
|
export const denoCollageModes = new DenoCollageModes();
|