mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-17 06:21:16 +02:00
Binding highlight refactor
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { THEME, THEME_FILTER } from "@excalidraw/common";
|
||||
|
||||
import { FIXED_BINDING_DISTANCE } from "@excalidraw/element";
|
||||
import { getDiamondPoints } from "@excalidraw/element";
|
||||
import { elementCenterPoint, getCornerRadius } from "@excalidraw/element";
|
||||
|
||||
@@ -130,7 +129,6 @@ export const drawHighlightForRectWithRotation = (
|
||||
context: CanvasRenderingContext2D,
|
||||
element: ExcalidrawRectanguloidElement,
|
||||
elementsMap: ElementsMap,
|
||||
padding: number,
|
||||
) => {
|
||||
const [x, y] = pointRotateRads(
|
||||
pointFrom<GlobalPoint>(element.x, element.y),
|
||||
@@ -157,25 +155,25 @@ export const drawHighlightForRectWithRotation = (
|
||||
pointFrom(0, 0 + radius),
|
||||
pointFrom(0, 0),
|
||||
pointFrom(0 + radius, 0),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const topRightApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(element.width - radius, 0),
|
||||
pointFrom(element.width, 0),
|
||||
pointFrom(element.width, radius),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const bottomRightApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(element.width, element.height - radius),
|
||||
pointFrom(element.width, element.height),
|
||||
pointFrom(element.width - radius, element.height),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const bottomLeftApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(radius, element.height),
|
||||
pointFrom(0, element.height),
|
||||
pointFrom(0, element.height - radius),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
|
||||
context.moveTo(
|
||||
@@ -192,51 +190,8 @@ export const drawHighlightForRectWithRotation = (
|
||||
drawCatmullRomQuadraticApprox(context, topLeftApprox);
|
||||
}
|
||||
|
||||
// Counter-clockwise for the cutout in the middle. We need to have an "inverse
|
||||
// mask" on a filled shape for the diamond highlight, because stroking creates
|
||||
// sharp inset edges on line joins < 90 degrees.
|
||||
{
|
||||
const topLeftApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(0 + radius, 0),
|
||||
pointFrom(0, 0),
|
||||
pointFrom(0, 0 + radius),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const topRightApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(element.width, radius),
|
||||
pointFrom(element.width, 0),
|
||||
pointFrom(element.width - radius, 0),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const bottomRightApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(element.width - radius, element.height),
|
||||
pointFrom(element.width, element.height),
|
||||
pointFrom(element.width, element.height - radius),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const bottomLeftApprox = offsetPointsForQuadraticBezier(
|
||||
pointFrom(0, element.height - radius),
|
||||
pointFrom(0, element.height),
|
||||
pointFrom(radius, element.height),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
|
||||
context.moveTo(
|
||||
topLeftApprox[topLeftApprox.length - 1][0],
|
||||
topLeftApprox[topLeftApprox.length - 1][1],
|
||||
);
|
||||
context.lineTo(bottomLeftApprox[0][0], bottomLeftApprox[0][1]);
|
||||
drawCatmullRomQuadraticApprox(context, bottomLeftApprox);
|
||||
context.lineTo(bottomRightApprox[0][0], bottomRightApprox[0][1]);
|
||||
drawCatmullRomQuadraticApprox(context, bottomRightApprox);
|
||||
context.lineTo(topRightApprox[0][0], topRightApprox[0][1]);
|
||||
drawCatmullRomQuadraticApprox(context, topRightApprox);
|
||||
context.lineTo(topLeftApprox[0][0], topLeftApprox[0][1]);
|
||||
drawCatmullRomQuadraticApprox(context, topLeftApprox);
|
||||
}
|
||||
|
||||
context.closePath();
|
||||
context.fill();
|
||||
context.stroke();
|
||||
|
||||
context.restore();
|
||||
};
|
||||
@@ -286,7 +241,6 @@ export const strokeRectWithRotation = (
|
||||
|
||||
export const drawHighlightForDiamondWithRotation = (
|
||||
context: CanvasRenderingContext2D,
|
||||
padding: number,
|
||||
element: ExcalidrawDiamondElement,
|
||||
elementsMap: ElementsMap,
|
||||
) => {
|
||||
@@ -317,7 +271,7 @@ export const drawHighlightForDiamondWithRotation = (
|
||||
pointFrom(topX, topY),
|
||||
pointFrom(topX + verticalRadius, topY + horizontalRadius),
|
||||
),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const rightApprox = curveOffsetPoints(
|
||||
curve(
|
||||
@@ -326,7 +280,7 @@ export const drawHighlightForDiamondWithRotation = (
|
||||
pointFrom(rightX, rightY),
|
||||
pointFrom(rightX - verticalRadius, rightY + horizontalRadius),
|
||||
),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const bottomApprox = curveOffsetPoints(
|
||||
curve(
|
||||
@@ -335,7 +289,7 @@ export const drawHighlightForDiamondWithRotation = (
|
||||
pointFrom(bottomX, bottomY),
|
||||
pointFrom(bottomX - verticalRadius, bottomY - horizontalRadius),
|
||||
),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
const leftApprox = curveOffsetPoints(
|
||||
curve(
|
||||
@@ -344,7 +298,7 @@ export const drawHighlightForDiamondWithRotation = (
|
||||
pointFrom(leftX, leftY),
|
||||
pointFrom(leftX + verticalRadius, leftY - horizontalRadius),
|
||||
),
|
||||
padding,
|
||||
0,
|
||||
);
|
||||
|
||||
context.moveTo(
|
||||
@@ -361,69 +315,7 @@ export const drawHighlightForDiamondWithRotation = (
|
||||
drawCatmullRomCubicApprox(context, topApprox);
|
||||
}
|
||||
|
||||
// Counter-clockwise for the cutout in the middle. We need to have an "inverse
|
||||
// mask" on a filled shape for the diamond highlight, because stroking creates
|
||||
// sharp inset edges on line joins < 90 degrees.
|
||||
{
|
||||
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =
|
||||
getDiamondPoints(element);
|
||||
const verticalRadius = element.roundness
|
||||
? getCornerRadius(Math.abs(topX - leftX), element)
|
||||
: (topX - leftX) * 0.01;
|
||||
const horizontalRadius = element.roundness
|
||||
? getCornerRadius(Math.abs(rightY - topY), element)
|
||||
: (rightY - topY) * 0.01;
|
||||
const topApprox = curveOffsetPoints(
|
||||
curve(
|
||||
pointFrom(topX + verticalRadius, topY + horizontalRadius),
|
||||
pointFrom(topX, topY),
|
||||
pointFrom(topX, topY),
|
||||
pointFrom(topX - verticalRadius, topY + horizontalRadius),
|
||||
),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const rightApprox = curveOffsetPoints(
|
||||
curve(
|
||||
pointFrom(rightX - verticalRadius, rightY + horizontalRadius),
|
||||
pointFrom(rightX, rightY),
|
||||
pointFrom(rightX, rightY),
|
||||
pointFrom(rightX - verticalRadius, rightY - horizontalRadius),
|
||||
),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const bottomApprox = curveOffsetPoints(
|
||||
curve(
|
||||
pointFrom(bottomX - verticalRadius, bottomY - horizontalRadius),
|
||||
pointFrom(bottomX, bottomY),
|
||||
pointFrom(bottomX, bottomY),
|
||||
pointFrom(bottomX + verticalRadius, bottomY - horizontalRadius),
|
||||
),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
const leftApprox = curveOffsetPoints(
|
||||
curve(
|
||||
pointFrom(leftX + verticalRadius, leftY - horizontalRadius),
|
||||
pointFrom(leftX, leftY),
|
||||
pointFrom(leftX, leftY),
|
||||
pointFrom(leftX + verticalRadius, leftY + horizontalRadius),
|
||||
),
|
||||
-FIXED_BINDING_DISTANCE,
|
||||
);
|
||||
|
||||
context.moveTo(
|
||||
topApprox[topApprox.length - 1][0],
|
||||
topApprox[topApprox.length - 1][1],
|
||||
);
|
||||
context.lineTo(leftApprox[1][0], leftApprox[1][1]);
|
||||
drawCatmullRomCubicApprox(context, leftApprox);
|
||||
context.lineTo(bottomApprox[1][0], bottomApprox[1][1]);
|
||||
drawCatmullRomCubicApprox(context, bottomApprox);
|
||||
context.lineTo(rightApprox[1][0], rightApprox[1][1]);
|
||||
drawCatmullRomCubicApprox(context, rightApprox);
|
||||
context.lineTo(topApprox[1][0], topApprox[1][1]);
|
||||
drawCatmullRomCubicApprox(context, topApprox);
|
||||
}
|
||||
context.closePath();
|
||||
context.fill();
|
||||
context.stroke();
|
||||
context.restore();
|
||||
};
|
||||
|
@@ -16,7 +16,6 @@ import {
|
||||
throttleRAF,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import { FIXED_BINDING_DISTANCE } from "@excalidraw/element";
|
||||
import { LinearElementEditor } from "@excalidraw/element";
|
||||
import {
|
||||
getOmitSidesForDevice,
|
||||
@@ -192,11 +191,11 @@ const renderBindingHighlightForBindableElement = (
|
||||
context: CanvasRenderingContext2D,
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: InteractiveCanvasAppState["zoom"],
|
||||
) => {
|
||||
const padding = 5;
|
||||
|
||||
context.fillStyle = "rgba(0,0,0,.05)";
|
||||
context.lineWidth = 1;
|
||||
context.strokeStyle = element.strokeColor;
|
||||
context.shadowColor = element.strokeColor;
|
||||
context.shadowBlur = 10;
|
||||
|
||||
switch (element.type) {
|
||||
case "rectangle":
|
||||
@@ -206,28 +205,20 @@ const renderBindingHighlightForBindableElement = (
|
||||
case "embeddable":
|
||||
case "frame":
|
||||
case "magicframe":
|
||||
drawHighlightForRectWithRotation(context, element, elementsMap, padding);
|
||||
drawHighlightForRectWithRotation(context, element, elementsMap);
|
||||
break;
|
||||
case "diamond":
|
||||
drawHighlightForDiamondWithRotation(
|
||||
context,
|
||||
padding,
|
||||
element,
|
||||
elementsMap,
|
||||
);
|
||||
drawHighlightForDiamondWithRotation(context, element, elementsMap);
|
||||
break;
|
||||
case "ellipse": {
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
||||
const width = x2 - x1;
|
||||
const height = y2 - y1;
|
||||
|
||||
context.strokeStyle = "rgba(0,0,0,.05)";
|
||||
context.lineWidth = padding - FIXED_BINDING_DISTANCE;
|
||||
|
||||
strokeEllipseWithRotation(
|
||||
context,
|
||||
width + padding + FIXED_BINDING_DISTANCE,
|
||||
height + padding + FIXED_BINDING_DISTANCE,
|
||||
width,
|
||||
height,
|
||||
x1 + width / 2,
|
||||
y1 + height / 2,
|
||||
element.angle,
|
||||
@@ -241,7 +232,6 @@ const renderBindingHighlightForSuggestedPointBinding = (
|
||||
context: CanvasRenderingContext2D,
|
||||
suggestedBinding: SuggestedPointBinding,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: InteractiveCanvasAppState["zoom"],
|
||||
) => {
|
||||
const [element, startOrEnd] = suggestedBinding;
|
||||
|
||||
@@ -343,7 +333,7 @@ const renderBindingHighlight = (
|
||||
|
||||
context.save();
|
||||
context.translate(appState.scrollX, appState.scrollY);
|
||||
renderHighlight(context, suggestedBinding as any, elementsMap, appState.zoom);
|
||||
renderHighlight(context, suggestedBinding as any, elementsMap);
|
||||
|
||||
context.restore();
|
||||
};
|
||||
|
Reference in New Issue
Block a user