Skip to content

Commit 90988f5

Browse files
committed
Refactored resize logic
1 parent 3f1e77d commit 90988f5

File tree

4 files changed

+71
-146
lines changed

4 files changed

+71
-146
lines changed

src/core-resizing.ts

Lines changed: 56 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SyntheticEvent } from "react";
2-
import { ISpaceDefinition, ISize, ResizeType, ISpaceStore, OnResizeEnd, Type, EndEvent, MoveEvent } from "./core-types";
3-
import { throttle, coalesce } from "./core-utils";
2+
import { ISpaceDefinition, ResizeType, ISpaceStore, OnResizeEnd, EndEvent, MoveEvent } from "./core-types";
3+
import { throttle } from "./core-utils";
44

55
const RESIZE_THROTTLE = 0;
66

@@ -9,167 +9,95 @@ export interface IResizeChange {
99
y: number;
1010
}
1111

12-
function customSizeHoriz(space: ISpaceDefinition, adjust: number) {
13-
if (space.width.size) {
14-
space.width.resized = -adjust;
15-
}
12+
function isHorizontal(resizeType: ResizeType) {
13+
return resizeType === ResizeType.Left || resizeType === ResizeType.Right;
1614
}
1715

18-
function customSizeVert(space: ISpaceDefinition, adjust: number) {
19-
if (space.height.size) {
20-
space.height.resized = -adjust;
21-
}
22-
}
16+
type ResizeAdjuster = (currentX: number, currentY: number) => void;
17+
18+
function createAdjuster(resizeType: ResizeType, space: ISpaceDefinition, originalX: number, originalY: number): ResizeAdjuster {
19+
const dimensionToAdjust = (() => {
20+
if (resizeType === ResizeType.Left) {
21+
return space.left;
22+
} else if (resizeType === ResizeType.Right) {
23+
return space.right;
24+
} else if (resizeType === ResizeType.Bottom) {
25+
return space.bottom;
26+
} else if (resizeType === ResizeType.Top) {
27+
return space.top;
28+
} else {
29+
throw new Error("unknown resize type");
30+
}
31+
})();
2332

24-
function getCustomSizing(resizeType: ResizeType, space: ISpaceDefinition) {
25-
if (resizeType === ResizeType.Left) {
26-
return space.type === Type.Positioned ? (a: number) => customSizeHoriz(space, a) : undefined;
27-
} else if (resizeType === ResizeType.Right) {
28-
return space.type === Type.Positioned ? (space.width.size ? undefined : (a: number) => customSizeHoriz(space, a)) : undefined;
29-
} else if (resizeType === ResizeType.Top) {
30-
return space.type === Type.Positioned ? (a: number) => customSizeVert(space, a) : undefined;
31-
} else if (resizeType === ResizeType.Bottom) {
32-
return space.type === Type.Positioned ? (space.height.size ? undefined : (a: number) => customSizeVert(space, a)) : undefined;
33-
}
34-
throw new Error("unknown resize type");
35-
}
33+
const negater = resizeType === ResizeType.Right || resizeType === ResizeType.Bottom ? (val: number) => -val : (val: number) => val;
3634

37-
function getTargetSize(resizeType: ResizeType, space: ISpaceDefinition) {
38-
if (resizeType === ResizeType.Left) {
39-
return space.type === Type.Positioned ? space.left : space.width;
40-
} else if (resizeType === ResizeType.Right) {
41-
return space.type === Type.Positioned ? (space.width.size ? space.width : space.right) : space.width;
42-
} else if (resizeType === ResizeType.Top) {
43-
return space.type === Type.Positioned ? space.top : space.height;
44-
} else if (resizeType === ResizeType.Bottom) {
45-
return space.type === Type.Positioned ? (space.height.size ? space.height : space.bottom) : space.height;
46-
}
47-
throw new Error("unknown resize type");
48-
}
35+
const candidateOppositeDimensionToAdjust = isHorizontal(resizeType) ? space.width : space.height;
4936

50-
function getResizeType(resizeType: ResizeType, space: ISpaceDefinition) {
51-
if (resizeType === ResizeType.Left) {
52-
return ResizeType.Left;
53-
} else if (resizeType === ResizeType.Right) {
54-
return space.type === Type.Positioned ? (space.width.size ? ResizeType.Left : ResizeType.Right) : ResizeType.Right;
55-
} else if (resizeType === ResizeType.Top) {
56-
return ResizeType.Top;
57-
} else if (resizeType === ResizeType.Bottom) {
58-
return space.type === Type.Positioned ? (space.height.size ? ResizeType.Top : ResizeType.Bottom) : ResizeType.Bottom;
59-
}
60-
throw new Error("unknown resize type");
61-
}
37+
const offset1 = dimensionToAdjust.resized;
38+
const offset2 = candidateOppositeDimensionToAdjust.resized;
6239

63-
function getCustomOriginal(resizeType: ResizeType, space: ISpaceDefinition) {
64-
if (resizeType === ResizeType.Left) {
65-
return space.width.size ? -space.width.resized : 0;
66-
} else if (resizeType === ResizeType.Right) {
67-
return 0;
68-
} else if (resizeType === ResizeType.Top) {
69-
return space.height.size ? -space.height.resized : 0;
70-
} else if (resizeType === ResizeType.Bottom) {
71-
return 0;
72-
}
73-
throw new Error("unknown resize type");
74-
}
40+
// const rect = space.element.getBoundingClientRect();
41+
// const size = isHorizontal(resizeType) ? rect.width : rect.height;
42+
// const minimumAdjust = coalesce(space.minimumSize, 20)! - size + 0;
43+
// const maximumAdjust = space.maximumSize ? space.maximumSize - size + 0 : undefined;
7544

76-
export function createResize(store: ISpaceStore) {
77-
function onResize(
78-
space: ISpaceDefinition,
79-
targetSize: ISize,
80-
resizeType: ResizeType,
81-
startSize: number,
82-
originalX: number,
83-
originalY: number,
84-
customOriginal: number,
85-
x: number,
86-
y: number,
87-
minimumAdjust: number,
88-
maximumAdjust: number | undefined,
89-
customAdjust?: (adjustment: number) => void,
90-
) {
91-
let adjustment =
92-
startSize +
93-
(resizeType === ResizeType.Left || resizeType === ResizeType.Right
94-
? resizeType === ResizeType.Left
95-
? x - originalX
96-
: originalX - x
97-
: resizeType === ResizeType.Top
98-
? y - originalY
99-
: originalY - y);
100-
101-
if (adjustment < minimumAdjust) {
102-
adjustment = minimumAdjust;
103-
} else {
104-
if (typeof maximumAdjust === "number") {
105-
if (adjustment > maximumAdjust) {
106-
adjustment = maximumAdjust;
107-
}
108-
}
109-
}
45+
return (currentX: number, currentY: number) => {
46+
const adjustment = (isHorizontal(resizeType) ? originalX : originalY) - (isHorizontal(resizeType) ? currentX : currentY);
11047

111-
if (adjustment !== targetSize.resized) {
112-
targetSize.resized = adjustment;
48+
// if (adjustment < minimumAdjust) {
49+
// adjustment = minimumAdjust;
50+
// } else {
51+
// if (typeof maximumAdjust === "number") {
52+
// if (adjustment > maximumAdjust) {
53+
// adjustment = maximumAdjust;
54+
// }
55+
// }
56+
// }
11357

114-
if (customAdjust) {
115-
customAdjust(adjustment + customOriginal);
58+
if (dimensionToAdjust.size !== undefined) {
59+
dimensionToAdjust.resized = negater(-adjustment) + offset1;
60+
if (candidateOppositeDimensionToAdjust.size) {
61+
candidateOppositeDimensionToAdjust.resized = negater(adjustment) + offset2;
11662
}
117-
118-
store.updateStyles(space);
63+
} else {
64+
candidateOppositeDimensionToAdjust.resized = negater(adjustment) + offset2;
11965
}
120-
}
66+
};
67+
}
12168

69+
export function createResize(store: ISpaceStore) {
12270
return {
12371
startResize<T extends SyntheticEvent<HTMLElement> | MouseEvent | TouchEvent>(
12472
e: T,
125-
resizeHandleType: ResizeType,
73+
resizeType: ResizeType,
12674
space: ISpaceDefinition,
12775
endEvent: EndEvent,
12876
moveEvent: MoveEvent,
12977
getCoords: (event: T) => { x: number; y: number },
13078
onResizeEnd?: OnResizeEnd,
13179
) {
13280
if (space.onResizeStart) {
133-
const result = space.onResizeStart();
81+
const result = space.onResizeStart(resizeType);
13482
if (typeof result === "boolean" && !result) {
13583
return;
13684
}
13785
}
13886

13987
const originalCoords = getCoords(e);
140-
const resizeType = getResizeType(resizeHandleType, space);
141-
const customAdjust = getCustomSizing(resizeHandleType, space);
142-
const targetSize = getTargetSize(resizeHandleType, space);
143-
const customOriginal = getCustomOriginal(resizeHandleType, space) - targetSize.resized;
88+
const adjuster = createAdjuster(resizeType, space, originalCoords.x, originalCoords.y);
14489

14590
space.resizing = true;
14691
space.updateParent();
14792

148-
const rect = space.element.getBoundingClientRect();
149-
const size = resizeType === ResizeType.Left || resizeType === ResizeType.Right ? rect.width : rect.height;
150-
const startSize = targetSize.resized;
151-
const minimumAdjust = coalesce(space.minimumSize, 20)! - size + targetSize.resized;
152-
const maximumAdjust = space.maximumSize ? space.maximumSize - size + targetSize.resized : undefined;
153-
15493
let lastX = 0;
15594
let lastY = 0;
15695
let moved = false;
15796

158-
const resize = (x: number, y: number) =>
159-
onResize(
160-
space,
161-
targetSize,
162-
resizeType,
163-
startSize,
164-
originalCoords.x,
165-
originalCoords.y,
166-
customOriginal,
167-
x,
168-
y,
169-
minimumAdjust,
170-
maximumAdjust,
171-
customAdjust,
172-
);
97+
const resize = (currentX: number, currentY: number) => {
98+
adjuster(currentX, currentY);
99+
store.updateStyles(space);
100+
};
173101

174102
const withPreventDefault = (e: T) => {
175103
moved = true;
@@ -194,10 +122,7 @@ export function createResize(store: ISpaceStore) {
194122
const resizeEnd = onResizeEnd || space.onResizeEnd;
195123
if (resizeEnd) {
196124
const currentRect = space.element.getBoundingClientRect();
197-
resizeEnd(
198-
Math.floor(resizeType === ResizeType.Left || resizeType === ResizeType.Right ? currentRect.width : currentRect.height),
199-
currentRect as DOMRect,
200-
);
125+
resizeEnd(Math.floor(isHorizontal(resizeType) ? currentRect.width : currentRect.height), currentRect as DOMRect, resizeType);
201126
}
202127
};
203128

src/core-types.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export type ResizeMouseEvent = React.MouseEvent<HTMLElement, MouseEvent>;
2-
export type OnResizeStart = (() => void | boolean) | undefined;
3-
export type OnResizeEnd = ((newSize: SizeUnit, domRect: DOMRect) => void) | undefined;
2+
export type OnResizeStart = ((resizeType?: ResizeType) => void | boolean) | undefined;
3+
export type OnResizeEnd = ((newSize: SizeUnit, domRect: DOMRect, resizeType?: ResizeType) => void) | undefined;
44
export type OnDragEnd = (position: IPosition, moved: boolean) => void;
55

66
export enum Type {
@@ -31,10 +31,10 @@ export enum ResizeType {
3131
Right = "resize-right",
3232
Top = "resize-top",
3333
Bottom = "resize-bottom",
34-
NW = "resize-nw",
35-
NE = "resize-ne",
36-
SW = "resize-sw",
37-
SE = "resize-se",
34+
TopLeft = "resize-topleft",
35+
TopRight = "resize-topright",
36+
BottomLeft = "resize-bottomleft",
37+
BottomRight = "resize-bottomright",
3838
}
3939

4040
export enum ResizeHandlePlacement {

src/core-utils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ export function styleDefinition(space: ISpaceDefinition) {
150150
space.top,
151151
)}; bottom: ${css(space.bottom)}; height: ${css(space.height)}; }`,
152152
);
153-
cssElements.push(`#${space.id}-ml:after { left: -${touchHandleSize}px; right: -${touchHandleSize}px; top: 0; bottom: 0; }`);
154153
}
155154

156155
if (space.canResizeTop) {
@@ -167,6 +166,7 @@ export function styleDefinition(space: ISpaceDefinition) {
167166
}
168167

169168
if (space.canResizeRight) {
169+
cssElements.push(`#${space.id}-mr:after { left: -${touchHandleSize}px; right: -${touchHandleSize}px; top: 0; bottom: 0; }`);
170170
if (space.width.size) {
171171
cssElements.push(
172172
`#${space.id}-mr { left: calc(${css(space.left, true)} + ${css(space.width, true)} - ${
@@ -206,7 +206,7 @@ export function styleDefinition(space: ISpaceDefinition) {
206206
} else {
207207
if (space.canResizeLeft) {
208208
cssElements.push(
209-
`#${space.id}-ml { left: calc(${css(space.left, true)} + ${css(space.width, true)} - ${handleOffset}px); width: ${
209+
`#${space.id}-ml { right: calc(${css(space.right, true)} + ${css(space.width, true)} - ${handleOffset}px); width: ${
210210
space.handleSize
211211
}px; }`,
212212
);
@@ -215,7 +215,7 @@ export function styleDefinition(space: ISpaceDefinition) {
215215

216216
if (space.canResizeTop) {
217217
cssElements.push(
218-
`#${space.id}-mt { top: calc(${css(space.top, true)} + ${css(space.height, true)} - ${handleOffset}px); height: ${
218+
`#${space.id}-mt { bottom: calc(${css(space.bottom, true)} + ${css(space.height, true)} - ${handleOffset}px); height: ${
219219
space.handleSize
220220
}px; }`,
221221
);
@@ -224,7 +224,7 @@ export function styleDefinition(space: ISpaceDefinition) {
224224

225225
if (space.canResizeRight) {
226226
cssElements.push(
227-
`#${space.id}-mr { right: calc(${css(space.right, true)} + ${css(space.width, true)} - ${handleOffset}px); width: ${
227+
`#${space.id}-mr { left: calc(${css(space.left, true)} + ${css(space.width, true)} - ${handleOffset}px); width: ${
228228
space.handleSize
229229
}px; }`,
230230
);
@@ -233,7 +233,7 @@ export function styleDefinition(space: ISpaceDefinition) {
233233

234234
if (space.canResizeBottom) {
235235
cssElements.push(
236-
`#${space.id}-mb { bottom: calc(${css(space.bottom, true)} + ${css(space.height, true)} - ${handleOffset}px); height: ${
236+
`#${space.id}-mb { top: calc(${css(space.top, true)} + ${css(space.height, true)} - ${handleOffset}px); height: ${
237237
space.handleSize
238238
}px; }`,
239239
);

src/core.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,10 @@ export function createStore(): ISpaceStore {
232232
handlePlacement,
233233
allowOverflow,
234234
} = props;
235-
const canResizeLeft = (position && position.rightResizable) || false;
236-
const canResizeRight = (position && position.leftResizable) || false;
237-
const canResizeTop = (position && position.bottomResizable) || false;
238-
const canResizeBottom = (position && position.topResizable) || false;
235+
const canResizeLeft = (position && position.leftResizable) || false;
236+
const canResizeRight = (position && position.rightResizable) || false;
237+
const canResizeTop = (position && position.topResizable) || false;
238+
const canResizeBottom = (position && position.bottomResizable) || false;
239239

240240
let changed = false;
241241

0 commit comments

Comments
 (0)