File

src/layer/Layer.ts

Index

Properties

Properties

coordinates
coordinates: literal type
Type : literal type
Optional
height
height: number
Type : number
Optional
width
width: number
Type : number
Optional
import { Canvas, createCanvas, SKRSContext2D } from "@napi-rs/canvas";
import { ToolBox } from "../toolbox/base/ToolBox";
import { LayerManager } from "./LayerManager";
import { LayerTools } from "./LayerTools";
import { LayerUtils } from "./LayerUtils";

export type LayerToolHistory = Array<(ctx: SKRSContext2D) => Promise<void> | void>[];

export interface LayerTransformationData {
    coordinates?: {
        x: number;
        y: number;
    };
    height?: number;
    width?: number;
}

export class Layer {
    public canvas: Canvas;
    public ctx: SKRSContext2D;
    #locked = false;
    #hidden = false;
    #toolHistory: LayerToolHistory = [];
    public utils: LayerUtils;
    public tools = new LayerTools(this);
    public coordinates = {
        x: 0,
        y: 0
    };
    public width: number;
    public height: number;

    public constructor(
        public readonly manager: LayerManager,
        public readonly id: number,
        options?: {
            width?: number;
            height?: number;
        }
    ) {
        this.height = options?.height ?? this.manager.illustrator.height;
        this.width = options?.width ?? this.manager.illustrator.width;
        this.canvas = createCanvas(this.width, this.height);
        this.ctx = this.canvas.getContext("2d");
        this.utils = new LayerUtils(this.ctx);
    }

    public get name() {
        return this.manager.resolve(this)?.name as string;
    }

    public get illustrator() {
        return this.manager.illustrator;
    }

    public get context() {
        return this.ctx;
    }

    public get position() {
        return this.manager.getLayerPosition(this);
    }

    public setPosition(position: number) {
        return this.manager.setLayerPosition(this, position);
    }

    public createTransformation(data: LayerTransformationData) {
        if (data.coordinates) this.coordinates = data.coordinates;
        if (data.width) this.width = data.width;
        if (data.height) this.height = data.height;
    }

    public get locked() {
        return this.#locked;
    }

    public isLocked() {
        return this.locked;
    }

    public lock() {
        this.#locked = true;
        return this;
    }

    public unlock() {
        this.#locked = false;
        return this;
    }

    public isHidden() {
        return this.hidden;
    }

    public get hidden() {
        return this.#hidden;
    }

    public hide() {
        this.#hidden = true;
        return this;
    }

    public show() {
        this.#hidden = false;
        return this;
    }

    public save() {
        this.ctx.save();
    }

    public restore() {
        this.ctx.restore();
    }

    public duplicate(name = `${this.name} Copy`) {
        return this.manager.duplicateLayer(this, this.#toolHistory, {
            name,
            config: {
                height: this.height,
                width: this.width
            },
            position: this.position + 1
        });
    }

    public applyTool(tool: ToolBox) {
        this.#throwIfLocked();
        if (!(tool instanceof ToolBox)) throw new Error("tool must be a ToolBox instance");
        this.#toolHistory.push(tool.history);
    }

    public setHistory(history: LayerToolHistory) {
        this.#toolHistory = history;
    }

    #throwIfLocked() {
        if (this.#locked) throw new Error("Cannot perform operations on locked layer");
    }

    public async render() {
        if (this.#hidden) return null;
        await Promise.all(this.#toolHistory.flat(2).map((m) => m(this.ctx)));
        return this.canvas;
    }
}

results matching ""

    No results matching ""