mirror of
https://github.com/excalidraw/excalidraw
synced 2025-07-25 13:58:22 +08:00
Turn off inside binding mode after leaving a shape
This commit is contained in:
@ -247,7 +247,7 @@ const bindingStrategyForEndpointDragging = (
|
||||
|
||||
// If the global bind mode is in free binding mode, just bind
|
||||
// where the pointer is and keep the other end intact
|
||||
if (globalBindMode === "fixed") {
|
||||
if (globalBindMode === "inside") {
|
||||
current = hovered
|
||||
? { element: hovered, mode: hit ? "inside" : "outside" }
|
||||
: { mode: undefined };
|
||||
|
@ -1992,7 +1992,7 @@ const pointDraggingUpdates = (
|
||||
isBindingEnabled(appState) &&
|
||||
isArrowElement(element) &&
|
||||
hoveredElement &&
|
||||
appState.bindMode === "focus" &&
|
||||
appState.bindMode === "orbit" &&
|
||||
!otherPointInsideElement
|
||||
) {
|
||||
newGlobalPointPosition = getOutlineAvoidingPoint(
|
||||
|
@ -1720,7 +1720,7 @@ export const actionChangeArrowType = register({
|
||||
bindBindingElement(
|
||||
newElement,
|
||||
startElement,
|
||||
appState.bindMode === "fixed" ? "inside" : "orbit",
|
||||
appState.bindMode === "inside" ? "inside" : "orbit",
|
||||
"start",
|
||||
app.scene,
|
||||
);
|
||||
@ -1734,7 +1734,7 @@ export const actionChangeArrowType = register({
|
||||
bindBindingElement(
|
||||
newElement,
|
||||
endElement,
|
||||
appState.bindMode === "fixed" ? "inside" : "orbit",
|
||||
appState.bindMode === "inside" ? "inside" : "orbit",
|
||||
"end",
|
||||
app.scene,
|
||||
);
|
||||
|
@ -124,7 +124,7 @@ export const getDefaultAppState = (): Omit<
|
||||
searchMatches: null,
|
||||
lockedMultiSelections: {},
|
||||
activeLockedId: null,
|
||||
bindMode: "focus",
|
||||
bindMode: "orbit",
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -4326,7 +4326,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
|
||||
// Handle Alt key for bind mode
|
||||
if (event.key === KEYS.ALT && this.state.bindMode === "focus") {
|
||||
if (event.key === KEYS.ALT && this.state.bindMode === "orbit") {
|
||||
// Cancel any pending bind mode timer
|
||||
if (this.bindModeHandler) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
@ -4647,7 +4647,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
) {
|
||||
// Handle Alt key release for bind mode
|
||||
this.setState({
|
||||
bindMode: "focus",
|
||||
bindMode: "orbit",
|
||||
});
|
||||
|
||||
// Restart the timer if we're creating/editing a linear element and hovering over an element
|
||||
@ -4670,9 +4670,9 @@ class App extends React.Component<AppProps, AppState> {
|
||||
if (hoveredElement && !this.bindModeHandler) {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
// this.setState({
|
||||
// bindMode: "fixed",
|
||||
// });
|
||||
this.setState({
|
||||
bindMode: "inside",
|
||||
});
|
||||
} else {
|
||||
this.bindModeHandler = null;
|
||||
}
|
||||
@ -5999,10 +5999,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
if (arrowWithoutUncommittedPoint || this.state.newElement) {
|
||||
// Timed bind mode handler for arrow elements
|
||||
if (
|
||||
isArrowElement(this.state.newElement) &&
|
||||
this.state.bindMode === "focus"
|
||||
) {
|
||||
if (isArrowElement(this.state.newElement)) {
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
pointFrom<GlobalPoint>(scenePointer.x, scenePointer.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
@ -6010,48 +6007,56 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.state.zoom,
|
||||
);
|
||||
|
||||
if (this.bindModeHandler && !hoveredElement) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
this.bindModeHandler = null;
|
||||
} else if (!this.bindModeHandler && hoveredElement) {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
flushSync(() => {
|
||||
// this.setState({
|
||||
// bindMode: "fixed",
|
||||
// });
|
||||
});
|
||||
if (this.state.bindMode === "orbit") {
|
||||
if (this.bindModeHandler && !hoveredElement) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
this.bindModeHandler = null;
|
||||
} else if (!this.bindModeHandler && hoveredElement) {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "inside",
|
||||
});
|
||||
});
|
||||
|
||||
if (isArrowElement(this.state.newElement)) {
|
||||
const lastSceneCoords = viewportCoordsToSceneCoords(
|
||||
{
|
||||
clientX: this.lastPointerMoveEvent?.clientX ?? 0,
|
||||
clientY: this.lastPointerMoveEvent?.clientY ?? 0,
|
||||
},
|
||||
this.state,
|
||||
);
|
||||
this.scene.mutateElement(
|
||||
this.state.newElement,
|
||||
{
|
||||
points: [
|
||||
...this.state.newElement.points.slice(0, -1),
|
||||
LinearElementEditor.pointFromAbsoluteCoords(
|
||||
this.state.newElement,
|
||||
pointFrom<GlobalPoint>(
|
||||
lastSceneCoords.x,
|
||||
lastSceneCoords.y,
|
||||
if (isArrowElement(this.state.newElement)) {
|
||||
const lastSceneCoords = viewportCoordsToSceneCoords(
|
||||
{
|
||||
clientX: this.lastPointerMoveEvent?.clientX ?? 0,
|
||||
clientY: this.lastPointerMoveEvent?.clientY ?? 0,
|
||||
},
|
||||
this.state,
|
||||
);
|
||||
this.scene.mutateElement(
|
||||
this.state.newElement,
|
||||
{
|
||||
points: [
|
||||
...this.state.newElement.points.slice(0, -1),
|
||||
LinearElementEditor.pointFromAbsoluteCoords(
|
||||
this.state.newElement,
|
||||
pointFrom<GlobalPoint>(
|
||||
lastSceneCoords.x,
|
||||
lastSceneCoords.y,
|
||||
),
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
),
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
),
|
||||
],
|
||||
},
|
||||
{ informMutation: false, isDragging: false },
|
||||
);
|
||||
],
|
||||
},
|
||||
{ informMutation: false, isDragging: false },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.bindModeHandler = null;
|
||||
}
|
||||
} else {
|
||||
this.bindModeHandler = null;
|
||||
}
|
||||
}, BIND_MODE_TIMEOUT);
|
||||
}, BIND_MODE_TIMEOUT);
|
||||
}
|
||||
} else if (!hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "orbit",
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -6135,7 +6140,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
if (
|
||||
isArrowElement(multiElement) &&
|
||||
this.state.bindMode === "focus" &&
|
||||
this.state.bindMode === "orbit" &&
|
||||
isBindingEnabled(this.state)
|
||||
) {
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
@ -6923,13 +6928,13 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.lastPointerUpEvent = event;
|
||||
|
||||
// Cancel any pending timeout for bind mode change
|
||||
if (this.state.bindMode === "fixed" || this.state.bindMode === "skip") {
|
||||
if (this.state.bindMode === "inside" || this.state.bindMode === "skip") {
|
||||
if (this.bindModeHandler) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
}
|
||||
this.bindModeHandler = null;
|
||||
this.setState({
|
||||
bindMode: "focus",
|
||||
bindMode: "orbit",
|
||||
});
|
||||
}
|
||||
|
||||
@ -8579,15 +8584,15 @@ class App extends React.Component<AppProps, AppState> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Timed bind mode handler for arrow elements
|
||||
if (this.state.bindMode === "focus") {
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
);
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
);
|
||||
|
||||
// Timed bind mode handler for arrow elements
|
||||
if (this.state.bindMode === "orbit") {
|
||||
if (this.bindModeHandler && !hoveredElement) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
this.bindModeHandler = null;
|
||||
@ -8595,9 +8600,9 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
flushSync(() => {
|
||||
// this.setState({
|
||||
// bindMode: "fixed",
|
||||
// });
|
||||
this.setState({
|
||||
bindMode: "inside",
|
||||
});
|
||||
});
|
||||
const newState = LinearElementEditor.handlePointDragging(
|
||||
event,
|
||||
@ -8620,6 +8625,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
}, BIND_MODE_TIMEOUT);
|
||||
}
|
||||
} else if (!hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "orbit",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const newState = LinearElementEditor.handlePointDragging(
|
||||
@ -9104,7 +9115,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
if (!arrowEndpointsAboutToBindToSameElement) {
|
||||
const [targetPointX, targetPointY] =
|
||||
this.state.bindMode === "focus" && isBindingEnabled(this.state)
|
||||
this.state.bindMode === "orbit" && isBindingEnabled(this.state)
|
||||
? getOutlineAvoidingPoint(
|
||||
newElement,
|
||||
hoveredElement,
|
||||
@ -9462,7 +9473,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
this.setState({
|
||||
selectedElementsAreBeingDragged: false,
|
||||
bindMode: "focus",
|
||||
bindMode: "orbit",
|
||||
});
|
||||
|
||||
if (
|
||||
|
@ -444,7 +444,7 @@ export interface AppState {
|
||||
// as elements are unlocked, we remove the groupId from the elements
|
||||
// and also remove groupId from this map
|
||||
lockedMultiSelections: { [groupId: string]: true };
|
||||
bindMode: "focus" | "fixed" | "skip";
|
||||
bindMode: "orbit" | "inside" | "skip";
|
||||
}
|
||||
|
||||
export type SearchMatch = {
|
||||
|
Reference in New Issue
Block a user