mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: IFrame and elbow arrow interaction fix (#9101)
This commit is contained in:
parent
b0c8c5f7a7
commit
9e49c9254b
3 changed files with 46 additions and 59 deletions
|
@ -32,7 +32,6 @@ import type { Bounds } from "./bounds";
|
||||||
import { getCenterForBounds, getElementAbsoluteCoords } from "./bounds";
|
import { getCenterForBounds, getElementAbsoluteCoords } from "./bounds";
|
||||||
import type { AppState } from "../types";
|
import type { AppState } from "../types";
|
||||||
import { isPointOnShape } from "../../utils/collision";
|
import { isPointOnShape } from "../../utils/collision";
|
||||||
import { getElementAtPosition } from "../scene";
|
|
||||||
import {
|
import {
|
||||||
isArrowElement,
|
isArrowElement,
|
||||||
isBindableElement,
|
isBindableElement,
|
||||||
|
@ -79,7 +78,6 @@ import {
|
||||||
clamp,
|
clamp,
|
||||||
} from "../../math";
|
} from "../../math";
|
||||||
import { segmentIntersectRectangleElement } from "../../utils/geometry/shape";
|
import { segmentIntersectRectangleElement } from "../../utils/geometry/shape";
|
||||||
import { getElementsAtPosition } from "../scene/comparisons";
|
|
||||||
|
|
||||||
export type SuggestedBinding =
|
export type SuggestedBinding =
|
||||||
| NonDeleted<ExcalidrawBindableElement>
|
| NonDeleted<ExcalidrawBindableElement>
|
||||||
|
@ -568,7 +566,7 @@ export const getHoveredElementForBinding = (
|
||||||
): NonDeleted<ExcalidrawBindableElement> | null => {
|
): NonDeleted<ExcalidrawBindableElement> | null => {
|
||||||
if (considerAllElements) {
|
if (considerAllElements) {
|
||||||
let cullRest = false;
|
let cullRest = false;
|
||||||
const candidateElements = getElementsAtPosition(
|
const candidateElements = getAllElementsAtPositionForBinding(
|
||||||
elements,
|
elements,
|
||||||
(element) =>
|
(element) =>
|
||||||
isBindableElement(element, false) &&
|
isBindableElement(element, false) &&
|
||||||
|
@ -622,7 +620,7 @@ export const getHoveredElementForBinding = (
|
||||||
.pop() as NonDeleted<ExcalidrawBindableElement>;
|
.pop() as NonDeleted<ExcalidrawBindableElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hoveredElement = getElementAtPosition(
|
const hoveredElement = getElementAtPositionForBinding(
|
||||||
elements,
|
elements,
|
||||||
(element) =>
|
(element) =>
|
||||||
isBindableElement(element, false) &&
|
isBindableElement(element, false) &&
|
||||||
|
@ -641,6 +639,50 @@ export const getHoveredElementForBinding = (
|
||||||
return hoveredElement as NonDeleted<ExcalidrawBindableElement> | null;
|
return hoveredElement as NonDeleted<ExcalidrawBindableElement> | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getElementAtPositionForBinding = (
|
||||||
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
|
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
||||||
|
) => {
|
||||||
|
let hitElement = null;
|
||||||
|
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
||||||
|
// because array is ordered from lower z-index to highest and we want element z-index
|
||||||
|
// with higher z-index
|
||||||
|
for (let index = elements.length - 1; index >= 0; --index) {
|
||||||
|
const element = elements[index];
|
||||||
|
if (element.isDeleted) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isAtPositionFn(element)) {
|
||||||
|
hitElement = element;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hitElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAllElementsAtPositionForBinding = (
|
||||||
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
|
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
||||||
|
) => {
|
||||||
|
const elementsAtPosition: NonDeletedExcalidrawElement[] = [];
|
||||||
|
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
||||||
|
// because array is ordered from lower z-index to highest and we want element z-index
|
||||||
|
// with higher z-index
|
||||||
|
for (let index = elements.length - 1; index >= 0; --index) {
|
||||||
|
const element = elements[index];
|
||||||
|
if (element.isDeleted) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAtPositionFn(element)) {
|
||||||
|
elementsAtPosition.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return elementsAtPosition;
|
||||||
|
};
|
||||||
|
|
||||||
const calculateFocusAndGap = (
|
const calculateFocusAndGap = (
|
||||||
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
||||||
hoveredElement: ExcalidrawBindableElement,
|
hoveredElement: ExcalidrawBindableElement,
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import { isIframeElement } from "../element/typeChecks";
|
|
||||||
import type {
|
|
||||||
ExcalidrawIframeElement,
|
|
||||||
NonDeletedExcalidrawElement,
|
|
||||||
} from "../element/types";
|
|
||||||
import type { ElementOrToolType } from "../types";
|
import type { ElementOrToolType } from "../types";
|
||||||
|
|
||||||
export const hasBackground = (type: ElementOrToolType) =>
|
export const hasBackground = (type: ElementOrToolType) =>
|
||||||
|
@ -47,51 +42,3 @@ export const canChangeRoundness = (type: ElementOrToolType) =>
|
||||||
export const toolIsArrow = (type: ElementOrToolType) => type === "arrow";
|
export const toolIsArrow = (type: ElementOrToolType) => type === "arrow";
|
||||||
|
|
||||||
export const canHaveArrowheads = (type: ElementOrToolType) => type === "arrow";
|
export const canHaveArrowheads = (type: ElementOrToolType) => type === "arrow";
|
||||||
|
|
||||||
export const getElementAtPosition = (
|
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
|
||||||
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
|
||||||
) => {
|
|
||||||
let hitElement = null;
|
|
||||||
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
|
||||||
// because array is ordered from lower z-index to highest and we want element z-index
|
|
||||||
// with higher z-index
|
|
||||||
for (let index = elements.length - 1; index >= 0; --index) {
|
|
||||||
const element = elements[index];
|
|
||||||
if (element.isDeleted) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isAtPositionFn(element)) {
|
|
||||||
hitElement = element;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hitElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getElementsAtPosition = (
|
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
|
||||||
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
|
||||||
) => {
|
|
||||||
const iframeLikes: ExcalidrawIframeElement[] = [];
|
|
||||||
const elementsAtPosition: NonDeletedExcalidrawElement[] = [];
|
|
||||||
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
|
||||||
// because array is ordered from lower z-index to highest and we want element z-index
|
|
||||||
// with higher z-index
|
|
||||||
for (let index = elements.length - 1; index >= 0; --index) {
|
|
||||||
const element = elements[index];
|
|
||||||
if (element.isDeleted) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isIframeElement(element)) {
|
|
||||||
iframeLikes.push(element);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isAtPositionFn(element)) {
|
|
||||||
elementsAtPosition.push(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return elementsAtPosition.concat(iframeLikes);
|
|
||||||
};
|
|
||||||
|
|
|
@ -12,8 +12,6 @@ export {
|
||||||
hasStrokeStyle,
|
hasStrokeStyle,
|
||||||
canHaveArrowheads,
|
canHaveArrowheads,
|
||||||
canChangeRoundness,
|
canChangeRoundness,
|
||||||
getElementAtPosition,
|
|
||||||
getElementsAtPosition,
|
|
||||||
} from "./comparisons";
|
} from "./comparisons";
|
||||||
export {
|
export {
|
||||||
getNormalizedZoom,
|
getNormalizedZoom,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue