import { Vector2 } from '../../math/Vector2.js'; import { CurvePath } from './CurvePath.js'; import { EllipseCurve } from '../curves/EllipseCurve.js'; import { SplineCurve } from '../curves/SplineCurve.js'; import { CubicBezierCurve } from '../curves/CubicBezierCurve.js'; import { QuadraticBezierCurve } from '../curves/QuadraticBezierCurve.js'; import { LineCurve } from '../curves/LineCurve.js'; class Path extends CurvePath { constructor(points) { super(); this.type = 'Path'; this.currentPoint = new Vector2(); if (points) { this.setFromPoints(points); } } setFromPoints(points) { this.moveTo(points[0].x, points[0].y); for (let i = 1, l = points.length; i < l; i++) { this.lineTo(points[i].x, points[i].y); } return this; } moveTo(x, y) { this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? return this; } lineTo(x, y) { const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); this.curves.push(curve); this.currentPoint.set(x, y); return this; } quadraticCurveTo(aCPx, aCPy, aX, aY) { const curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY)); this.curves.push(curve); this.currentPoint.set(aX, aY); return this; } bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { const curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY)); this.curves.push(curve); this.currentPoint.set(aX, aY); return this; } splineThru(pts /*Array of Vector*/) { const npts = [this.currentPoint.clone()].concat(pts); const curve = new SplineCurve(npts); this.curves.push(curve); this.currentPoint.copy(pts[pts.length - 1]); return this; } arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); return this; } absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); if (this.curves.length > 0) { // if a previous curve is present, attempt to join const firstPoint = curve.getPoint(0); if (!firstPoint.equals(this.currentPoint)) { this.lineTo(firstPoint.x, firstPoint.y); } } this.curves.push(curve); const lastPoint = curve.getPoint(1); this.currentPoint.copy(lastPoint); return this; } copy(source) { super.copy(source); this.currentPoint.copy(source.currentPoint); return this; } toJSON() { const data = super.toJSON(); data.currentPoint = this.currentPoint.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.currentPoint.fromArray(json.currentPoint); return this; } } export { Path };