Skip to content

Commit 863ad42

Browse files
committed
feat: support snappable in request #954
1 parent 77df18b commit 863ad42

File tree

7 files changed

+152
-17
lines changed

7 files changed

+152
-17
lines changed

packages/react-moveable/src/ables/Draggable.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
} from "../types";
1818
import { triggerChildGesto } from "../groupUtils";
1919
import { startCheckSnapDrag } from "./Snappable";
20-
import { IObject, getRad, throttle, throttleArray } from "@daybrush/utils";
20+
import { getRad, throttle, throttleArray } from "@daybrush/utils";
2121
import { checkSnapBoundsDrag } from "./snappable/snapBounds";
2222
import { TINY_NUM } from "../consts";
2323

@@ -140,7 +140,12 @@ export default {
140140
}
141141
resolveTransformEvent(e, "translate");
142142

143-
const { datas, parentEvent, parentFlag, isPinch, isRequest, deltaOffset } = e;
143+
const {
144+
datas, parentEvent,
145+
parentFlag, isPinch, deltaOffset,
146+
useSnap,
147+
isRequest,
148+
} = e;
144149
let { distX, distY } = e;
145150
const { isDrag, prevDist, prevBeforeDist, startValue } = datas;
146151

@@ -182,7 +187,7 @@ export default {
182187
const [verticalInfo, horizontalInfo] = checkSnapBoundsDrag(
183188
moveable, distX, distY,
184189
throttleDragRotate,
185-
isRequest || deltaOffset,
190+
(!useSnap && isRequest) || deltaOffset,
186191
datas,
187192
);
188193
isVerticalSnap = verticalInfo.isSnap;
@@ -398,13 +403,15 @@ export default {
398403
const rect = moveable.getRect();
399404
let distX = 0;
400405
let distY = 0;
406+
let useSnap = false;
401407

402408
return {
403409
isControl: false,
404-
requestStart() {
405-
return { datas };
410+
requestStart(e: Record<string, any>) {
411+
useSnap = e.useSnap;
412+
return { datas, useSnap };
406413
},
407-
request(e: IObject<any>) {
414+
request(e: Record<string, any>) {
408415
if ("x" in e) {
409416
distX = e.x - rect.left;
410417
} else if ("deltaX" in e) {
@@ -416,10 +423,10 @@ export default {
416423
distY += e.deltaY;
417424
}
418425

419-
return { datas, distX, distY };
426+
return { datas, distX, distY, useSnap };
420427
},
421428
requestEnd() {
422-
return { datas, isDrag: true };
429+
return { datas, isDrag: true, useSnap };
423430
},
424431
};
425432
},

packages/react-moveable/src/ables/Resizable.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export default {
243243
parentKeepRatio,
244244
dragClient,
245245
parentDist,
246+
useSnap,
246247
isRequest,
247248
isGroup,
248249
parentEvent,
@@ -378,13 +379,14 @@ export default {
378379
let snapDist = [0, 0];
379380

380381
if (!isPinch) {
382+
console.log(useSnap, isRequest);
381383
snapDist = checkSnapResize(
382384
moveable,
383385
boundingWidth,
384386
boundingHeight,
385387
direction,
386388
fixedPosition,
387-
isRequest,
389+
!useSnap && isRequest,
388390
datas,
389391
);
390392
}
@@ -784,12 +786,19 @@ export default {
784786
const datas: Record<string, any> = {};
785787
let distWidth = 0;
786788
let distHeight = 0;
789+
let useSnap = false;
787790
const rect = moveable.getRect();
788791

789792
return {
790793
isControl: true,
791794
requestStart(e: ResizableRequestParam) {
792-
return { datas, parentDirection: e.direction || [1, 1], parentIsWidth: e?.horizontal ?? true };
795+
useSnap = e.useSnap!;
796+
797+
return {
798+
datas, parentDirection: e.direction || [1, 1],
799+
parentIsWidth: e?.horizontal ?? true,
800+
useSnap,
801+
};
793802
},
794803
request(e: ResizableRequestParam) {
795804
if ("offsetWidth" in e) {
@@ -804,10 +813,15 @@ export default {
804813
}
805814

806815

807-
return { datas, parentDist: [distWidth, distHeight], parentKeepRatio: e.keepRatio };
816+
return {
817+
datas,
818+
parentDist: [distWidth, distHeight],
819+
parentKeepRatio: e.keepRatio,
820+
useSnap,
821+
};
808822
},
809823
requestEnd() {
810-
return { datas, isDrag: true };
824+
return { datas, isDrag: true, useSnap };
811825
},
812826
};
813827
},

packages/react-moveable/src/ables/Scalable.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ export default {
189189
isPinch,
190190
dragClient,
191191
isRequest,
192+
useSnap,
192193
resolveMatrix,
193194
} = e;
194195
const {
@@ -219,7 +220,7 @@ export default {
219220
const keepRatio = (ratio && (parentKeepRatio != null ? parentKeepRatio : props.keepRatio)) || false;
220221
const state = moveable.state;
221222

222-
const tempScaleValue = [
223+
const tempScaleValue = [
223224
startValue[0],
224225
startValue[1],
225226
];
@@ -303,7 +304,7 @@ export default {
303304
moveable,
304305
dist,
305306
direction,
306-
isRequest,
307+
!useSnap && isRequest,
307308
datas,
308309
);
309310
}
@@ -610,20 +611,32 @@ export default {
610611
const datas = {};
611612
let distWidth = 0;
612613
let distHeight = 0;
614+
let useSnap = false;
613615

614616
return {
615617
isControl: true,
616618
requestStart(e: IObject<any>) {
617-
return { datas, parentDirection: e.direction || [1, 1] };
619+
useSnap = e.useSnap;
620+
621+
return {
622+
datas,
623+
parentDirection: e.direction || [1, 1],
624+
useSnap,
625+
};
618626
},
619627
request(e: IObject<any>) {
620628
distWidth += e.deltaWidth;
621629
distHeight += e.deltaHeight;
622630

623-
return { datas, parentDist: [distWidth, distHeight], parentKeepRatio: e.keepRatio };
631+
return {
632+
datas,
633+
parentDist: [distWidth, distHeight],
634+
parentKeepRatio: e.keepRatio,
635+
useSnap,
636+
};
624637
},
625638
requestEnd() {
626-
return { datas, isDrag: true };
639+
return { datas, isDrag: true, useSnap };
627640
},
628641
};
629642
},

packages/react-moveable/src/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,10 @@ export interface DraggableRequestParam extends AbleRequestParam {
21602160
* Y number to move
21612161
*/
21622162
deltaY?: number;
2163+
/**
2164+
* whether to use with `snappable`
2165+
*/
2166+
useSnap?: boolean;
21632167
}
21642168

21652169
/**
@@ -2198,6 +2202,10 @@ export interface ResizableRequestParam extends AbleRequestParam {
21982202
*
21992203
*/
22002204
horizontal?: boolean;
2205+
/**
2206+
* whether to use with `snappable`
2207+
*/
2208+
useSnap?: boolean;
22012209
}
22022210

22032211
export interface ResizableEvents {
@@ -2270,6 +2278,10 @@ export interface ScalableRequestParam extends AbleRequestParam {
22702278
* delta number of height
22712279
*/
22722280
deltaHeight?: number;
2281+
/**
2282+
* whether to use with `snappable`
2283+
*/
2284+
useSnap?: boolean;
22732285
}
22742286

22752287

packages/react-moveable/stories/7-Request/0-Request.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,15 @@ export const RequestResizableGroup = add("Resizable Group", {
4444
...DEFAULT_RESIZABLE_CONTROLS,
4545
},
4646
});
47+
48+
49+
50+
export const RequestDraggableSnappable = add("Draggable With Snappable", {
51+
app: require("./ReactDraggableSnappableApp").default,
52+
path: require.resolve("./ReactDraggableSnappableApp"),
53+
});
54+
55+
export const RequestResizableSnappable = add("Resizable With Snappable", {
56+
app: require("./ReactResizableSnappableApp").default,
57+
path: require.resolve("./ReactResizableSnappableApp"),
58+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as React from "react";
2+
import Moveable, { DraggableRequestParam } from "@/react-moveable";
3+
4+
export default function App() {
5+
const moveableRef = React.useRef<Moveable>(null);
6+
7+
return (
8+
<div className="root">
9+
<button onClick={() => {
10+
moveableRef.current!.request<DraggableRequestParam>("draggable", {
11+
deltaX: -49,
12+
deltaY: 0,
13+
useSnap: true,
14+
}, true);
15+
}}>Left</button>
16+
<button onClick={() => {
17+
moveableRef.current!.request<DraggableRequestParam>("draggable", {
18+
deltaX: 49,
19+
deltaY: 0,
20+
useSnap: true,
21+
}, true);
22+
}}>Right</button>
23+
<div className="container">
24+
<div className="target">Target</div>
25+
<Moveable
26+
ref={moveableRef}
27+
target={".target"}
28+
draggable={true}
29+
snappable={true}
30+
snapGridWidth={50}
31+
onRender={e => {
32+
e.target.style.cssText += e.cssText;
33+
}}
34+
/>
35+
</div>
36+
</div>
37+
);
38+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as React from "react";
2+
import Moveable, { ResizableRequestParam } from "@/react-moveable";
3+
4+
export default function App() {
5+
const moveableRef = React.useRef<Moveable>(null);
6+
7+
return (
8+
<div className="root">
9+
<button onClick={() => {
10+
moveableRef.current!.request<ResizableRequestParam>("resizable", {
11+
direction: [1, 0],
12+
deltaWidth: -49,
13+
useSnap: true,
14+
}, true);
15+
}}>Left</button>
16+
<button onClick={() => {
17+
moveableRef.current!.request<ResizableRequestParam>("resizable", {
18+
direction: [1, 0],
19+
deltaWidth: 49,
20+
useSnap: true,
21+
}, true);
22+
}}>Right</button>
23+
<div className="container">
24+
<div className="target">Target</div>
25+
<Moveable
26+
ref={moveableRef}
27+
target={".target"}
28+
draggable={true}
29+
resizable={true}
30+
snappable={true}
31+
snapGridWidth={50}
32+
onRender={e => {
33+
e.target.style.cssText += e.cssText;
34+
}}
35+
/>
36+
</div>
37+
</div>
38+
);
39+
}

0 commit comments

Comments
 (0)