UNPKG

@tldraw/editor

Version:

A tiny little drawing app (editor).

172 lines (171 loc) 5.34 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var Geometry2d_exports = {}; __export(Geometry2d_exports, { Geometry2d: () => Geometry2d }); module.exports = __toCommonJS(Geometry2d_exports); var import_Box = require("../Box"); var import_Vec = require("../Vec"); var import_utils = require("../utils"); class Geometry2d { isFilled = false; isClosed = true; isLabel = false; debugColor; ignore; constructor(opts) { this.isFilled = opts.isFilled; this.isClosed = opts.isClosed; this.isLabel = opts.isLabel ?? false; this.debugColor = opts.debugColor; this.ignore = opts.ignore; } // hitTestPoint(point: Vec, margin = 0, hitInside = false) { // // We've removed the broad phase here; that should be done outside of the call // return this.distanceToPoint(point, hitInside) <= margin // } hitTestPoint(point, margin = 0, hitInside = false) { if (this.isClosed && (this.isFilled || hitInside) && (0, import_utils.pointInPolygon)(point, this.vertices)) { return true; } return import_Vec.Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin; } distanceToPoint(point, hitInside = false) { return point.dist(this.nearestPoint(point)) * (this.isClosed && (this.isFilled || hitInside) && (0, import_utils.pointInPolygon)(point, this.vertices) ? -1 : 1); } distanceToLineSegment(A, B) { if (A.equals(B)) return this.distanceToPoint(A); const { vertices } = this; let nearest; let dist = Infinity; let d, p, q; for (let i = 0; i < vertices.length; i++) { p = vertices[i]; q = import_Vec.Vec.NearestPointOnLineSegment(A, B, p, true); d = import_Vec.Vec.Dist2(p, q); if (d < dist) { dist = d; nearest = q; } } if (!nearest) throw Error("nearest point not found"); return this.isClosed && this.isFilled && (0, import_utils.pointInPolygon)(nearest, this.vertices) ? -dist : dist; } hitTestLineSegment(A, B, distance = 0) { return this.distanceToLineSegment(A, B) <= distance; } nearestPointOnLineSegment(A, B) { const { vertices } = this; let nearest; let dist = Infinity; let d, p, q; for (let i = 0; i < vertices.length; i++) { p = vertices[i]; q = import_Vec.Vec.NearestPointOnLineSegment(A, B, p, true); d = import_Vec.Vec.Dist2(p, q); if (d < dist) { dist = d; nearest = q; } } if (!nearest) throw Error("nearest point not found"); return nearest; } isPointInBounds(point, margin = 0) { const { bounds } = this; return !(point.x < bounds.minX - margin || point.y < bounds.minY - margin || point.x > bounds.maxX + margin || point.y > bounds.maxY + margin); } _vertices; // eslint-disable-next-line no-restricted-syntax get vertices() { if (!this._vertices) { this._vertices = this.getVertices(); } return this._vertices; } getBounds() { return import_Box.Box.FromPoints(this.vertices); } _bounds; // eslint-disable-next-line no-restricted-syntax get bounds() { if (!this._bounds) { this._bounds = this.getBounds(); } return this._bounds; } // eslint-disable-next-line no-restricted-syntax get center() { return this.bounds.center; } _area; // eslint-disable-next-line no-restricted-syntax get area() { if (!this._area) { this._area = this.getArea(); } return this._area; } getArea() { if (!this.isClosed) { return 0; } const { vertices } = this; let area = 0; for (let i = 0, n = vertices.length; i < n; i++) { const curr = vertices[i]; const next = vertices[(i + 1) % n]; area += curr.x * next.y - next.x * curr.y; } return area / 2; } toSimpleSvgPath() { let path = ""; const { vertices } = this; const n = vertices.length; if (n === 0) return path; path += `M${vertices[0].x},${vertices[0].y}`; for (let i = 1; i < n; i++) { path += `L${vertices[i].x},${vertices[i].y}`; } if (this.isClosed) { path += "Z"; } return path; } _length; // eslint-disable-next-line no-restricted-syntax get length() { if (this._length) return this._length; this._length = this.getLength(); return this._length; } getLength() { const { vertices } = this; let n1, p1 = vertices[0], length = 0; for (let i = 1; i < vertices.length; i++) { n1 = vertices[i]; length += import_Vec.Vec.Dist2(p1, n1); p1 = n1; } return Math.sqrt(length); } } //# sourceMappingURL=Geometry2d.js.map