mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-24 09:50:56 +02:00
fix: Binding highlight stroke on sharp bindables
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
|||||||
assertNever,
|
assertNever,
|
||||||
COLOR_PALETTE,
|
COLOR_PALETTE,
|
||||||
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
||||||
THEME,
|
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import { RoughGenerator } from "roughjs/bin/generator";
|
import { RoughGenerator } from "roughjs/bin/generator";
|
||||||
@@ -33,7 +32,6 @@ import type { Mutable } from "@excalidraw/common/utility-types";
|
|||||||
import type {
|
import type {
|
||||||
AppState,
|
AppState,
|
||||||
EmbedsValidationStatus,
|
EmbedsValidationStatus,
|
||||||
InteractiveCanvasAppState,
|
|
||||||
} from "@excalidraw/excalidraw/types";
|
} from "@excalidraw/excalidraw/types";
|
||||||
import type {
|
import type {
|
||||||
ElementShape,
|
ElementShape,
|
||||||
@@ -72,7 +70,6 @@ import type {
|
|||||||
ExcalidrawFreeDrawElement,
|
ExcalidrawFreeDrawElement,
|
||||||
ElementsMap,
|
ElementsMap,
|
||||||
ExcalidrawLineElement,
|
ExcalidrawLineElement,
|
||||||
ExcalidrawBindableElement,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
import type { Drawable, Options } from "roughjs/bin/core";
|
import type { Drawable, Options } from "roughjs/bin/core";
|
||||||
@@ -108,31 +105,6 @@ export class ShapeCache {
|
|||||||
ShapeCache.cache = new WeakMap();
|
ShapeCache.cache = new WeakMap();
|
||||||
};
|
};
|
||||||
|
|
||||||
public static generateBindableElementHighlight = <
|
|
||||||
T extends ExcalidrawBindableElement,
|
|
||||||
>(
|
|
||||||
element: T,
|
|
||||||
appState: Pick<InteractiveCanvasAppState, "theme">,
|
|
||||||
) => {
|
|
||||||
let shape =
|
|
||||||
(ShapeCache.get(element) as Drawable | null) ||
|
|
||||||
(ShapeCache.rg.rectangle(0, 0, element.width, element.height, {
|
|
||||||
roughness: 0,
|
|
||||||
strokeWidth: 2,
|
|
||||||
}) as Drawable);
|
|
||||||
|
|
||||||
// Clone the shape from the cache
|
|
||||||
shape = {
|
|
||||||
...shape,
|
|
||||||
options: {
|
|
||||||
...shape.options,
|
|
||||||
stroke: appState.theme === THEME.DARK ? "#035da1" : "#6abdfc",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates & caches shape for element if not already cached, otherwise
|
* Generates & caches shape for element if not already cached, otherwise
|
||||||
* returns cached shape.
|
* returns cached shape.
|
||||||
|
@@ -17,11 +17,7 @@ import {
|
|||||||
throttleRAF,
|
throttleRAF,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import {
|
import { LinearElementEditor, renderElement } from "@excalidraw/element";
|
||||||
LinearElementEditor,
|
|
||||||
renderElement,
|
|
||||||
ShapeCache,
|
|
||||||
} from "@excalidraw/element";
|
|
||||||
import {
|
import {
|
||||||
getOmitSidesForDevice,
|
getOmitSidesForDevice,
|
||||||
getTransformHandles,
|
getTransformHandles,
|
||||||
@@ -196,83 +192,71 @@ const renderBindingHighlightForBindableElement = (
|
|||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case "magicframe":
|
case "magicframe":
|
||||||
case "frame":
|
case "frame":
|
||||||
{
|
context.save();
|
||||||
const {
|
context.translate(
|
||||||
options: { stroke: highlightStroke },
|
element.x + appState.scrollX,
|
||||||
} = ShapeCache.generateBindableElementHighlight(element, appState);
|
element.y + appState.scrollY,
|
||||||
|
);
|
||||||
|
|
||||||
context.save();
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
||||||
context.translate(
|
context.strokeStyle =
|
||||||
element.x + appState.scrollX,
|
appState.theme === THEME.DARK ? "#035da1" : "#6abdfc";
|
||||||
element.y + appState.scrollY,
|
|
||||||
|
if (FRAME_STYLE.radius && context.roundRect) {
|
||||||
|
context.beginPath();
|
||||||
|
context.roundRect(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
element.width,
|
||||||
|
element.height,
|
||||||
|
FRAME_STYLE.radius / appState.zoom.value,
|
||||||
);
|
);
|
||||||
|
context.stroke();
|
||||||
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
context.closePath();
|
||||||
context.strokeStyle = highlightStroke;
|
} else {
|
||||||
|
context.strokeRect(0, 0, element.width, element.height);
|
||||||
if (FRAME_STYLE.radius && context.roundRect) {
|
|
||||||
context.beginPath();
|
|
||||||
context.roundRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
element.width,
|
|
||||||
element.height,
|
|
||||||
FRAME_STYLE.radius / appState.zoom.value,
|
|
||||||
);
|
|
||||||
context.stroke();
|
|
||||||
context.closePath();
|
|
||||||
} else {
|
|
||||||
context.strokeRect(0, 0, element.width, element.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.restore();
|
||||||
break;
|
break;
|
||||||
case "image":
|
case "image":
|
||||||
case "text":
|
case "text":
|
||||||
{
|
context.save();
|
||||||
const {
|
context.translate(
|
||||||
options: { stroke: highlightStroke },
|
element.x + appState.scrollX,
|
||||||
} = ShapeCache.generateBindableElementHighlight(element, appState);
|
element.y + appState.scrollY,
|
||||||
|
);
|
||||||
|
|
||||||
context.save();
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
||||||
context.translate(
|
context.strokeStyle =
|
||||||
element.x + appState.scrollX,
|
appState.theme === THEME.DARK ? "#035da1" : "#6abdfc";
|
||||||
element.y + appState.scrollY,
|
|
||||||
);
|
|
||||||
|
|
||||||
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
context.strokeRect(0, 0, element.width, element.height);
|
||||||
context.strokeStyle = highlightStroke;
|
context.restore();
|
||||||
|
|
||||||
context.strokeRect(0, 0, element.width, element.height);
|
|
||||||
context.restore();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
const cx =
|
renderElement(
|
||||||
(element.x + element.width / 2 + appState.scrollX) *
|
{
|
||||||
window.devicePixelRatio;
|
...element,
|
||||||
const cy =
|
strokeColor: appState.theme === THEME.DARK ? "#035da1" : "#6abdfc",
|
||||||
(element.y + element.height / 2 + appState.scrollY) *
|
fillStyle: "solid",
|
||||||
window.devicePixelRatio;
|
backgroundColor: "transparent",
|
||||||
context.save();
|
},
|
||||||
|
elementsMap,
|
||||||
context.translate(cx, cy);
|
allElementsMap,
|
||||||
context.rotate(element.angle);
|
rough.canvas(context.canvas),
|
||||||
context.translate(-cx, -cy);
|
context,
|
||||||
context.translate(
|
{
|
||||||
appState.scrollX + element.x,
|
canvasBackgroundColor: "transparent",
|
||||||
appState.scrollY + element.y,
|
imageCache: new Map(),
|
||||||
);
|
renderGrid: false,
|
||||||
|
isExporting: false,
|
||||||
const drawable = ShapeCache.generateBindableElementHighlight(
|
embedsValidationStatus: new Map(),
|
||||||
element,
|
elementsPendingErasure: new Set(),
|
||||||
|
pendingFlowchartNodes: null,
|
||||||
|
},
|
||||||
appState,
|
appState,
|
||||||
);
|
);
|
||||||
drawable.options.fill = "transparent";
|
|
||||||
rough.canvas(context.canvas).draw(drawable);
|
|
||||||
|
|
||||||
context.restore();
|
|
||||||
|
|
||||||
// Overdraw the arrow if exists (if there is a suggestedBinding it's an arrow)
|
// Overdraw the arrow if exists (if there is a suggestedBinding it's an arrow)
|
||||||
if (appState.selectedLinearElement) {
|
if (appState.selectedLinearElement) {
|
||||||
|
Reference in New Issue
Block a user