UNPKG

@nmmty/lazycanvas

Version:

A simple way to interact with @napi-rs/canvas in an advanced way!

206 lines (205 loc) 6.8 kB
"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 : {}; this.props = this.validateProps(this.props); } /** * Sets the color of the Path2D Layer. * @param {ColorType} [color] - The color of the 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, { debug, manager }); (0, utils_1.transform)(ctx, this.props.transform, { width: 0, height: 0, x: 0, y: 0, type: this.type }); (0, utils_1.drawShadow)(ctx, this.props.shadow); (0, utils_1.opacity)(ctx, this.props.opacity); (0, utils_1.filters)(ctx, this.props.filter); 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 }; } /** * Validates the properties of the Path2D Layer. * @param {IPath2DLayerProps} [data] - The properties to validate. * @returns {IPath2DLayerProps} The validated properties. */ validateProps(data) { return { ...super.validateProps(data), filled: data.filled || true, fillStyle: data.fillStyle || '#000000', path2D: data.path2D || new canvas_1.Path2D(), stroke: { width: data.stroke?.width || 1, cap: data.stroke?.cap || 'butt', join: data.stroke?.join || 'miter', dashOffset: data.stroke?.dashOffset || 0, dash: data.stroke?.dash || [], miterLimit: data.stroke?.miterLimit || 10 }, loadFromSVG: data.loadFromSVG || false, clipPath: data.clipPath || false }; } } exports.Path2DLayer = Path2DLayer;