mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Small refactor
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
028c397c0a
commit
47064a3662
4 changed files with 35 additions and 48 deletions
|
@ -798,14 +798,18 @@ export const bindPointToSnapToElementOutline = (
|
||||||
const intersections: GlobalPoint[] = [
|
const intersections: GlobalPoint[] = [
|
||||||
...(intersectElementWithLine(
|
...(intersectElementWithLine(
|
||||||
bindableElement,
|
bindableElement,
|
||||||
pointFrom(p[0], p[1] - 2 * bindableElement.height),
|
line(
|
||||||
pointFrom(p[0], p[1] + 2 * bindableElement.height),
|
pointFrom(p[0], p[1] - 2 * bindableElement.height),
|
||||||
|
pointFrom(p[0], p[1] + 2 * bindableElement.height),
|
||||||
|
),
|
||||||
FIXED_BINDING_DISTANCE,
|
FIXED_BINDING_DISTANCE,
|
||||||
) ?? []),
|
) ?? []),
|
||||||
...(intersectElementWithLine(
|
...(intersectElementWithLine(
|
||||||
bindableElement,
|
bindableElement,
|
||||||
pointFrom(p[0] - 2 * bindableElement.width, p[1]),
|
line(
|
||||||
pointFrom(p[0] + 2 * bindableElement.width, p[1]),
|
pointFrom(p[0] - 2 * bindableElement.width, p[1]),
|
||||||
|
pointFrom(p[0] + 2 * bindableElement.width, p[1]),
|
||||||
|
),
|
||||||
FIXED_BINDING_DISTANCE,
|
FIXED_BINDING_DISTANCE,
|
||||||
) ?? []),
|
) ?? []),
|
||||||
].filter((p) => p != null);
|
].filter((p) => p != null);
|
||||||
|
@ -1102,8 +1106,7 @@ const updateBoundPoint = (
|
||||||
} else {
|
} else {
|
||||||
const intersections = intersectElementWithLine(
|
const intersections = intersectElementWithLine(
|
||||||
bindableElement,
|
bindableElement,
|
||||||
adjacentPoint,
|
line<GlobalPoint>(adjacentPoint, focusPointAbsolute),
|
||||||
focusPointAbsolute,
|
|
||||||
binding.gap,
|
binding.gap,
|
||||||
);
|
);
|
||||||
if (!intersections || intersections.length === 0) {
|
if (!intersections || intersections.length === 0) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { intersectElementWithLine } from "./collision";
|
import { intersectElementWithLine } from "./collision";
|
||||||
import { newElement } from "./newElement";
|
import { newElement } from "./newElement";
|
||||||
import { pointFrom } from "../../math";
|
import type { GlobalPoint } from "../../math";
|
||||||
|
import { lineFromPointPair, pointFrom } from "../../math";
|
||||||
import { ROUNDNESS } from "..";
|
import { ROUNDNESS } from "..";
|
||||||
|
|
||||||
describe("intersection with element", () => {
|
describe("intersection with element", () => {
|
||||||
|
@ -150,8 +151,7 @@ describe("intersection with element", () => {
|
||||||
type: ROUNDNESS.PROPORTIONAL_RADIUS,
|
type: ROUNDNESS.PROPORTIONAL_RADIUS,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pointFrom(0, -30),
|
lineFromPointPair<GlobalPoint>([pointFrom(0, -30), pointFrom(0, -25)]),
|
||||||
pointFrom(0, -25),
|
|
||||||
).map((p) =>
|
).map((p) =>
|
||||||
pointFrom(Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100),
|
pointFrom(Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100),
|
||||||
),
|
),
|
||||||
|
@ -169,8 +169,7 @@ describe("intersection with element", () => {
|
||||||
type: ROUNDNESS.PROPORTIONAL_RADIUS,
|
type: ROUNDNESS.PROPORTIONAL_RADIUS,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pointFrom(-30, 0),
|
lineFromPointPair<GlobalPoint>([pointFrom(-30, 0), pointFrom(-25, 0)]),
|
||||||
pointFrom(-25, 0),
|
|
||||||
).map((p) =>
|
).map((p) =>
|
||||||
pointFrom(Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100),
|
pointFrom(Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100),
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,11 +6,7 @@ import type {
|
||||||
ExcalidrawRectangleElement,
|
ExcalidrawRectangleElement,
|
||||||
ExcalidrawRectanguloidElement,
|
ExcalidrawRectanguloidElement,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import {
|
import { createDiamondArc, getElementBounds } from "./bounds";
|
||||||
createDiamondArc,
|
|
||||||
createDiamondSide,
|
|
||||||
getElementBounds,
|
|
||||||
} from "./bounds";
|
|
||||||
import type { FrameNameBounds } from "../types";
|
import type { FrameNameBounds } from "../types";
|
||||||
import type { GeometricShape } from "../../utils/geometry/shape";
|
import type { GeometricShape } from "../../utils/geometry/shape";
|
||||||
import { getPolygonShape } from "../../utils/geometry/shape";
|
import { getPolygonShape } from "../../utils/geometry/shape";
|
||||||
|
@ -23,7 +19,7 @@ import {
|
||||||
isTextElement,
|
isTextElement,
|
||||||
} from "./typeChecks";
|
} from "./typeChecks";
|
||||||
import { getBoundTextShape, getCornerRadius } from "../shapes";
|
import { getBoundTextShape, getCornerRadius } from "../shapes";
|
||||||
import type { Arc, GlobalPoint, Polygon } from "../../math";
|
import type { Arc, GlobalPoint, Line, Polygon } from "../../math";
|
||||||
import {
|
import {
|
||||||
pathIsALoop,
|
pathIsALoop,
|
||||||
isPointWithinBounds,
|
isPointWithinBounds,
|
||||||
|
@ -148,8 +144,7 @@ export const hitElementBoundText = (
|
||||||
|
|
||||||
export const intersectElementWithLine = (
|
export const intersectElementWithLine = (
|
||||||
element: ExcalidrawElement,
|
element: ExcalidrawElement,
|
||||||
a: GlobalPoint,
|
line: Line<GlobalPoint>,
|
||||||
b: GlobalPoint,
|
|
||||||
offset: number = 0,
|
offset: number = 0,
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
|
@ -160,11 +155,11 @@ export const intersectElementWithLine = (
|
||||||
case "embeddable":
|
case "embeddable":
|
||||||
case "frame":
|
case "frame":
|
||||||
case "magicframe":
|
case "magicframe":
|
||||||
return intersectRectanguloidWithLine(element, a, b, offset);
|
return intersectRectanguloidWithLine(element, line, offset);
|
||||||
case "diamond":
|
case "diamond":
|
||||||
return intersectDiamondWithLine(element, a, b, offset);
|
return intersectDiamondWithLine(element, line, offset);
|
||||||
case "ellipse":
|
case "ellipse":
|
||||||
return intersectEllipseWithLine(element, a, b, offset);
|
return intersectEllipseWithLine(element, line, offset);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unimplemented element type '${element.type}'`);
|
throw new Error(`Unimplemented element type '${element.type}'`);
|
||||||
}
|
}
|
||||||
|
@ -172,8 +167,7 @@ export const intersectElementWithLine = (
|
||||||
|
|
||||||
const intersectRectanguloidWithLine = (
|
const intersectRectanguloidWithLine = (
|
||||||
element: ExcalidrawRectanguloidElement,
|
element: ExcalidrawRectanguloidElement,
|
||||||
a: GlobalPoint,
|
l: Line<GlobalPoint>,
|
||||||
b: GlobalPoint,
|
|
||||||
offset: number,
|
offset: number,
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
const r = rectangle(
|
const r = rectangle(
|
||||||
|
@ -190,12 +184,12 @@ const intersectRectanguloidWithLine = (
|
||||||
// To emulate a rotated rectangle we rotate the point in the inverse angle
|
// To emulate a rotated rectangle we rotate the point in the inverse angle
|
||||||
// instead. It's all the same distance-wise.
|
// instead. It's all the same distance-wise.
|
||||||
const rotatedA = pointRotateRads<GlobalPoint>(
|
const rotatedA = pointRotateRads<GlobalPoint>(
|
||||||
a,
|
l[0],
|
||||||
center,
|
center,
|
||||||
radians(-element.angle),
|
radians(-element.angle),
|
||||||
);
|
);
|
||||||
const rotatedB = pointRotateRads<GlobalPoint>(
|
const rotatedB = pointRotateRads<GlobalPoint>(
|
||||||
b,
|
l[1],
|
||||||
center,
|
center,
|
||||||
radians(-element.angle),
|
radians(-element.angle),
|
||||||
);
|
);
|
||||||
|
@ -265,7 +259,7 @@ const intersectRectanguloidWithLine = (
|
||||||
.filter(
|
.filter(
|
||||||
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,
|
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,
|
||||||
)
|
)
|
||||||
.sort((g, h) => pointDistanceSq(g!, a) - pointDistanceSq(h!, a))
|
.sort((g, h) => pointDistanceSq(g!, l[0]) - pointDistanceSq(h!, l[1]))
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,8 +272,7 @@ const intersectRectanguloidWithLine = (
|
||||||
*/
|
*/
|
||||||
const intersectDiamondWithLine = (
|
const intersectDiamondWithLine = (
|
||||||
element: ExcalidrawDiamondElement,
|
element: ExcalidrawDiamondElement,
|
||||||
a: GlobalPoint,
|
l: Line<GlobalPoint>,
|
||||||
b: GlobalPoint,
|
|
||||||
offset: number = 0,
|
offset: number = 0,
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
const top = pointFrom<GlobalPoint>(
|
const top = pointFrom<GlobalPoint>(
|
||||||
|
@ -310,8 +303,8 @@ const intersectDiamondWithLine = (
|
||||||
|
|
||||||
// Rotate the point to the inverse direction to simulate the rotated diamond
|
// Rotate the point to the inverse direction to simulate the rotated diamond
|
||||||
// points. It's all the same distance-wise.
|
// points. It's all the same distance-wise.
|
||||||
const rotatedA = pointRotateRads(a, center, radians(-element.angle));
|
const rotatedA = pointRotateRads(l[0], center, radians(-element.angle));
|
||||||
const rotatedB = pointRotateRads(b, center, radians(-element.angle));
|
const rotatedB = pointRotateRads(l[1], center, radians(-element.angle));
|
||||||
|
|
||||||
const topRight = segment<GlobalPoint>(
|
const topRight = segment<GlobalPoint>(
|
||||||
pointFrom(top[0] + verticalRadius, top[1] + horizontalRadius),
|
pointFrom(top[0] + verticalRadius, top[1] + horizontalRadius),
|
||||||
|
@ -393,7 +386,7 @@ const intersectDiamondWithLine = (
|
||||||
.filter(
|
.filter(
|
||||||
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,
|
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,
|
||||||
)
|
)
|
||||||
.sort((g, h) => pointDistanceSq(g!, a) - pointDistanceSq(h!, a))
|
.sort((g, h) => pointDistanceSq(g!, l[0]) - pointDistanceSq(h!, l[1]))
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -406,8 +399,7 @@ const intersectDiamondWithLine = (
|
||||||
*/
|
*/
|
||||||
const intersectEllipseWithLine = (
|
const intersectEllipseWithLine = (
|
||||||
element: ExcalidrawEllipseElement,
|
element: ExcalidrawEllipseElement,
|
||||||
a: GlobalPoint,
|
l: Line<GlobalPoint>,
|
||||||
b: GlobalPoint,
|
|
||||||
offset: number = 0,
|
offset: number = 0,
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
const center = pointFrom<GlobalPoint>(
|
const center = pointFrom<GlobalPoint>(
|
||||||
|
@ -415,13 +407,13 @@ const intersectEllipseWithLine = (
|
||||||
element.y + element.height / 2,
|
element.y + element.height / 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const rotatedA = pointRotateRads(a, center, radians(-element.angle));
|
const rotatedA = pointRotateRads(l[0], center, radians(-element.angle));
|
||||||
const rotatedB = pointRotateRads(b, center, radians(-element.angle));
|
const rotatedB = pointRotateRads(l[1], center, radians(-element.angle));
|
||||||
|
|
||||||
return ellipseLineIntersectionPoints(
|
return ellipseLineIntersectionPoints(
|
||||||
ellipse(center, element.width / 2 + offset, element.height / 2 + offset),
|
ellipse(center, element.width / 2 + offset, element.height / 2 + offset),
|
||||||
line(rotatedA, rotatedB),
|
line(rotatedA, rotatedB),
|
||||||
)
|
)
|
||||||
.map((p) => pointRotateRads(p, center, element.angle))
|
.map((p) => pointRotateRads(p, center, element.angle))
|
||||||
.sort((g, h) => pointDistanceSq(g!, a) - pointDistanceSq(h!, a));
|
.sort((g, h) => pointDistanceSq(g!, l[0]) - pointDistanceSq(h!, l[1]));
|
||||||
};
|
};
|
||||||
|
|
|
@ -262,7 +262,7 @@ const generateElementCanvas = (
|
||||||
context.filter = IMAGE_INVERT_FILTER;
|
context.filter = IMAGE_INVERT_FILTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawElementOnCanvas(element, rc, context, renderConfig, appState);
|
drawElementOnCanvas(element, rc, context, renderConfig);
|
||||||
|
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
|
@ -392,7 +392,6 @@ const drawElementOnCanvas = (
|
||||||
rc: RoughCanvas,
|
rc: RoughCanvas,
|
||||||
context: CanvasRenderingContext2D,
|
context: CanvasRenderingContext2D,
|
||||||
renderConfig: StaticCanvasRenderConfig,
|
renderConfig: StaticCanvasRenderConfig,
|
||||||
appState: StaticCanvasAppState,
|
|
||||||
) => {
|
) => {
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case "rectangle":
|
case "rectangle":
|
||||||
|
@ -779,7 +778,7 @@ export const renderElement = (
|
||||||
context.translate(cx, cy);
|
context.translate(cx, cy);
|
||||||
context.rotate(element.angle);
|
context.rotate(element.angle);
|
||||||
context.translate(-shiftX, -shiftY);
|
context.translate(-shiftX, -shiftY);
|
||||||
drawElementOnCanvas(element, rc, context, renderConfig, appState);
|
drawElementOnCanvas(element, rc, context, renderConfig);
|
||||||
context.restore();
|
context.restore();
|
||||||
} else {
|
} else {
|
||||||
const elementWithCanvas = generateElementWithCanvas(
|
const elementWithCanvas = generateElementWithCanvas(
|
||||||
|
@ -875,13 +874,7 @@ export const renderElement = (
|
||||||
|
|
||||||
tempCanvasContext.translate(-shiftX, -shiftY);
|
tempCanvasContext.translate(-shiftX, -shiftY);
|
||||||
|
|
||||||
drawElementOnCanvas(
|
drawElementOnCanvas(element, tempRc, tempCanvasContext, renderConfig);
|
||||||
element,
|
|
||||||
tempRc,
|
|
||||||
tempCanvasContext,
|
|
||||||
renderConfig,
|
|
||||||
appState,
|
|
||||||
);
|
|
||||||
|
|
||||||
tempCanvasContext.translate(shiftX, shiftY);
|
tempCanvasContext.translate(shiftX, shiftY);
|
||||||
|
|
||||||
|
@ -920,7 +913,7 @@ export const renderElement = (
|
||||||
}
|
}
|
||||||
|
|
||||||
context.translate(-shiftX, -shiftY);
|
context.translate(-shiftX, -shiftY);
|
||||||
drawElementOnCanvas(element, rc, context, renderConfig, appState);
|
drawElementOnCanvas(element, rc, context, renderConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue