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