@nmmty/lazycanvas
Version:
A simple way to interact with @napi-rs/canvas in an advanced way!
294 lines (293 loc) • 9.64 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Path2DLayer = void 0;
const canvas_1 = require("@napi-rs/canvas");
const types_1 = require("../../types");
const utils_1 = require("../../utils/utils");
const BaseLayer_1 = require("./BaseLayer");
const LazyUtil_1 = require("../../utils/LazyUtil");
class Path2DLayer extends BaseLayer_1.BaseLayer {
id;
type = types_1.LayerType.Path;
zIndex;
visible;
props;
constructor(props, misc) {
super(types_1.LayerType.Path, props || {}, misc);
this.id = misc?.id || (0, utils_1.generateID)(types_1.LayerType.Path);
this.zIndex = misc?.zIndex || 1;
this.visible = misc?.visible || true;
this.props = props ? props : {};
}
/**
* Sets the unique identifier of the layer.
*
* @param {string} id - The unique identifier.
* @returns {this} The current instance for chaining.
*/
setID(id) {
this.id = id;
return this;
}
/**
* Sets the visibility of the layer.
* @param visible {boolean} - The visibility state of the layer.
* @returns {this} The current instance for chaining.
*/
setVisible(visible) {
this.visible = visible;
return this;
}
/**
* Sets the z-index of the layer.
* @param zIndex {number} - The z-index value of the layer.
* @returns {this} The current instance for chaining.
*/
setZIndex(zIndex) {
this.zIndex = zIndex;
return this;
}
/**
* Sets the global composite operation for the layer.
* @param {AnyGlobalCompositeOperation} operation - The composite operation.
* @returns {this} The current instance for chaining.
*/
setGlobalCompositeOperation(operation) {
this.props.globalComposite = operation;
return this;
}
/**
* Sets the filter effects for the layer.
* @param {...AnyFilter} filter - The filter effects to apply.
* @returns {this} The current instance for chaining.
*/
setFilters(...filter) {
this.props.filter = filter.join(' ');
return this;
}
/**
* Sets the transformation matrix of the layer.
* @param {DOMMatrix2DInit} matrix - The transformation matrix.
* @returns {this} The current instance for chaining.
*/
setMatrix(matrix) {
this.props.transform = { ...this.props.transform, matrix };
return this;
}
/**
* Sets the scale of the layer in the x and y directions.
* @param {number} x - The scale factor in the x direction.
* @param {number} y - The scale factor in the y direction.
* @returns {this} The current instance for chaining.
*/
setScale(x, y) {
this.props.transform = { ...this.props.transform, scale: { x, y } };
return this;
}
/**
* Sets the translation of the layer in the x and y directions.
* @param {number} x - The translation in the x direction.
* @param {number} y - The translation in the y direction.
* @returns {this} The current instance for chaining.
*/
setTranslate(x, y) {
this.props.transform = { ...this.props.transform, translate: { x, y } };
return this;
}
/**
* Sets the opacity of the layer.
* @param {number} opacity - The opacity value, between 0 and 1.
* @returns {this} The current instance for chaining.
*/
setOpacity(opacity) {
this.props.opacity = opacity;
return this;
}
/**
* Sets the stroke properties of the Path2D Layer.
* @param width {number} - The width of the stroke.
* @param cap {string} - The cap style of the stroke.
* @param join {string} - The join style of the stroke.
* @param dash {number[]} - The dash pattern of the stroke.
* @param dashOffset {number} - The dash offset of the stroke.
* @param miterLimit {number} - The miter limit of the stroke.
* @returns {this} The current instance for chaining.
*/
setStroke(width, cap, join, dash, dashOffset, miterLimit) {
this.props.stroke = {
width,
cap: cap || 'butt',
join: join || 'miter',
dash: dash || [],
dashOffset: dashOffset || 0,
miterLimit: miterLimit || 10,
};
return this;
}
/**
* Sets whether the Path2D Layer should be filled or stroked.
* @param filled {boolean} - If true, the layer will be filled; otherwise, it will be stroked.
* @returns {this} The current instance for chaining.
*/
setFilled(filled) {
this.props.filled = filled;
return this;
}
/**
* Sets the color of the Path2D Layer.
* @param color {string} - The color of the Path2D Layer.
* @returns {this} The current instance for chaining.
* @throws {LazyError} If the color is not provided or invalid.
*/
setColor(color) {
if (!color)
throw new LazyUtil_1.LazyError('The color of the layer must be provided');
if (!(0, utils_1.isColor)(color))
throw new LazyUtil_1.LazyError('The color of the layer must be a valid color');
this.props.fillStyle = color;
return this;
}
setPath(path) {
this.props.path2D = path instanceof canvas_1.Path2D ? path : new canvas_1.Path2D(path);
return this;
}
loadFromSVG(path) {
this.props.loadFromSVG = path;
return this;
}
setClipPath(clipPath) {
this.props.clipPath = clipPath;
return this;
}
toSVGString() {
return this.props.path2D.toSVGString();
}
addPath(path, transform) {
this.props.path2D.addPath(path, transform);
return this;
}
arc(x, y, radius, startAngle, endAngle, anticlockwise) {
this.props.path2D.arc(x, y, radius, startAngle, endAngle, anticlockwise);
return this;
}
arcTo(x1, y1, x2, y2, radius) {
this.props.path2D.arcTo(x1, y1, x2, y2, radius);
return this;
}
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
this.props.path2D.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
return this;
}
closePath() {
this.props.path2D.closePath();
return this;
}
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {
this.props.path2D.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
return this;
}
lineTo(x, y) {
this.props.path2D.lineTo(x, y);
return this;
}
moveTo(x, y) {
this.props.path2D.moveTo(x, y);
return this;
}
quadraticCurveTo(cpx, cpy, x, y) {
this.props.path2D.quadraticCurveTo(cpx, cpy, x, y);
return this;
}
rect(x, y, width, height) {
this.props.path2D.rect(x, y, width, height);
return this;
}
stroke(stroke) {
this.props.path2D.stroke(stroke);
return this;
}
op(path, op) {
this.props.path2D.op(path, op);
return this;
}
getFillType() {
return this.props.path2D.getFillType();
}
getFillTypeString() {
return this.props.path2D.getFillTypeString();
}
setFillType(fillType) {
this.props.path2D.setFillType(fillType);
return this;
}
simplify() {
this.props.path2D.simplify();
return this;
}
asWinding() {
this.props.path2D.asWinding();
return this;
}
transform(matrix) {
this.props.path2D.transform(matrix);
return this;
}
getBounds() {
return this.props.path2D.getBounds();
}
computeTightBounds() {
return this.props.path2D.computeTightBounds();
}
trim(start, end, isComplement) {
this.props.path2D.trim(start, end, isComplement);
return this;
}
equals(path) {
return this.props.path2D.equals(path.props.path2D);
}
roundRect(x, y, width, height, radius) {
this.props.path2D.roundRect(x, y, width, height, radius);
return this;
}
async draw(ctx, canvas, manager, debug) {
ctx.beginPath();
ctx.save();
let fillStyle = await (0, utils_1.parseFillStyle)(ctx, this.props.fillStyle);
(0, utils_1.transform)(ctx, this.props.transform, { width: 0, height: 0, x: 0, y: 0, type: this.type });
(0, utils_1.opacity)(ctx, this.props.opacity);
ctx.globalCompositeOperation = this.props.globalComposite;
if (this.props.clipPath) {
ctx.clip(this.props.path2D);
}
else if (this.props.filled) {
ctx.fillStyle = fillStyle;
ctx.fill(this.props.path2D);
}
else {
ctx.strokeStyle = fillStyle;
ctx.lineWidth = this.props.stroke.width;
ctx.lineCap = this.props.stroke.cap;
ctx.lineJoin = this.props.stroke.join;
ctx.miterLimit = this.props.stroke.miterLimit;
ctx.lineDashOffset = this.props.stroke.dashOffset;
ctx.setLineDash(this.props.stroke.dash);
ctx.stroke(this.props.path2D);
}
ctx.restore();
ctx.closePath();
}
/**
* Converts the Path2D Layer to a JSON representation.
* @returns {IPath2DLayer} The JSON representation of the Path2D Layer.
*/
toJSON() {
return {
id: this.id,
type: this.type,
zIndex: this.zIndex,
visible: this.visible,
props: this.props
};
}
}
exports.Path2DLayer = Path2DLayer;