UNPKG

@nmmty/lazycanvas

Version:

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

294 lines (293 loc) 9.64 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 : {}; } /** * 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;