From 4765c88eca759182d7111be2e73226032e3c51bb Mon Sep 17 00:00:00 2001 From: hyesungoh Date: Sat, 10 Aug 2024 16:06:50 +0900 Subject: [PATCH 1/3] fix: prevent stop or pause when drag constraints --- .../src/gestures/drag/VisualElementDragControls.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts b/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts index a9fe135872..ce776cf76d 100644 --- a/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts +++ b/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts @@ -96,11 +96,13 @@ export class VisualElementDragControls { if (presenceContext && presenceContext.isPresent === false) return const onSessionStart = (event: PointerEvent) => { - const { dragSnapToOrigin } = this.getProps() + const { dragSnapToOrigin, dragConstraints } = this.getProps() - // Stop or pause any animations on both axis values immediately. This allows the user to throw and catch - // the component. - dragSnapToOrigin ? this.pauseAnimation() : this.stopAnimation() + // Stop or pause any animations on both axis values immediately when not using dragConstraints. + // This allows the user to throw and catch the component. + if (!dragConstraints) { + dragSnapToOrigin ? this.pauseAnimation() : this.stopAnimation() + } if (snapToCursor) { this.snapToCursor(extractEventInfo(event, "page").point) @@ -454,6 +456,7 @@ export class VisualElementDragControls { transition: Transition ) { const axisValue = this.getAxisMotionValue(axis) + console.log("axisValue", axisValue) return axisValue.start( animateMotionValue( @@ -469,10 +472,12 @@ export class VisualElementDragControls { } private stopAnimation() { + console.log("stopAnimation") eachAxis((axis) => this.getAxisMotionValue(axis).stop()) } private pauseAnimation() { + console.log("pauseAnimation") eachAxis((axis) => this.getAxisMotionValue(axis).animation?.pause()) } From ff6a0b006235404ab45ed57e56a156ac33757287 Mon Sep 17 00:00:00 2001 From: hyesungoh Date: Sat, 10 Aug 2024 16:08:15 +0900 Subject: [PATCH 2/3] chore: delete useless log --- .../src/gestures/drag/VisualElementDragControls.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts b/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts index ce776cf76d..bb9969d6a4 100644 --- a/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts +++ b/packages/framer-motion/src/gestures/drag/VisualElementDragControls.ts @@ -98,7 +98,7 @@ export class VisualElementDragControls { const onSessionStart = (event: PointerEvent) => { const { dragSnapToOrigin, dragConstraints } = this.getProps() - // Stop or pause any animations on both axis values immediately when not using dragConstraints. + // Stop or pause any animations on both axis values immediately when not using dragConstraints. // This allows the user to throw and catch the component. if (!dragConstraints) { dragSnapToOrigin ? this.pauseAnimation() : this.stopAnimation() @@ -456,7 +456,6 @@ export class VisualElementDragControls { transition: Transition ) { const axisValue = this.getAxisMotionValue(axis) - console.log("axisValue", axisValue) return axisValue.start( animateMotionValue( @@ -472,12 +471,10 @@ export class VisualElementDragControls { } private stopAnimation() { - console.log("stopAnimation") eachAxis((axis) => this.getAxisMotionValue(axis).stop()) } private pauseAnimation() { - console.log("pauseAnimation") eachAxis((axis) => this.getAxisMotionValue(axis).animation?.pause()) } From 0fe52823621cf5016300c3355a09325862de5ff8 Mon Sep 17 00:00:00 2001 From: hyesungoh Date: Sun, 11 Aug 2024 17:04:11 +0900 Subject: [PATCH 3/3] test: reset position when click after dragging --- dev/react/src/tests/drag-ref-constraints.tsx | 3 ++- .../framer-motion/cypress/integration/drag.ts | 25 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/dev/react/src/tests/drag-ref-constraints.tsx b/dev/react/src/tests/drag-ref-constraints.tsx index 4953a9c5c3..2cce23e387 100644 --- a/dev/react/src/tests/drag-ref-constraints.tsx +++ b/dev/react/src/tests/drag-ref-constraints.tsx @@ -8,6 +8,7 @@ export const App = () => { const [dragging, setDragging] = useState(false) const params = new URLSearchParams(window.location.search) const layout = params.get("layout") || undefined + const elastic = Number(params.get("elastic")) || 0 // We do this to test when scroll position isn't 0/0 useLayoutEffect(() => { @@ -27,7 +28,7 @@ export const App = () => { id="box" data-testid="draggable" drag - dragElastic={0} + dragElastic={elastic} dragMomentum={false} style={{ width: 50, diff --git a/packages/framer-motion/cypress/integration/drag.ts b/packages/framer-motion/cypress/integration/drag.ts index 125740e80f..8ef843f620 100644 --- a/packages/framer-motion/cypress/integration/drag.ts +++ b/packages/framer-motion/cypress/integration/drag.ts @@ -228,6 +228,27 @@ describe("Drag", () => { }) }) + it("reset drag constraints (ref-based), when click after dragging", () => { + cy.visit("?test=drag-ref-constraints&elastic=1") + .wait(200) + .get("[data-testid='draggable']") + .trigger("pointerdown", 10, 10) + .wait(200) + .trigger("pointermove", 300, 300, { force: true }) + .wait(200) + .trigger("pointerup", { force: true }) + .trigger("pointerdown", { force: true }) + .trigger("pointerup", { force: true }) + .wait(1000) + .should(($draggable: any) => { + const draggable = $draggable[0] as HTMLDivElement + const { left, top } = draggable.getBoundingClientRect() + + expect(left).to.equal(150) + expect(top).to.equal(150) + }) + }) + it("doesn't reset drag constraints (ref-based), while dragging, on unrelated parent component updates", () => { cy.visit("?test=drag-ref-constraints") .wait(200) @@ -242,8 +263,8 @@ describe("Drag", () => { const draggable = $draggable[0] as HTMLDivElement const { left, top } = draggable.getBoundingClientRect() - expect(left).to.equal(150) - expect(top).to.equal(150) + expect(left).to.equal(200) + expect(top).to.equal(200) }) })