Skip to content

Commit 05f6f22

Browse files
committed
fix: fix snap for fixed position #791
1 parent d1c9e2c commit 05f6f22

File tree

6 files changed

+101
-19
lines changed

6 files changed

+101
-19
lines changed

packages/react-moveable/src/react-moveable/ables/snappable/getTotalGuidelines.ts

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { minus } from "@scena/matrix";
44
import { getMinMaxs } from "overlap-area";
55
import {
66
MoveableManagerInterface, SnappableProps,
7-
SnappableState, SnapGuideline, SnapDirectionPoses, PosGuideline, ElementGuidelineValue, SnapElementRect,
7+
SnappableState, SnapGuideline, SnapDirectionPoses,
8+
PosGuideline, ElementGuidelineValue,
9+
SnapElementRect,
810
} from "../../types";
911
import { getRect, getAbsolutePosesByState, getRefTarget, calculateInversePosition, roundSign } from "../../utils";
1012
import {
@@ -15,18 +17,20 @@ import {
1517
export function getTotalGuidelines(
1618
moveable: MoveableManagerInterface<SnappableProps, SnappableState>,
1719
) {
20+
const state = moveable.state;
1821
const {
19-
snapOffset,
20-
containerClientRect: {
21-
overflow,
22-
scrollHeight: containerHeight,
23-
scrollWidth: containerWidth,
24-
clientHeight: containerClientHeight,
25-
clientWidth: containerClientWidth,
26-
clientLeft,
27-
clientTop,
28-
},
29-
} = moveable.state;
22+
containerClientRect,
23+
hasFixed,
24+
} = state;
25+
const {
26+
overflow,
27+
scrollHeight: containerHeight,
28+
scrollWidth: containerWidth,
29+
clientHeight: containerClientHeight,
30+
clientWidth: containerClientWidth,
31+
clientLeft,
32+
clientTop,
33+
} = containerClientRect;
3034
const {
3135
snapGap = true,
3236
verticalGuidelines,
@@ -54,6 +58,20 @@ export function getTotalGuidelines(
5458
clientLeft,
5559
clientTop,
5660
));
61+
const snapOffset = {
62+
...(state.snapOffset || {
63+
left: 0,
64+
top: 0,
65+
bottom: 0,
66+
right: 0,
67+
}),
68+
};
69+
70+
71+
if (hasFixed) {
72+
snapOffset.left += containerClientRect.left;
73+
snapOffset.top += containerClientRect.top;
74+
}
5775

5876
totalGuidelines.push(...getDefaultGuidelines(
5977
horizontalGuidelines || false,
@@ -398,21 +416,25 @@ export function getDefaultGuidelines(
398416
const nextPosInfo = isObject(posInfo) ? posInfo : { pos: posInfo };
399417

400418
guidelines.push({
401-
type: "horizontal", pos: [
419+
type: "horizontal",
420+
pos: [
402421
snapOffsetLeft,
403422
throttle(nextPosInfo.pos - clientTop + snapOffsetTop, 0.1),
404-
], size: snapWidth,
423+
],
424+
size: snapWidth,
405425
className: nextPosInfo.className,
406426
});
407427
});
408428
verticalGuidelines && verticalGuidelines!.forEach(posInfo => {
409429
const nextPosInfo = isObject(posInfo) ? posInfo : { pos: posInfo };
410430

411431
guidelines.push({
412-
type: "vertical", pos: [
432+
type: "vertical",
433+
pos: [
413434
throttle(nextPosInfo.pos - clientLeft + snapOffsetLeft, 0.1),
414435
snapOffsetTop,
415-
], size: snapHeight,
436+
],
437+
size: snapHeight,
416438
className: nextPosInfo.className,
417439
});
418440
});

packages/react-moveable/src/react-moveable/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2738,7 +2738,7 @@ export interface OnCustomDrag extends GestoTypes.Position {
27382738
* @memberof Moveable
27392739
*/
27402740
export type PersistRectData = Omit<Partial<RectInfo>, "children"> & {
2741-
children?: Partial<RectInfo>;
2741+
children?: Array<Partial<RectInfo>>;
27422742
};
27432743

27442744

packages/react-moveable/src/react-moveable/utils/persist.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function getPersistState(rect: PersistRectData): Partial<MoveableManagerS
1515
}
1616
const minPos = getMinMaxs([pos1!, pos2!, pos3!, pos4!]);
1717
const posDelta = [minPos.minX, minPos.minY];
18-
const origin = minus(rect.origin, posDelta);
18+
const origin = minus(rect.origin!, posDelta);
1919

2020
pos1 = minus(pos1, posDelta);
2121
pos2 = minus(pos2, posDelta);

packages/react-moveable/stories/9-Scrolling/apps/ScrollableApp.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function App() {
2929
<div className="target" ref={targetRef}>Target</div>
3030
<Moveable
3131
scrollable={true}
32-
scrollContainer={() => viewerRef.current!.getElement()}
32+
scrollContainer={() => viewerRef.current!.getContainer()}
3333
scrollThreshold={20}
3434
getScrollPosition={() => {
3535
return [

packages/react-moveable/stories/99-Tests/Deafult.stories.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ group.add("Test Changing Snap Container", {
8585
app: require("./ReactChangingSnapContainerApp").default,
8686
path: require.resolve("./ReactChangingSnapContainerApp"),
8787
});
88+
89+
90+
91+
group.add("Test Snap with position: fixed", {
92+
app: require("./ReactFixedSnapApp").default,
93+
path: require.resolve("./ReactFixedSnapApp"),
94+
});
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as React from "react";
2+
import Moveable from "@/react-moveable";
3+
4+
export default function App(props: Record<string, any>) {
5+
return (
6+
<div className="root">
7+
<div className="container" style={{
8+
height: "900px",
9+
}}>
10+
<div className="target element1" style={{
11+
width: "100px",
12+
height: "100px",
13+
left: "0px",
14+
top: "120px",
15+
}}>Element1</div>
16+
<div className="target element2" style={{
17+
width: "100px",
18+
height: "100px",
19+
left: "400px",
20+
top: "120px",
21+
}}>Element2</div>
22+
<div className="target element3" style={{
23+
width: "300px",
24+
height: "100px",
25+
top: "400px",
26+
left: "50px",
27+
}}>Element3</div>
28+
<div className="target target1" style={{
29+
position: "fixed",
30+
width: "150px",
31+
height: "150px",
32+
}}>Target</div>
33+
<Moveable
34+
target=".target1"
35+
draggable={true}
36+
scalable={true}
37+
rotatable={true}
38+
snappable={true}
39+
// verticalGuidelines={[0, 100, 200]}
40+
horizontalGuidelines={[0, 100, 200]}
41+
elementGuidelines={[{
42+
element: ".element1",
43+
refresh: true,
44+
}, ".element2", ".element3"]}
45+
onRender={e => {
46+
// console.log(e.moveable.state.guidelines);
47+
e.target.style.cssText += e.cssText;
48+
}}
49+
/>
50+
</div>
51+
</div>
52+
);
53+
}

0 commit comments

Comments
 (0)