@tldraw/editor
Version:
A tiny little drawing app (editor).
172 lines (171 loc) • 5.34 kB
JavaScript
"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