fix: Increase transform handle offset (#10180)

* fix: Increase transform handle offset

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* fix: Temporarily disable transform handles for linear elements on mobile and tablets

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* fix: Linear hidden resize

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* disable mobielOrTablet linear element bbox completely

* fix: Test

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* fix: Lint

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

---------

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
Márk Tolmács
2025-10-15 21:16:20 +02:00
committed by GitHub
parent 5fffc4743f
commit 7da176ff7d
4 changed files with 24 additions and 23 deletions

View File

@@ -2,6 +2,7 @@ import {
DEFAULT_TRANSFORM_HANDLE_SPACING,
isAndroid,
isIOS,
isMobileOrTablet,
} from "@excalidraw/common";
import { pointFrom, pointRotateRads } from "@excalidraw/math";
@@ -326,7 +327,7 @@ export const getTransformHandles = (
);
};
export const shouldShowBoundingBox = (
export const hasBoundingBox = (
elements: readonly NonDeletedExcalidrawElement[],
appState: InteractiveCanvasAppState,
) => {
@@ -345,5 +346,7 @@ export const shouldShowBoundingBox = (
return true;
}
return element.points.length > 2;
// on mobile/tablet we currently don't show bbox because of resize issues
// (also prob best for simplicity's sake)
return element.points.length > 2 && !isMobileOrTablet();
};

View File

@@ -10,6 +10,8 @@ import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { UI, Pointer, Keyboard } from "@excalidraw/excalidraw/tests/helpers/ui";
import { fireEvent, render } from "@excalidraw/excalidraw/tests/test-utils";
import { LinearElementEditor } from "@excalidraw/element";
import { getTransformHandles } from "../src/transformHandles";
import {
getTextEditor,
@@ -413,16 +415,12 @@ describe("element binding", () => {
expect(arrow.endBinding?.elementId).toBe(rectRight.id);
// Drag arrow off of bound rectangle range
const handles = getTransformHandles(
const [elX, elY] = LinearElementEditor.getPointAtIndexGlobalCoordinates(
arrow,
h.state.zoom,
arrayToMap(h.elements),
"mouse",
).se!;
-1,
h.scene.getNonDeletedElementsMap(),
);
Keyboard.keyDown(KEYS.CTRL_OR_CMD);
const elX = handles[0] + handles[2] / 2;
const elY = handles[1] + handles[3] / 2;
mouse.downAt(elX, elY);
mouse.moveTo(300, 400);
mouse.up();

View File

@@ -173,7 +173,7 @@ import {
getContainerElement,
isValidTextContainer,
redrawTextBoundingBox,
shouldShowBoundingBox,
hasBoundingBox,
getFrameChildren,
isCursorInFrame,
addElementsToFrame,
@@ -5262,7 +5262,7 @@ class App extends React.Component<AppProps, AppState> {
if (
considerBoundingBox &&
this.state.selectedElementIds[element.id] &&
shouldShowBoundingBox([element], this.state)
hasBoundingBox([element], this.state)
) {
// if hitting the bounding box, return early
// but if not, we should check for other cases as well (e.g. frame name)
@@ -6165,7 +6165,13 @@ class App extends React.Component<AppProps, AppState> {
(!this.state.selectedLinearElement ||
this.state.selectedLinearElement.hoverPointIndex === -1) &&
this.state.openDialog?.name !== "elementLinkSelector" &&
!(selectedElements.length === 1 && isElbowArrow(selectedElements[0]))
!(selectedElements.length === 1 && isElbowArrow(selectedElements[0])) &&
// HACK: Disable transform handles for linear elements on mobile until a
// better way of showing them is found
!(
isLinearElement(selectedElements[0]) &&
(isMobileOrTablet() || selectedElements[0].points.length === 2)
)
) {
const elementWithTransformHandleType =
getElementWithTransformHandleType(
@@ -7285,14 +7291,8 @@ class App extends React.Component<AppProps, AppState> {
!this.state.selectedLinearElement?.isEditing &&
!isElbowArrow(selectedElements[0]) &&
!(
isLineElement(selectedElements[0]) &&
LinearElementEditor.getPointIndexUnderCursor(
selectedElements[0],
elementsMap,
this.state.zoom,
pointerDownState.origin.x,
pointerDownState.origin.y,
) !== -1
isLinearElement(selectedElements[0]) &&
(isMobileOrTablet() || selectedElements[0].points.length === 2)
) &&
!(
this.state.selectedLinearElement &&

View File

@@ -22,7 +22,7 @@ import {
getOmitSidesForDevice,
getTransformHandles,
getTransformHandlesFromCoords,
shouldShowBoundingBox,
hasBoundingBox,
} from "@excalidraw/element";
import {
isElbowArrow,
@@ -892,7 +892,7 @@ const _renderInteractiveScene = ({
// Paint selected elements
if (!appState.multiElement && !appState.selectedLinearElement?.isEditing) {
const showBoundingBox = shouldShowBoundingBox(selectedElements, appState);
const showBoundingBox = hasBoundingBox(selectedElements, appState);
const isSingleLinearElementSelected =
selectedElements.length === 1 && isLinearElement(selectedElements[0]);