mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
refactor: Update generic constraint Point to use GenericPoint
- Changed existing generic constraints that used LocalPoint | GlobalPoint as Point to now use the unified GenericPoint type.
This commit is contained in:
parent
71e55dba9f
commit
85cb973936
21 changed files with 153 additions and 211 deletions
|
@ -1,17 +1,14 @@
|
|||
import {
|
||||
vectorCross,
|
||||
vectorFromPoint,
|
||||
type GlobalPoint,
|
||||
type LocalPoint,
|
||||
type GenericPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { Bounds } from "@excalidraw/element/bounds";
|
||||
|
||||
export type LineSegment<P extends LocalPoint | GlobalPoint> = [P, P];
|
||||
export type LineSegment<P extends GenericPoint> = [P, P];
|
||||
|
||||
export function getBBox<P extends LocalPoint | GlobalPoint>(
|
||||
line: LineSegment<P>,
|
||||
): Bounds {
|
||||
export function getBBox<P extends GenericPoint>(line: LineSegment<P>): Bounds {
|
||||
return [
|
||||
Math.min(line[0][0], line[1][0]),
|
||||
Math.min(line[0][1], line[1][1]),
|
||||
|
@ -26,10 +23,7 @@ export function doBBoxesIntersect(a: Bounds, b: Bounds) {
|
|||
|
||||
const EPSILON = 0.000001;
|
||||
|
||||
export function isPointOnLine<P extends GlobalPoint | LocalPoint>(
|
||||
l: LineSegment<P>,
|
||||
p: P,
|
||||
) {
|
||||
export function isPointOnLine<P extends GenericPoint>(l: LineSegment<P>, p: P) {
|
||||
const p1 = vectorFromPoint(l[1], l[0]);
|
||||
const p2 = vectorFromPoint(p, l[0]);
|
||||
|
||||
|
@ -38,7 +32,7 @@ export function isPointOnLine<P extends GlobalPoint | LocalPoint>(
|
|||
return Math.abs(r) < EPSILON;
|
||||
}
|
||||
|
||||
export function isPointRightOfLine<P extends GlobalPoint | LocalPoint>(
|
||||
export function isPointRightOfLine<P extends GenericPoint>(
|
||||
l: LineSegment<P>,
|
||||
p: P,
|
||||
) {
|
||||
|
@ -48,9 +42,10 @@ export function isPointRightOfLine<P extends GlobalPoint | LocalPoint>(
|
|||
return vectorCross(p1, p2) < 0;
|
||||
}
|
||||
|
||||
export function isLineSegmentTouchingOrCrossingLine<
|
||||
P extends GlobalPoint | LocalPoint,
|
||||
>(a: LineSegment<P>, b: LineSegment<P>) {
|
||||
export function isLineSegmentTouchingOrCrossingLine<P extends GenericPoint>(
|
||||
a: LineSegment<P>,
|
||||
b: LineSegment<P>,
|
||||
) {
|
||||
return (
|
||||
isPointOnLine(a, b[0]) ||
|
||||
isPointOnLine(a, b[1]) ||
|
||||
|
@ -61,7 +56,7 @@ export function isLineSegmentTouchingOrCrossingLine<
|
|||
}
|
||||
|
||||
// https://martin-thoma.com/how-to-check-if-two-line-segments-intersect/
|
||||
export function doLineSegmentsIntersect<P extends GlobalPoint | LocalPoint>(
|
||||
export function doLineSegmentsIntersect<P extends GenericPoint>(
|
||||
a: LineSegment<P>,
|
||||
b: LineSegment<P>,
|
||||
) {
|
||||
|
|
|
@ -5,19 +5,17 @@ import {
|
|||
pointOnLineSegment,
|
||||
pointOnPolygon,
|
||||
polygonFromPoints,
|
||||
type GlobalPoint,
|
||||
type LocalPoint,
|
||||
type Polygon,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { Curve } from "@excalidraw/math";
|
||||
import type { Curve, GenericPoint } from "@excalidraw/math";
|
||||
|
||||
import { pointInEllipse, pointOnEllipse } from "./shape";
|
||||
|
||||
import type { Polycurve, Polyline, GeometricShape } from "./shape";
|
||||
|
||||
// check if the given point is considered on the given shape's border
|
||||
export const isPointOnShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const isPointOnShape = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
shape: GeometricShape<Point>,
|
||||
tolerance = 0,
|
||||
|
@ -43,7 +41,7 @@ export const isPointOnShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
|
||||
// check if the given point is considered inside the element's border
|
||||
export const isPointInShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const isPointInShape = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
shape: GeometricShape<Point>,
|
||||
) => {
|
||||
|
@ -69,14 +67,14 @@ export const isPointInShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
|
||||
// check if the given element is in the given bounds
|
||||
export const isPointInBounds = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const isPointInBounds = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
bounds: Polygon<Point>,
|
||||
) => {
|
||||
return polygonIncludesPoint(point, bounds);
|
||||
};
|
||||
|
||||
const pointOnPolycurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
const pointOnPolycurve = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
polycurve: Polycurve<Point>,
|
||||
tolerance: number,
|
||||
|
@ -84,7 +82,7 @@ const pointOnPolycurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return polycurve.some((curve) => pointOnCurve(point, curve, tolerance));
|
||||
};
|
||||
|
||||
const cubicBezierEquation = <Point extends LocalPoint | GlobalPoint>(
|
||||
const cubicBezierEquation = <Point extends GenericPoint>(
|
||||
curve: Curve<Point>,
|
||||
) => {
|
||||
const [p0, p1, p2, p3] = curve;
|
||||
|
@ -96,7 +94,7 @@ const cubicBezierEquation = <Point extends LocalPoint | GlobalPoint>(
|
|||
p0[idx] * Math.pow(t, 3);
|
||||
};
|
||||
|
||||
const polyLineFromCurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
const polyLineFromCurve = <Point extends GenericPoint>(
|
||||
curve: Curve<Point>,
|
||||
segments = 10,
|
||||
): Polyline<Point> => {
|
||||
|
@ -118,7 +116,7 @@ const polyLineFromCurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return lineSegments;
|
||||
};
|
||||
|
||||
export const pointOnCurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnCurve = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
curve: Curve<Point>,
|
||||
threshold: number,
|
||||
|
@ -126,7 +124,7 @@ export const pointOnCurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return pointOnPolyline(point, polyLineFromCurve(curve), threshold);
|
||||
};
|
||||
|
||||
export const pointOnPolyline = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnPolyline = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
polyline: Polyline<Point>,
|
||||
threshold = 10e-5,
|
||||
|
|
|
@ -30,8 +30,6 @@ import {
|
|||
vectorAdd,
|
||||
vectorFromPoint,
|
||||
vectorScale,
|
||||
type GlobalPoint,
|
||||
type LocalPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import { getElementAbsoluteCoords } from "@excalidraw/element/bounds";
|
||||
|
@ -52,31 +50,36 @@ import type {
|
|||
ExcalidrawSelectionElement,
|
||||
ExcalidrawTextElement,
|
||||
} from "@excalidraw/element/types";
|
||||
import type { Curve, LineSegment, Polygon, Radians } from "@excalidraw/math";
|
||||
import type {
|
||||
Curve,
|
||||
GenericPoint,
|
||||
LineSegment,
|
||||
Polygon,
|
||||
Radians,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { Drawable, Op } from "roughjs/bin/core";
|
||||
|
||||
// a polyline (made up term here) is a line consisting of other line segments
|
||||
// this corresponds to a straight line element in the editor but it could also
|
||||
// be used to model other elements
|
||||
export type Polyline<Point extends GlobalPoint | LocalPoint> =
|
||||
LineSegment<Point>[];
|
||||
export type Polyline<Point extends GenericPoint> = LineSegment<Point>[];
|
||||
|
||||
// a polycurve is a curve consisting of ther curves, this corresponds to a complex
|
||||
// curve on the canvas
|
||||
export type Polycurve<Point extends GlobalPoint | LocalPoint> = Curve<Point>[];
|
||||
export type Polycurve<Point extends GenericPoint> = Curve<Point>[];
|
||||
|
||||
// an ellipse is specified by its center, angle, and its major and minor axes
|
||||
// but for the sake of simplicity, we've used halfWidth and halfHeight instead
|
||||
// in replace of semi major and semi minor axes
|
||||
export type Ellipse<Point extends GlobalPoint | LocalPoint> = {
|
||||
export type Ellipse<Point extends GenericPoint> = {
|
||||
center: Point;
|
||||
angle: Radians;
|
||||
halfWidth: number;
|
||||
halfHeight: number;
|
||||
};
|
||||
|
||||
export type GeometricShape<Point extends GlobalPoint | LocalPoint> =
|
||||
export type GeometricShape<Point extends GenericPoint> =
|
||||
| {
|
||||
type: "line";
|
||||
data: LineSegment<Point>;
|
||||
|
@ -113,7 +116,7 @@ type RectangularElement =
|
|||
| ExcalidrawSelectionElement;
|
||||
|
||||
// polygon
|
||||
export const getPolygonShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getPolygonShape = <Point extends GenericPoint>(
|
||||
element: RectangularElement,
|
||||
): GeometricShape<Point> => {
|
||||
const { angle, width, height, x, y } = element;
|
||||
|
@ -148,7 +151,7 @@ export const getPolygonShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
|
||||
// return the selection box for an element, possibly rotated as well
|
||||
export const getSelectionBoxShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getSelectionBoxShape = <Point extends GenericPoint>(
|
||||
element: ExcalidrawElement,
|
||||
elementsMap: ElementsMap,
|
||||
padding = 10,
|
||||
|
@ -178,7 +181,7 @@ export const getSelectionBoxShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
|
||||
// ellipse
|
||||
export const getEllipseShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getEllipseShape = <Point extends GenericPoint>(
|
||||
element: ExcalidrawEllipseElement,
|
||||
): GeometricShape<Point> => {
|
||||
const { width, height, angle, x, y } = element;
|
||||
|
@ -209,7 +212,7 @@ export const getCurvePathOps = (shape: Drawable): Op[] => {
|
|||
};
|
||||
|
||||
// linear
|
||||
export const getCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getCurveShape = <Point extends GenericPoint>(
|
||||
roughShape: Drawable,
|
||||
startingPoint: Point = pointFrom(0, 0),
|
||||
angleInRadian: Radians,
|
||||
|
@ -247,7 +250,7 @@ export const getCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
};
|
||||
|
||||
const polylineFromPoints = <Point extends GlobalPoint | LocalPoint>(
|
||||
const polylineFromPoints = <Point extends GenericPoint>(
|
||||
points: Point[],
|
||||
): Polyline<Point> => {
|
||||
let previousPoint: Point = points[0];
|
||||
|
@ -262,7 +265,7 @@ const polylineFromPoints = <Point extends GlobalPoint | LocalPoint>(
|
|||
return polyline;
|
||||
};
|
||||
|
||||
export const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getFreedrawShape = <Point extends GenericPoint>(
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
center: Point,
|
||||
isClosed: boolean = false,
|
||||
|
@ -293,7 +296,7 @@ export const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
) as GeometricShape<Point>;
|
||||
};
|
||||
|
||||
export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getClosedCurveShape = <Point extends GenericPoint>(
|
||||
element: ExcalidrawLinearElement,
|
||||
roughShape: Drawable,
|
||||
startingPoint: Point = pointFrom<Point>(0, 0),
|
||||
|
@ -359,9 +362,7 @@ export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
* @returns An array of intersections
|
||||
*/
|
||||
// TODO: Replace with final rounded rectangle code
|
||||
export const segmentIntersectRectangleElement = <
|
||||
Point extends LocalPoint | GlobalPoint,
|
||||
>(
|
||||
export const segmentIntersectRectangleElement = <Point extends GenericPoint>(
|
||||
element: ExcalidrawBindableElement,
|
||||
segment: LineSegment<Point>,
|
||||
gap: number = 0,
|
||||
|
@ -399,7 +400,7 @@ export const segmentIntersectRectangleElement = <
|
|||
.filter((i): i is Point => !!i);
|
||||
};
|
||||
|
||||
const distanceToEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
const distanceToEllipse = <Point extends GenericPoint>(
|
||||
p: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
|
@ -456,7 +457,7 @@ const distanceToEllipse = <Point extends LocalPoint | GlobalPoint>(
|
|||
);
|
||||
};
|
||||
|
||||
export const pointOnEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnEllipse = <Point extends GenericPoint>(
|
||||
point: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
threshold = PRECISION,
|
||||
|
@ -464,7 +465,7 @@ export const pointOnEllipse = <Point extends LocalPoint | GlobalPoint>(
|
|||
return distanceToEllipse(point, ellipse) <= threshold;
|
||||
};
|
||||
|
||||
export const pointInEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointInEllipse = <Point extends GenericPoint>(
|
||||
p: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
|
@ -486,7 +487,7 @@ export const pointInEllipse = <Point extends LocalPoint | GlobalPoint>(
|
|||
);
|
||||
};
|
||||
|
||||
export const ellipseAxes = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const ellipseAxes = <Point extends GenericPoint>(
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
const widthGreaterThanHeight = ellipse.halfWidth > ellipse.halfHeight;
|
||||
|
@ -504,7 +505,7 @@ export const ellipseAxes = <Point extends LocalPoint | GlobalPoint>(
|
|||
};
|
||||
};
|
||||
|
||||
export const ellipseFocusToCenter = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const ellipseFocusToCenter = <Point extends GenericPoint>(
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
const { majorAxis, minorAxis } = ellipseAxes(ellipse);
|
||||
|
@ -512,7 +513,7 @@ export const ellipseFocusToCenter = <Point extends LocalPoint | GlobalPoint>(
|
|||
return Math.sqrt(majorAxis ** 2 - minorAxis ** 2);
|
||||
};
|
||||
|
||||
export const ellipseExtremes = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const ellipseExtremes = <Point extends GenericPoint>(
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
const { center, angle } = ellipse;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue