@zag-js/rect-utils 1.41.0 → 2.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/align.mjs +0 -2
  2. package/dist/angle.mjs +0 -2
  3. package/dist/clamp.mjs +0 -2
  4. package/dist/closest.mjs +0 -2
  5. package/dist/compass.d.mts +1 -5
  6. package/dist/compass.d.ts +1 -5
  7. package/dist/compass.js +0 -33
  8. package/dist/compass.mjs +0 -27
  9. package/dist/constrain.mjs +0 -2
  10. package/dist/contains.mjs +0 -2
  11. package/dist/distance.mjs +0 -2
  12. package/dist/equality.mjs +0 -2
  13. package/dist/from-element.mjs +0 -2
  14. package/dist/from-points.mjs +0 -2
  15. package/dist/from-range.mjs +0 -2
  16. package/dist/from-rotation.mjs +0 -2
  17. package/dist/from-window.mjs +0 -2
  18. package/dist/index.d.mts +3 -4
  19. package/dist/index.d.ts +3 -4
  20. package/dist/index.js +2 -4
  21. package/dist/index.mjs +1 -2
  22. package/dist/interact.d.mts +71 -0
  23. package/dist/interact.d.ts +71 -0
  24. package/dist/interact.js +377 -0
  25. package/dist/interact.mjs +338 -0
  26. package/dist/intersection.mjs +0 -2
  27. package/dist/operations.mjs +0 -2
  28. package/dist/polygon.mjs +0 -2
  29. package/dist/rect.d.mts +9 -2
  30. package/dist/rect.d.ts +9 -2
  31. package/dist/rect.js +40 -0
  32. package/dist/rect.mjs +33 -2
  33. package/dist/types.d.mts +1 -5
  34. package/dist/types.d.ts +1 -5
  35. package/dist/union.mjs +0 -2
  36. package/package.json +1 -1
  37. package/dist/affine-transform.d.mts +0 -39
  38. package/dist/affine-transform.d.ts +0 -39
  39. package/dist/affine-transform.js +0 -189
  40. package/dist/affine-transform.mjs +0 -166
  41. package/dist/chunk-QZ7TP4HQ.mjs +0 -7
  42. package/dist/resize.d.mts +0 -6
  43. package/dist/resize.d.ts +0 -6
  44. package/dist/resize.js +0 -113
  45. package/dist/resize.mjs +0 -90
@@ -0,0 +1,377 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/interact.ts
21
+ var interact_exports = {};
22
+ __export(interact_exports, {
23
+ applyMove: () => applyMove,
24
+ applyResize: () => applyResize,
25
+ centerInRect: () => centerInRect,
26
+ centerOnPoint: () => centerOnPoint,
27
+ clampPointInRange: () => clampPointInRange,
28
+ getArrowKeyDelta: () => getArrowKeyDelta,
29
+ getDirectionDelta: () => getDirectionDelta,
30
+ getKeyboardResizeDelta: () => getKeyboardResizeDelta,
31
+ isBottomHandle: () => isBottomHandle,
32
+ isCornerHandle: () => isCornerHandle,
33
+ isHorizontalHandle: () => isHorizontalHandle,
34
+ isLeftHandle: () => isLeftHandle,
35
+ isRightHandle: () => isRightHandle,
36
+ isTopHandle: () => isTopHandle,
37
+ isVerticalHandle: () => isVerticalHandle
38
+ });
39
+ module.exports = __toCommonJS(interact_exports);
40
+ var isLeftHandle = (h) => h === "w" || h === "nw" || h === "sw";
41
+ var isRightHandle = (h) => h === "e" || h === "ne" || h === "se";
42
+ var isTopHandle = (h) => h === "n" || h === "nw" || h === "ne";
43
+ var isBottomHandle = (h) => h === "s" || h === "sw" || h === "se";
44
+ var isCornerHandle = (h) => (isLeftHandle(h) || isRightHandle(h)) && (isTopHandle(h) || isBottomHandle(h));
45
+ var isHorizontalHandle = (h) => (isLeftHandle(h) || isRightHandle(h)) && !isTopHandle(h) && !isBottomHandle(h);
46
+ var isVerticalHandle = (h) => (isTopHandle(h) || isBottomHandle(h)) && !isLeftHandle(h) && !isRightHandle(h);
47
+ var { min, max, abs, round } = Math;
48
+ var clamp = (v, lo, hi) => min(max(v, lo), hi);
49
+ function resolveLimits(opts) {
50
+ const minW = opts.minSize?.width ?? 0;
51
+ const minH = opts.minSize?.height ?? 0;
52
+ let maxW = opts.maxSize?.width ?? Infinity;
53
+ let maxH = opts.maxSize?.height ?? Infinity;
54
+ if (opts.boundary) {
55
+ if (Number.isFinite(maxW)) maxW = min(maxW, opts.boundary.width);
56
+ else maxW = opts.boundary.width;
57
+ if (Number.isFinite(maxH)) maxH = min(maxH, opts.boundary.height);
58
+ else maxH = opts.boundary.height;
59
+ }
60
+ return { minW: max(0, minW), minH: max(0, minH), maxW: max(minW, maxW), maxH: max(minH, maxH) };
61
+ }
62
+ function resolveLimitsWithAspect(limits, boundary, ar) {
63
+ let { minW, minH, maxW, maxH } = limits;
64
+ const bw = boundary?.width ?? Infinity;
65
+ const bh = boundary?.height ?? Infinity;
66
+ const minWa = max(minW, minH * ar);
67
+ const minHa = minWa / ar;
68
+ minW = min(minWa, bw);
69
+ minH = min(minHa, bh);
70
+ let cmw = min(maxW, maxH * ar, bw);
71
+ let cmh = cmw / ar;
72
+ if (cmh > maxH || cmh > bh) {
73
+ cmh = min(maxH, bh);
74
+ cmw = cmh * ar;
75
+ }
76
+ maxW = max(minW, min(cmw, bw));
77
+ maxH = max(minH, min(cmh, bh));
78
+ return { minW, minH, maxW, maxH };
79
+ }
80
+ function applyDelta(edges, delta, handle, limits, boundary) {
81
+ let { left, top, right, bottom } = edges;
82
+ const { minW, minH, maxW, maxH } = limits;
83
+ if (isLeftHandle(handle)) {
84
+ const lo = boundary ? max(boundary.x, right - maxW) : right - maxW;
85
+ const hi = right - minW;
86
+ left = clamp(left + delta.x, lo, hi);
87
+ }
88
+ if (isRightHandle(handle)) {
89
+ const lo = left + minW;
90
+ const hi = boundary ? min(boundary.x + boundary.width, left + maxW) : left + maxW;
91
+ right = clamp(right + delta.x, lo, hi);
92
+ }
93
+ if (isTopHandle(handle)) {
94
+ const lo = boundary ? max(boundary.y, bottom - maxH) : bottom - maxH;
95
+ const hi = bottom - minH;
96
+ top = clamp(top + delta.y, lo, hi);
97
+ }
98
+ if (isBottomHandle(handle)) {
99
+ const lo = top + minH;
100
+ const hi = boundary ? min(boundary.y + boundary.height, top + maxH) : top + maxH;
101
+ bottom = clamp(bottom + delta.y, lo, hi);
102
+ }
103
+ return { left, top, right, bottom };
104
+ }
105
+ function clampAspectSize(wHint, hHint, ar, lim, bw, bh) {
106
+ const fromHeight = (h) => {
107
+ const w = clamp(h * ar, lim.minW, min(lim.maxW, bw));
108
+ return { width: w, height: w / ar };
109
+ };
110
+ const tryWidth = (value) => {
111
+ let w = clamp(value, lim.minW, min(lim.maxW, bw));
112
+ let h = w / ar;
113
+ if (h < lim.minH) ({ width: w, height: h } = fromHeight(lim.minH));
114
+ if (h > min(lim.maxH, bh)) ({ width: w, height: h } = fromHeight(min(lim.maxH, bh)));
115
+ if (h > bh) {
116
+ ;
117
+ ({ width: w, height: h } = fromHeight(bh));
118
+ if (h < lim.minH) ({ width: w, height: h } = fromHeight(lim.minH));
119
+ }
120
+ return { width: w, height: h };
121
+ };
122
+ const tryHeight = (value) => {
123
+ let h = clamp(value, lim.minH, min(lim.maxH, bh));
124
+ let w = clamp(h * ar, lim.minW, min(lim.maxW, bw));
125
+ let ah = w / ar;
126
+ if (ah < lim.minH) ({ width: w, height: ah } = fromHeight(lim.minH));
127
+ if (ah > min(lim.maxH, bh)) ({ width: w, height: ah } = fromHeight(min(lim.maxH, bh)));
128
+ if (w > bw) {
129
+ w = bw;
130
+ ah = w / ar;
131
+ if (ah > min(lim.maxH, bh)) ({ width: w, height: ah } = fromHeight(min(lim.maxH, bh)));
132
+ if (ah < lim.minH) ({ width: w, height: ah } = fromHeight(lim.minH));
133
+ }
134
+ return { width: w, height: ah };
135
+ };
136
+ const byW = tryWidth(wHint);
137
+ const byH = tryHeight(hHint);
138
+ const dw = abs(byW.width - wHint) + abs(byW.height - hHint);
139
+ const dh = abs(byH.width - wHint) + abs(byH.height - hHint);
140
+ return dh < dw ? byH : byW;
141
+ }
142
+ function enforceAspect(edges, handle, ar, lim, boundary) {
143
+ const { left, top, right, bottom } = edges;
144
+ const bw = boundary?.width ?? Infinity;
145
+ const bh = boundary?.height ?? Infinity;
146
+ const bx = boundary?.x ?? 0;
147
+ const by = boundary?.y ?? 0;
148
+ if (isCornerHandle(handle)) {
149
+ let w = right - left;
150
+ let h = w / ar;
151
+ if (h > bottom - top || boundary && (top + h > by + bh || left + w > bx + bw)) {
152
+ h = bottom - top;
153
+ w = h * ar;
154
+ }
155
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
156
+ w = s.width;
157
+ h = s.height;
158
+ if (isRightHandle(handle) && isBottomHandle(handle)) {
159
+ return { left, top, right: left + w, bottom: top + h };
160
+ }
161
+ if (isRightHandle(handle) && isTopHandle(handle)) {
162
+ return { left, top: bottom - h, right: left + w, bottom };
163
+ }
164
+ if (isLeftHandle(handle) && isBottomHandle(handle)) {
165
+ return { left: right - w, top, right, bottom: top + h };
166
+ }
167
+ return { left: right - w, top: bottom - h, right, bottom };
168
+ }
169
+ if (isHorizontalHandle(handle)) {
170
+ const centerY = (top + bottom) / 2;
171
+ let w = right - left;
172
+ let h = w / ar;
173
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
174
+ w = s.width;
175
+ h = s.height;
176
+ const halfH = h / 2;
177
+ let newTop = centerY - halfH;
178
+ let newBottom = centerY + halfH;
179
+ if (boundary) {
180
+ if (newTop < by) {
181
+ newTop = by;
182
+ newBottom = newTop + h;
183
+ }
184
+ if (newBottom > by + bh) {
185
+ newBottom = by + bh;
186
+ newTop = newBottom - h;
187
+ }
188
+ }
189
+ return {
190
+ left: isRightHandle(handle) ? left : right - w,
191
+ top: newTop,
192
+ right: isRightHandle(handle) ? left + w : right,
193
+ bottom: newBottom
194
+ };
195
+ }
196
+ if (isVerticalHandle(handle)) {
197
+ const centerX = (left + right) / 2;
198
+ let h = bottom - top;
199
+ let w = h * ar;
200
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
201
+ w = s.width;
202
+ h = s.height;
203
+ const halfW = w / 2;
204
+ let newLeft = centerX - halfW;
205
+ let newRight = centerX + halfW;
206
+ if (boundary) {
207
+ if (newLeft < bx) {
208
+ newLeft = bx;
209
+ newRight = newLeft + w;
210
+ }
211
+ if (newRight > bx + bw) {
212
+ newRight = bx + bw;
213
+ newLeft = newRight - w;
214
+ }
215
+ }
216
+ return {
217
+ left: newLeft,
218
+ top: isBottomHandle(handle) ? top : bottom - h,
219
+ right: newRight,
220
+ bottom: isBottomHandle(handle) ? top + h : bottom
221
+ };
222
+ }
223
+ return edges;
224
+ }
225
+ function centerInRect(size, boundary) {
226
+ return {
227
+ x: boundary.x + max(0, (boundary.width - size.width) / 2),
228
+ y: boundary.y + max(0, (boundary.height - size.height) / 2)
229
+ };
230
+ }
231
+ function centerOnPoint(size, center, boundary) {
232
+ const pos = {
233
+ x: center.x - size.width / 2,
234
+ y: center.y - size.height / 2
235
+ };
236
+ return {
237
+ x: clamp(pos.x, boundary.x, boundary.x + boundary.width - size.width),
238
+ y: clamp(pos.y, boundary.y, boundary.y + boundary.height - size.height)
239
+ };
240
+ }
241
+ function clampPointInRange(point, minPoint, maxPoint) {
242
+ return {
243
+ x: clamp(point.x, minPoint.x, maxPoint.x),
244
+ y: clamp(point.y, minPoint.y, maxPoint.y)
245
+ };
246
+ }
247
+ function applyMove(rect, delta, options = {}) {
248
+ const { boundary, gridSize = 1 } = options;
249
+ const dx = round(delta.x / gridSize) * gridSize;
250
+ const dy = round(delta.y / gridSize) * gridSize;
251
+ let x = rect.x + dx;
252
+ let y = rect.y + dy;
253
+ if (boundary) {
254
+ x = clamp(x, boundary.x, boundary.x + boundary.width - rect.width);
255
+ y = clamp(y, boundary.y, boundary.y + boundary.height - rect.height);
256
+ }
257
+ return { x, y, width: rect.width, height: rect.height };
258
+ }
259
+ function applyResize(rect, delta, handle, options = {}) {
260
+ const { boundary, aspectRatio, origin = "extent" } = options;
261
+ const baseLimits = resolveLimits(options);
262
+ const effectiveDelta = origin === "center" ? { x: delta.x * 2, y: delta.y * 2 } : delta;
263
+ let edges = applyDelta(
264
+ { left: rect.x, top: rect.y, right: rect.x + rect.width, bottom: rect.y + rect.height },
265
+ effectiveDelta,
266
+ handle,
267
+ baseLimits,
268
+ boundary
269
+ );
270
+ if (aspectRatio != null && aspectRatio > 0) {
271
+ const arLimits = resolveLimitsWithAspect(baseLimits, boundary, aspectRatio);
272
+ edges = enforceAspect(edges, handle, aspectRatio, arLimits, boundary);
273
+ }
274
+ let { left, top, right, bottom } = edges;
275
+ if (origin === "center") {
276
+ const cx = rect.x + rect.width / 2;
277
+ const cy = rect.y + rect.height / 2;
278
+ const w = right - left;
279
+ const h = bottom - top;
280
+ left = cx - w / 2;
281
+ top = cy - h / 2;
282
+ right = cx + w / 2;
283
+ bottom = cy + h / 2;
284
+ if (boundary) {
285
+ if (left < boundary.x) {
286
+ right += boundary.x - left;
287
+ left = boundary.x;
288
+ }
289
+ if (right > boundary.x + boundary.width) {
290
+ left -= right - (boundary.x + boundary.width);
291
+ right = boundary.x + boundary.width;
292
+ }
293
+ if (top < boundary.y) {
294
+ bottom += boundary.y - top;
295
+ top = boundary.y;
296
+ }
297
+ if (bottom > boundary.y + boundary.height) {
298
+ top -= bottom - (boundary.y + boundary.height);
299
+ bottom = boundary.y + boundary.height;
300
+ }
301
+ }
302
+ }
303
+ if (boundary) {
304
+ const maxLeft = max(boundary.x, boundary.x + boundary.width - baseLimits.minW);
305
+ const maxTop = max(boundary.y, boundary.y + boundary.height - baseLimits.minH);
306
+ left = clamp(left, boundary.x, maxLeft);
307
+ top = clamp(top, boundary.y, maxTop);
308
+ right = clamp(right, left + baseLimits.minW, min(boundary.x + boundary.width, left + baseLimits.maxW));
309
+ bottom = clamp(bottom, top + baseLimits.minH, min(boundary.y + boundary.height, top + baseLimits.maxH));
310
+ }
311
+ return { x: left, y: top, width: right - left, height: bottom - top };
312
+ }
313
+ function getDirectionDelta(direction, step) {
314
+ switch (direction) {
315
+ case "left":
316
+ return { x: -step, y: 0 };
317
+ case "right":
318
+ return { x: step, y: 0 };
319
+ case "up":
320
+ return { x: 0, y: -step };
321
+ case "down":
322
+ return { x: 0, y: step };
323
+ }
324
+ }
325
+ function getArrowKeyDelta(key, step) {
326
+ switch (key) {
327
+ case "ArrowLeft":
328
+ return { x: -step, y: 0 };
329
+ case "ArrowRight":
330
+ return { x: step, y: 0 };
331
+ case "ArrowUp":
332
+ return { x: 0, y: -step };
333
+ case "ArrowDown":
334
+ return { x: 0, y: step };
335
+ default:
336
+ return { x: 0, y: 0 };
337
+ }
338
+ }
339
+ function getKeyboardResizeDelta(key, handle, step) {
340
+ let x = 0;
341
+ let y = 0;
342
+ if (isLeftHandle(handle)) {
343
+ if (key === "ArrowLeft") x = -step;
344
+ else if (key === "ArrowRight") x = step;
345
+ }
346
+ if (isRightHandle(handle)) {
347
+ if (key === "ArrowRight") x = step;
348
+ else if (key === "ArrowLeft") x = -step;
349
+ }
350
+ if (isTopHandle(handle)) {
351
+ if (key === "ArrowUp") y = -step;
352
+ else if (key === "ArrowDown") y = step;
353
+ }
354
+ if (isBottomHandle(handle)) {
355
+ if (key === "ArrowDown") y = step;
356
+ else if (key === "ArrowUp") y = -step;
357
+ }
358
+ return { x, y };
359
+ }
360
+ // Annotate the CommonJS export names for ESM import in node:
361
+ 0 && (module.exports = {
362
+ applyMove,
363
+ applyResize,
364
+ centerInRect,
365
+ centerOnPoint,
366
+ clampPointInRange,
367
+ getArrowKeyDelta,
368
+ getDirectionDelta,
369
+ getKeyboardResizeDelta,
370
+ isBottomHandle,
371
+ isCornerHandle,
372
+ isHorizontalHandle,
373
+ isLeftHandle,
374
+ isRightHandle,
375
+ isTopHandle,
376
+ isVerticalHandle
377
+ });
@@ -0,0 +1,338 @@
1
+ // src/interact.ts
2
+ var isLeftHandle = (h) => h === "w" || h === "nw" || h === "sw";
3
+ var isRightHandle = (h) => h === "e" || h === "ne" || h === "se";
4
+ var isTopHandle = (h) => h === "n" || h === "nw" || h === "ne";
5
+ var isBottomHandle = (h) => h === "s" || h === "sw" || h === "se";
6
+ var isCornerHandle = (h) => (isLeftHandle(h) || isRightHandle(h)) && (isTopHandle(h) || isBottomHandle(h));
7
+ var isHorizontalHandle = (h) => (isLeftHandle(h) || isRightHandle(h)) && !isTopHandle(h) && !isBottomHandle(h);
8
+ var isVerticalHandle = (h) => (isTopHandle(h) || isBottomHandle(h)) && !isLeftHandle(h) && !isRightHandle(h);
9
+ var { min, max, abs, round } = Math;
10
+ var clamp = (v, lo, hi) => min(max(v, lo), hi);
11
+ function resolveLimits(opts) {
12
+ const minW = opts.minSize?.width ?? 0;
13
+ const minH = opts.minSize?.height ?? 0;
14
+ let maxW = opts.maxSize?.width ?? Infinity;
15
+ let maxH = opts.maxSize?.height ?? Infinity;
16
+ if (opts.boundary) {
17
+ if (Number.isFinite(maxW)) maxW = min(maxW, opts.boundary.width);
18
+ else maxW = opts.boundary.width;
19
+ if (Number.isFinite(maxH)) maxH = min(maxH, opts.boundary.height);
20
+ else maxH = opts.boundary.height;
21
+ }
22
+ return { minW: max(0, minW), minH: max(0, minH), maxW: max(minW, maxW), maxH: max(minH, maxH) };
23
+ }
24
+ function resolveLimitsWithAspect(limits, boundary, ar) {
25
+ let { minW, minH, maxW, maxH } = limits;
26
+ const bw = boundary?.width ?? Infinity;
27
+ const bh = boundary?.height ?? Infinity;
28
+ const minWa = max(minW, minH * ar);
29
+ const minHa = minWa / ar;
30
+ minW = min(minWa, bw);
31
+ minH = min(minHa, bh);
32
+ let cmw = min(maxW, maxH * ar, bw);
33
+ let cmh = cmw / ar;
34
+ if (cmh > maxH || cmh > bh) {
35
+ cmh = min(maxH, bh);
36
+ cmw = cmh * ar;
37
+ }
38
+ maxW = max(minW, min(cmw, bw));
39
+ maxH = max(minH, min(cmh, bh));
40
+ return { minW, minH, maxW, maxH };
41
+ }
42
+ function applyDelta(edges, delta, handle, limits, boundary) {
43
+ let { left, top, right, bottom } = edges;
44
+ const { minW, minH, maxW, maxH } = limits;
45
+ if (isLeftHandle(handle)) {
46
+ const lo = boundary ? max(boundary.x, right - maxW) : right - maxW;
47
+ const hi = right - minW;
48
+ left = clamp(left + delta.x, lo, hi);
49
+ }
50
+ if (isRightHandle(handle)) {
51
+ const lo = left + minW;
52
+ const hi = boundary ? min(boundary.x + boundary.width, left + maxW) : left + maxW;
53
+ right = clamp(right + delta.x, lo, hi);
54
+ }
55
+ if (isTopHandle(handle)) {
56
+ const lo = boundary ? max(boundary.y, bottom - maxH) : bottom - maxH;
57
+ const hi = bottom - minH;
58
+ top = clamp(top + delta.y, lo, hi);
59
+ }
60
+ if (isBottomHandle(handle)) {
61
+ const lo = top + minH;
62
+ const hi = boundary ? min(boundary.y + boundary.height, top + maxH) : top + maxH;
63
+ bottom = clamp(bottom + delta.y, lo, hi);
64
+ }
65
+ return { left, top, right, bottom };
66
+ }
67
+ function clampAspectSize(wHint, hHint, ar, lim, bw, bh) {
68
+ const fromHeight = (h) => {
69
+ const w = clamp(h * ar, lim.minW, min(lim.maxW, bw));
70
+ return { width: w, height: w / ar };
71
+ };
72
+ const tryWidth = (value) => {
73
+ let w = clamp(value, lim.minW, min(lim.maxW, bw));
74
+ let h = w / ar;
75
+ if (h < lim.minH) ({ width: w, height: h } = fromHeight(lim.minH));
76
+ if (h > min(lim.maxH, bh)) ({ width: w, height: h } = fromHeight(min(lim.maxH, bh)));
77
+ if (h > bh) {
78
+ ;
79
+ ({ width: w, height: h } = fromHeight(bh));
80
+ if (h < lim.minH) ({ width: w, height: h } = fromHeight(lim.minH));
81
+ }
82
+ return { width: w, height: h };
83
+ };
84
+ const tryHeight = (value) => {
85
+ let h = clamp(value, lim.minH, min(lim.maxH, bh));
86
+ let w = clamp(h * ar, lim.minW, min(lim.maxW, bw));
87
+ let ah = w / ar;
88
+ if (ah < lim.minH) ({ width: w, height: ah } = fromHeight(lim.minH));
89
+ if (ah > min(lim.maxH, bh)) ({ width: w, height: ah } = fromHeight(min(lim.maxH, bh)));
90
+ if (w > bw) {
91
+ w = bw;
92
+ ah = w / ar;
93
+ if (ah > min(lim.maxH, bh)) ({ width: w, height: ah } = fromHeight(min(lim.maxH, bh)));
94
+ if (ah < lim.minH) ({ width: w, height: ah } = fromHeight(lim.minH));
95
+ }
96
+ return { width: w, height: ah };
97
+ };
98
+ const byW = tryWidth(wHint);
99
+ const byH = tryHeight(hHint);
100
+ const dw = abs(byW.width - wHint) + abs(byW.height - hHint);
101
+ const dh = abs(byH.width - wHint) + abs(byH.height - hHint);
102
+ return dh < dw ? byH : byW;
103
+ }
104
+ function enforceAspect(edges, handle, ar, lim, boundary) {
105
+ const { left, top, right, bottom } = edges;
106
+ const bw = boundary?.width ?? Infinity;
107
+ const bh = boundary?.height ?? Infinity;
108
+ const bx = boundary?.x ?? 0;
109
+ const by = boundary?.y ?? 0;
110
+ if (isCornerHandle(handle)) {
111
+ let w = right - left;
112
+ let h = w / ar;
113
+ if (h > bottom - top || boundary && (top + h > by + bh || left + w > bx + bw)) {
114
+ h = bottom - top;
115
+ w = h * ar;
116
+ }
117
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
118
+ w = s.width;
119
+ h = s.height;
120
+ if (isRightHandle(handle) && isBottomHandle(handle)) {
121
+ return { left, top, right: left + w, bottom: top + h };
122
+ }
123
+ if (isRightHandle(handle) && isTopHandle(handle)) {
124
+ return { left, top: bottom - h, right: left + w, bottom };
125
+ }
126
+ if (isLeftHandle(handle) && isBottomHandle(handle)) {
127
+ return { left: right - w, top, right, bottom: top + h };
128
+ }
129
+ return { left: right - w, top: bottom - h, right, bottom };
130
+ }
131
+ if (isHorizontalHandle(handle)) {
132
+ const centerY = (top + bottom) / 2;
133
+ let w = right - left;
134
+ let h = w / ar;
135
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
136
+ w = s.width;
137
+ h = s.height;
138
+ const halfH = h / 2;
139
+ let newTop = centerY - halfH;
140
+ let newBottom = centerY + halfH;
141
+ if (boundary) {
142
+ if (newTop < by) {
143
+ newTop = by;
144
+ newBottom = newTop + h;
145
+ }
146
+ if (newBottom > by + bh) {
147
+ newBottom = by + bh;
148
+ newTop = newBottom - h;
149
+ }
150
+ }
151
+ return {
152
+ left: isRightHandle(handle) ? left : right - w,
153
+ top: newTop,
154
+ right: isRightHandle(handle) ? left + w : right,
155
+ bottom: newBottom
156
+ };
157
+ }
158
+ if (isVerticalHandle(handle)) {
159
+ const centerX = (left + right) / 2;
160
+ let h = bottom - top;
161
+ let w = h * ar;
162
+ const s = clampAspectSize(w, h, ar, lim, bw, bh);
163
+ w = s.width;
164
+ h = s.height;
165
+ const halfW = w / 2;
166
+ let newLeft = centerX - halfW;
167
+ let newRight = centerX + halfW;
168
+ if (boundary) {
169
+ if (newLeft < bx) {
170
+ newLeft = bx;
171
+ newRight = newLeft + w;
172
+ }
173
+ if (newRight > bx + bw) {
174
+ newRight = bx + bw;
175
+ newLeft = newRight - w;
176
+ }
177
+ }
178
+ return {
179
+ left: newLeft,
180
+ top: isBottomHandle(handle) ? top : bottom - h,
181
+ right: newRight,
182
+ bottom: isBottomHandle(handle) ? top + h : bottom
183
+ };
184
+ }
185
+ return edges;
186
+ }
187
+ function centerInRect(size, boundary) {
188
+ return {
189
+ x: boundary.x + max(0, (boundary.width - size.width) / 2),
190
+ y: boundary.y + max(0, (boundary.height - size.height) / 2)
191
+ };
192
+ }
193
+ function centerOnPoint(size, center, boundary) {
194
+ const pos = {
195
+ x: center.x - size.width / 2,
196
+ y: center.y - size.height / 2
197
+ };
198
+ return {
199
+ x: clamp(pos.x, boundary.x, boundary.x + boundary.width - size.width),
200
+ y: clamp(pos.y, boundary.y, boundary.y + boundary.height - size.height)
201
+ };
202
+ }
203
+ function clampPointInRange(point, minPoint, maxPoint) {
204
+ return {
205
+ x: clamp(point.x, minPoint.x, maxPoint.x),
206
+ y: clamp(point.y, minPoint.y, maxPoint.y)
207
+ };
208
+ }
209
+ function applyMove(rect, delta, options = {}) {
210
+ const { boundary, gridSize = 1 } = options;
211
+ const dx = round(delta.x / gridSize) * gridSize;
212
+ const dy = round(delta.y / gridSize) * gridSize;
213
+ let x = rect.x + dx;
214
+ let y = rect.y + dy;
215
+ if (boundary) {
216
+ x = clamp(x, boundary.x, boundary.x + boundary.width - rect.width);
217
+ y = clamp(y, boundary.y, boundary.y + boundary.height - rect.height);
218
+ }
219
+ return { x, y, width: rect.width, height: rect.height };
220
+ }
221
+ function applyResize(rect, delta, handle, options = {}) {
222
+ const { boundary, aspectRatio, origin = "extent" } = options;
223
+ const baseLimits = resolveLimits(options);
224
+ const effectiveDelta = origin === "center" ? { x: delta.x * 2, y: delta.y * 2 } : delta;
225
+ let edges = applyDelta(
226
+ { left: rect.x, top: rect.y, right: rect.x + rect.width, bottom: rect.y + rect.height },
227
+ effectiveDelta,
228
+ handle,
229
+ baseLimits,
230
+ boundary
231
+ );
232
+ if (aspectRatio != null && aspectRatio > 0) {
233
+ const arLimits = resolveLimitsWithAspect(baseLimits, boundary, aspectRatio);
234
+ edges = enforceAspect(edges, handle, aspectRatio, arLimits, boundary);
235
+ }
236
+ let { left, top, right, bottom } = edges;
237
+ if (origin === "center") {
238
+ const cx = rect.x + rect.width / 2;
239
+ const cy = rect.y + rect.height / 2;
240
+ const w = right - left;
241
+ const h = bottom - top;
242
+ left = cx - w / 2;
243
+ top = cy - h / 2;
244
+ right = cx + w / 2;
245
+ bottom = cy + h / 2;
246
+ if (boundary) {
247
+ if (left < boundary.x) {
248
+ right += boundary.x - left;
249
+ left = boundary.x;
250
+ }
251
+ if (right > boundary.x + boundary.width) {
252
+ left -= right - (boundary.x + boundary.width);
253
+ right = boundary.x + boundary.width;
254
+ }
255
+ if (top < boundary.y) {
256
+ bottom += boundary.y - top;
257
+ top = boundary.y;
258
+ }
259
+ if (bottom > boundary.y + boundary.height) {
260
+ top -= bottom - (boundary.y + boundary.height);
261
+ bottom = boundary.y + boundary.height;
262
+ }
263
+ }
264
+ }
265
+ if (boundary) {
266
+ const maxLeft = max(boundary.x, boundary.x + boundary.width - baseLimits.minW);
267
+ const maxTop = max(boundary.y, boundary.y + boundary.height - baseLimits.minH);
268
+ left = clamp(left, boundary.x, maxLeft);
269
+ top = clamp(top, boundary.y, maxTop);
270
+ right = clamp(right, left + baseLimits.minW, min(boundary.x + boundary.width, left + baseLimits.maxW));
271
+ bottom = clamp(bottom, top + baseLimits.minH, min(boundary.y + boundary.height, top + baseLimits.maxH));
272
+ }
273
+ return { x: left, y: top, width: right - left, height: bottom - top };
274
+ }
275
+ function getDirectionDelta(direction, step) {
276
+ switch (direction) {
277
+ case "left":
278
+ return { x: -step, y: 0 };
279
+ case "right":
280
+ return { x: step, y: 0 };
281
+ case "up":
282
+ return { x: 0, y: -step };
283
+ case "down":
284
+ return { x: 0, y: step };
285
+ }
286
+ }
287
+ function getArrowKeyDelta(key, step) {
288
+ switch (key) {
289
+ case "ArrowLeft":
290
+ return { x: -step, y: 0 };
291
+ case "ArrowRight":
292
+ return { x: step, y: 0 };
293
+ case "ArrowUp":
294
+ return { x: 0, y: -step };
295
+ case "ArrowDown":
296
+ return { x: 0, y: step };
297
+ default:
298
+ return { x: 0, y: 0 };
299
+ }
300
+ }
301
+ function getKeyboardResizeDelta(key, handle, step) {
302
+ let x = 0;
303
+ let y = 0;
304
+ if (isLeftHandle(handle)) {
305
+ if (key === "ArrowLeft") x = -step;
306
+ else if (key === "ArrowRight") x = step;
307
+ }
308
+ if (isRightHandle(handle)) {
309
+ if (key === "ArrowRight") x = step;
310
+ else if (key === "ArrowLeft") x = -step;
311
+ }
312
+ if (isTopHandle(handle)) {
313
+ if (key === "ArrowUp") y = -step;
314
+ else if (key === "ArrowDown") y = step;
315
+ }
316
+ if (isBottomHandle(handle)) {
317
+ if (key === "ArrowDown") y = step;
318
+ else if (key === "ArrowUp") y = -step;
319
+ }
320
+ return { x, y };
321
+ }
322
+ export {
323
+ applyMove,
324
+ applyResize,
325
+ centerInRect,
326
+ centerOnPoint,
327
+ clampPointInRange,
328
+ getArrowKeyDelta,
329
+ getDirectionDelta,
330
+ getKeyboardResizeDelta,
331
+ isBottomHandle,
332
+ isCornerHandle,
333
+ isHorizontalHandle,
334
+ isLeftHandle,
335
+ isRightHandle,
336
+ isTopHandle,
337
+ isVerticalHandle
338
+ };