feat: experiment with a diff shift locking behavior

This commit is contained in:
Ryan Di
2025-07-07 18:09:18 +10:00
parent a2cf15db9c
commit c79893608a
3 changed files with 52 additions and 11 deletions

View File

@ -124,6 +124,11 @@ export const getDefaultAppState = (): Omit<
searchMatches: null,
lockedMultiSelections: {},
activeLockedId: null,
cropPositionMovement: {
enabled: false,
croppingElementId: undefined,
directionLock: null,
},
};
};
@ -249,6 +254,7 @@ const APP_STATE_STORAGE_CONF = (<
searchMatches: { browser: false, export: false, server: false },
lockedMultiSelections: { browser: true, export: true, server: true },
activeLockedId: { browser: false, export: false, server: false },
cropPositionMovement: { browser: false, export: false, server: false },
});
const _clearAppStateForStorage = <

View File

@ -6994,6 +6994,8 @@ class App extends React.Component<AppProps, AppState> {
},
cropPositionMovement: {
enabled: false,
croppingElementId: undefined,
directionLock: null,
},
};
}
@ -8134,20 +8136,47 @@ class App extends React.Component<AppProps, AppState> {
};
// apply shift key constraint for directional movement
const threshold = 20;
let snappingToOrigin = false;
if (event.shiftKey) {
const distanceX = Math.abs(totalDragOffset.x);
const distanceY = Math.abs(totalDragOffset.y);
const lockX = distanceX < distanceY;
const lockY = distanceX > distanceY;
if (lockX) {
totalDragOffset.x = 0;
if (!pointerDownState.cropPositionMovement.directionLock) {
if (
Math.abs(totalDragOffset.x) > threshold ||
Math.abs(totalDragOffset.y) > threshold
) {
pointerDownState.cropPositionMovement.directionLock =
Math.abs(totalDragOffset.x) > Math.abs(totalDragOffset.y)
? "x"
: "y";
} else {
// if within threshold and not locked, always snap to origin
snappingToOrigin = true;
}
} else {
// if user moves back within threshold, unlock and snap back
if (
Math.abs(totalDragOffset.x) < threshold &&
Math.abs(totalDragOffset.y) < threshold
) {
pointerDownState.cropPositionMovement.directionLock = null;
snappingToOrigin = true;
}
}
} else {
pointerDownState.cropPositionMovement.directionLock = null;
}
if (lockY) {
if (snappingToOrigin) {
totalDragOffset.x = 0;
totalDragOffset.y = 0;
}
if (pointerDownState.cropPositionMovement.directionLock === "x") {
totalDragOffset.y = 0;
} else if (
pointerDownState.cropPositionMovement.directionLock === "y"
) {
totalDragOffset.x = 0;
}
// scale the drag offset

View File

@ -444,6 +444,11 @@ 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 };
cropPositionMovement: {
croppingElementId?: string;
enabled: boolean;
directionLock: "x" | "y" | null;
};
}
export type SearchMatch = {
@ -800,6 +805,7 @@ export type PointerDownState = Readonly<{
cropPositionMovement: {
croppingElementId?: string;
enabled: boolean;
directionLock: "x" | "y" | null;
};
}>;