fix: Add back transparency check for bindables
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -10,7 +10,6 @@ import {
|
||||
getBindingGap,
|
||||
getGlobalFixedPointForBindableElement,
|
||||
isBindingEnabled,
|
||||
maxBindingDistance_simple,
|
||||
unbindBindingElement,
|
||||
updateBoundPoint,
|
||||
} from "../binding";
|
||||
@@ -239,7 +238,7 @@ export const handleFocusPointDrag = (
|
||||
point,
|
||||
scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(appState.zoom),
|
||||
appState.zoom,
|
||||
);
|
||||
|
||||
// Hovering a bindable element
|
||||
|
||||
@@ -274,7 +274,7 @@ const bindingStrategyForElbowArrowEndpointDragging = (
|
||||
globalPoint,
|
||||
elements,
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(zoom),
|
||||
zoom,
|
||||
);
|
||||
|
||||
const current = hit
|
||||
@@ -705,7 +705,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
|
||||
globalPoint,
|
||||
elements,
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(appState.zoom),
|
||||
appState.zoom,
|
||||
);
|
||||
const pointInElement =
|
||||
hit &&
|
||||
|
||||
@@ -25,7 +25,7 @@ import type {
|
||||
Radians,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
|
||||
import type { AppState, FrameNameBounds } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { isPathALoop } from "./utils";
|
||||
import {
|
||||
@@ -59,7 +59,7 @@ import { LinearElementEditor } from "./linearElementEditor";
|
||||
|
||||
import { distanceToElement } from "./distance";
|
||||
|
||||
import { getBindingGap } from "./binding";
|
||||
import { getBindingGap, maxBindingDistance_simple } from "./binding";
|
||||
|
||||
import { hasBackground } from "./comparisons";
|
||||
|
||||
@@ -253,7 +253,7 @@ export const hitElementBoundText = (
|
||||
return isPointInElement(point, boundTextElement, elementsMap);
|
||||
};
|
||||
|
||||
const borderDistance = (
|
||||
const bindableElementBorderDistanceIfClose = (
|
||||
element: NonDeleted<ExcalidrawBindableElement>,
|
||||
point: GlobalPoint,
|
||||
elementsMap: ElementsMap,
|
||||
@@ -339,12 +339,16 @@ export const getHoveredElementForBinding = (
|
||||
point: Readonly<GlobalPoint>,
|
||||
elements: readonly Ordered<NonDeletedExcalidrawElement>[],
|
||||
elementsMap: NonDeletedSceneElementsMap,
|
||||
tolerance?: number,
|
||||
zoom?: AppState["zoom"],
|
||||
): NonDeleted<ExcalidrawBindableElement> | null => {
|
||||
const candidateElements: {
|
||||
type Candidate = {
|
||||
element: NonDeleted<ExcalidrawBindableElement>;
|
||||
distance: number;
|
||||
}[] = [];
|
||||
overlapPercent?: number;
|
||||
relativeArea?: number;
|
||||
};
|
||||
|
||||
const candidates: Candidate[] = [];
|
||||
for (let index = elements.length - 1; index >= 0; --index) {
|
||||
const element = elements[index];
|
||||
|
||||
@@ -352,38 +356,42 @@ export const getHoveredElementForBinding = (
|
||||
continue;
|
||||
}
|
||||
|
||||
const distance = borderDistance(
|
||||
const maxDistance = maxBindingDistance_simple(zoom);
|
||||
const distance = bindableElementBorderDistanceIfClose(
|
||||
element,
|
||||
point,
|
||||
elementsMap,
|
||||
tolerance ?? 0,
|
||||
maxDistance,
|
||||
);
|
||||
const bindingGap = getBindingGap(element, arrow);
|
||||
|
||||
if (distance > -(tolerance ?? bindingGap)) {
|
||||
candidateElements.push({ element, distance });
|
||||
if (distance > -maxDistance) {
|
||||
candidates.push({ element, distance });
|
||||
|
||||
if (!isTransparent(element.backgroundColor) && distance >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateElements.length === 0) {
|
||||
if (candidates.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (candidateElements.length === 1) {
|
||||
return candidateElements[0].element;
|
||||
if (candidates.length === 1) {
|
||||
return candidates[0].element;
|
||||
}
|
||||
|
||||
const closestDistance = candidateElements.sort(
|
||||
const closestElements = candidates.sort(
|
||||
(a, b) => Math.abs(a.distance) - Math.abs(b.distance),
|
||||
);
|
||||
|
||||
const candidate = closestDistance[0];
|
||||
const candidate = closestElements[0];
|
||||
const [cx1, cy1, cx2, cy2] = getElementBounds(candidate.element, elementsMap);
|
||||
const candidateArea = Math.max(
|
||||
0.00001,
|
||||
Math.abs(cx2 - cx1) * Math.abs(cy2 - cy1),
|
||||
);
|
||||
const overlaps = closestDistance
|
||||
const overlaps = closestElements
|
||||
.map((c) => {
|
||||
if (c.element === candidate.element) {
|
||||
return { ...c, overlapPercent: 0, relativeArea: 1 };
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
getHeadingForElbowArrowSnap,
|
||||
getGlobalFixedPointForBindableElement,
|
||||
getBindingGap,
|
||||
maxBindingDistance_simple,
|
||||
BASE_BINDING_GAP_ELBOW,
|
||||
} from "./binding";
|
||||
import { distanceToElement } from "./distance";
|
||||
@@ -2286,7 +2285,7 @@ const getHoveredElement = (
|
||||
origPoint,
|
||||
elements,
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(zoom),
|
||||
zoom,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -250,7 +250,6 @@ import {
|
||||
getElementBounds,
|
||||
doBoundsIntersect,
|
||||
isPointInElement,
|
||||
maxBindingDistance_simple,
|
||||
convertToExcalidrawElements,
|
||||
type ExcalidrawElementSkeleton,
|
||||
getSnapOutlineMidPoint,
|
||||
@@ -7092,7 +7091,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom<GlobalPoint>(scenePointerX, scenePointerY),
|
||||
this.scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(this.state.zoom),
|
||||
this.state.zoom,
|
||||
);
|
||||
if (hoveredElement) {
|
||||
this.setState({
|
||||
@@ -7132,7 +7131,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom<GlobalPoint>(scenePointerX, scenePointerY),
|
||||
this.scene.getNonDeletedElements(),
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
maxBindingDistance_simple(this.state.zoom),
|
||||
this.state.zoom,
|
||||
);
|
||||
if (hoveredElement) {
|
||||
this.actionManager.executeAction(actionFinalize, "ui", {
|
||||
@@ -7284,7 +7283,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom<GlobalPoint>(scenePointerX, scenePointerY),
|
||||
this.scene.getNonDeletedElements(),
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
maxBindingDistance_simple(this.state.zoom),
|
||||
this.state.zoom,
|
||||
);
|
||||
const scenePointer = pointFrom<GlobalPoint>(scenePointerX, scenePointerY);
|
||||
const elementsMap = this.scene.getNonDeletedElementsMap();
|
||||
@@ -9893,7 +9892,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
maxBindingDistance_simple(this.state.zoom),
|
||||
this.state.zoom,
|
||||
);
|
||||
|
||||
this.handleDelayedBindModeChange(element, hoveredElement);
|
||||
|
||||
Reference in New Issue
Block a user