mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Fix diamond distance
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
34ec751501
commit
c41486abd1
4 changed files with 74 additions and 53 deletions
|
@ -12,7 +12,7 @@ import {
|
||||||
segment,
|
segment,
|
||||||
segmentDistanceToPoint,
|
segmentDistanceToPoint,
|
||||||
} from "../../math";
|
} from "../../math";
|
||||||
import { getCornerRadius } from "../shapes";
|
import { getCornerRadius, getDiamondPoints } from "../shapes";
|
||||||
import type {
|
import type {
|
||||||
ExcalidrawBindableElement,
|
ExcalidrawBindableElement,
|
||||||
ExcalidrawDiamondElement,
|
ExcalidrawDiamondElement,
|
||||||
|
@ -128,18 +128,19 @@ export const distanceToRectangleElement = (
|
||||||
*/
|
*/
|
||||||
const createDiamondSide = (
|
const createDiamondSide = (
|
||||||
s: Segment<GlobalPoint>,
|
s: Segment<GlobalPoint>,
|
||||||
r: number,
|
startRadius: number,
|
||||||
|
endRadius: number,
|
||||||
): Segment<GlobalPoint> => {
|
): Segment<GlobalPoint> => {
|
||||||
if (r === 0) {
|
const a = ellipseSegmentInterceptPoints(
|
||||||
return s;
|
ellipse(s[0], startRadius, startRadius),
|
||||||
}
|
s,
|
||||||
|
)[0];
|
||||||
|
const b = ellipseSegmentInterceptPoints(
|
||||||
|
ellipse(s[1], endRadius, endRadius),
|
||||||
|
s,
|
||||||
|
)[0];
|
||||||
|
|
||||||
const t = (4 * r) / Math.sqrt(2);
|
return segment(a, b);
|
||||||
|
|
||||||
return segment(
|
|
||||||
ellipseSegmentInterceptPoints(ellipse(s[0], t, t), s)[0],
|
|
||||||
ellipseSegmentInterceptPoints(ellipse(s[1], t, t), s)[0],
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +155,10 @@ const createDiamondSide = (
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createDiamondArc = (start: GlobalPoint, end: GlobalPoint, r: number) => {
|
const createDiamondArc = (start: GlobalPoint, end: GlobalPoint, r: number) => {
|
||||||
const c = point((start[0] + end[0]) / 2, start[1]);
|
const c = point<GlobalPoint>(
|
||||||
|
(start[0] + end[0]) / 2,
|
||||||
|
(start[1] + end[1]) / 2,
|
||||||
|
);
|
||||||
|
|
||||||
return arc(
|
return arc(
|
||||||
c,
|
c,
|
||||||
|
@ -176,41 +180,58 @@ export const distanceToDiamondElement = (
|
||||||
element: ExcalidrawDiamondElement,
|
element: ExcalidrawDiamondElement,
|
||||||
p: GlobalPoint,
|
p: GlobalPoint,
|
||||||
): number => {
|
): number => {
|
||||||
const center = point<GlobalPoint>(
|
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =
|
||||||
element.x + element.width / 2,
|
getDiamondPoints(element);
|
||||||
element.y + element.height / 2,
|
const center = point<GlobalPoint>((topX + bottomX) / 2, (topY + bottomY) / 2);
|
||||||
);
|
const verticalRadius = getCornerRadius(Math.abs(topX - leftX), element);
|
||||||
const roundness = getCornerRadius(
|
const horizontalRadius = getCornerRadius(Math.abs(rightY - topY), element);
|
||||||
Math.min(element.width, element.height),
|
|
||||||
element,
|
|
||||||
);
|
|
||||||
// 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 rotatedPoint = pointRotateRads(p, center, radians(-element.angle));
|
const rotatedPoint = pointRotateRads(p, center, radians(-element.angle));
|
||||||
const [top, right, bottom, left]: GlobalPoint[] = [
|
const [top, right, bottom, left]: GlobalPoint[] = [
|
||||||
point(element.x + element.width / 2, element.y),
|
point(element.x + topX, element.y + topY),
|
||||||
point(element.x + element.width, element.y + element.height / 2),
|
point(element.x + rightX, element.y + rightY),
|
||||||
point(element.x + element.width / 2, element.y + element.height),
|
point(element.x + bottomX, element.y + bottomY),
|
||||||
point(element.x, element.y + element.height / 2),
|
point(element.x + leftX, element.y + leftY),
|
||||||
];
|
];
|
||||||
const topRight = createDiamondSide(segment(top, right), roundness);
|
|
||||||
const bottomRight = createDiamondSide(segment(right, bottom), roundness);
|
const topRight = createDiamondSide(
|
||||||
const bottomLeft = createDiamondSide(segment(bottom, left), roundness);
|
segment(top, right),
|
||||||
const topLeft = createDiamondSide(segment(left, top), roundness);
|
verticalRadius,
|
||||||
|
horizontalRadius,
|
||||||
|
);
|
||||||
|
const bottomRight = createDiamondSide(
|
||||||
|
segment(bottom, right),
|
||||||
|
verticalRadius,
|
||||||
|
horizontalRadius,
|
||||||
|
);
|
||||||
|
const bottomLeft = createDiamondSide(
|
||||||
|
segment(bottom, left),
|
||||||
|
verticalRadius,
|
||||||
|
horizontalRadius,
|
||||||
|
);
|
||||||
|
const topLeft = createDiamondSide(
|
||||||
|
segment(top, left),
|
||||||
|
verticalRadius,
|
||||||
|
horizontalRadius,
|
||||||
|
);
|
||||||
|
|
||||||
|
const arcs = element.roundness
|
||||||
|
? [
|
||||||
|
createDiamondArc(topLeft[0], topRight[0], verticalRadius), // TOP
|
||||||
|
createDiamondArc(topRight[1], bottomRight[1], horizontalRadius), // RIGHT
|
||||||
|
createDiamondArc(bottomRight[0], bottomLeft[0], verticalRadius), // BOTTOM
|
||||||
|
createDiamondArc(bottomLeft[1], topLeft[1], horizontalRadius), // LEFT
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
return Math.min(
|
return Math.min(
|
||||||
...[
|
...[
|
||||||
...[topRight, bottomRight, bottomLeft, topLeft].map((s) =>
|
...[topRight, bottomRight, bottomLeft, topLeft].map((s) =>
|
||||||
segmentDistanceToPoint(rotatedPoint, s),
|
segmentDistanceToPoint(rotatedPoint, s),
|
||||||
),
|
),
|
||||||
...(roundness > 0
|
...arcs.map((a) => arcDistanceFromPoint(a, rotatedPoint)),
|
||||||
? [
|
|
||||||
createDiamondArc(topLeft[1], topRight[0], roundness),
|
|
||||||
createDiamondArc(topRight[1], bottomRight[0], roundness),
|
|
||||||
createDiamondArc(bottomRight[1], bottomLeft[0], roundness),
|
|
||||||
createDiamondArc(bottomLeft[1], topLeft[0], roundness),
|
|
||||||
].map((a) => arcDistanceFromPoint(a, rotatedPoint))
|
|
||||||
: []),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,6 @@ export {
|
||||||
getCommonBounds,
|
getCommonBounds,
|
||||||
getClosestElementBounds,
|
getClosestElementBounds,
|
||||||
} from "./bounds";
|
} from "./bounds";
|
||||||
export { getDiamondPoints } from "../scene/Shape";
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
||||||
|
|
|
@ -30,7 +30,7 @@ import {
|
||||||
type GlobalPoint,
|
type GlobalPoint,
|
||||||
type LocalPoint,
|
type LocalPoint,
|
||||||
} from "../../math";
|
} from "../../math";
|
||||||
import { getCornerRadius } from "../shapes";
|
import { getCornerRadius, getDiamondPoints } from "../shapes";
|
||||||
|
|
||||||
const getDashArrayDashed = (strokeWidth: number) => [8, 8 + strokeWidth];
|
const getDashArrayDashed = (strokeWidth: number) => [8, 8 + strokeWidth];
|
||||||
|
|
||||||
|
@ -278,21 +278,6 @@ const getArrowheadShapes = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDiamondPoints = (element: ExcalidrawElement) => {
|
|
||||||
// Here we add +1 to avoid these numbers to be 0
|
|
||||||
// otherwise rough.js will throw an error complaining about it
|
|
||||||
const topX = Math.floor(element.width / 2) + 1;
|
|
||||||
const topY = 0;
|
|
||||||
const rightX = element.width;
|
|
||||||
const rightY = Math.floor(element.height / 2) + 1;
|
|
||||||
const bottomX = topX;
|
|
||||||
const bottomY = element.height;
|
|
||||||
const leftX = 0;
|
|
||||||
const leftY = rightY;
|
|
||||||
|
|
||||||
return [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the roughjs shape for given element.
|
* Generates the roughjs shape for given element.
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,6 +42,7 @@ import { getBoundTextElement } from "./element/textElement";
|
||||||
import type {
|
import type {
|
||||||
Bounds,
|
Bounds,
|
||||||
ElementsMap,
|
ElementsMap,
|
||||||
|
ExcalidrawDiamondElement,
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
ExcalidrawLinearElement,
|
ExcalidrawLinearElement,
|
||||||
NonDeleted,
|
NonDeleted,
|
||||||
|
@ -472,3 +473,18 @@ export const getCornerRadius = (x: number, element: ExcalidrawElement) => {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getDiamondPoints = (element: ExcalidrawDiamondElement) => {
|
||||||
|
// Here we add +1 to avoid these numbers to be 0
|
||||||
|
// otherwise rough.js will throw an error complaining about it
|
||||||
|
const topX = Math.floor(element.width / 2) + 1;
|
||||||
|
const topY = 0;
|
||||||
|
const rightX = element.width;
|
||||||
|
const rightY = Math.floor(element.height / 2) + 1;
|
||||||
|
const bottomX = topX;
|
||||||
|
const bottomY = element.height;
|
||||||
|
const leftX = 0;
|
||||||
|
const leftY = rightY;
|
||||||
|
|
||||||
|
return [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY];
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue