From 72c8876193dcfe647a15f13f1d95a38ba178c45b Mon Sep 17 00:00:00 2001 From: Chathura Date: Wed, 3 Oct 2018 21:27:32 +1000 Subject: [PATCH 1/6] FIX: #454 Component change the Y / X position when Drag stops even though dragging is restricted to X/Y axis --- src/index.tsx | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 9c8836fd..68732831 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -497,10 +497,32 @@ export class Rnd extends React.Component { const { left, top } = this.getOffsetFromParent(); let draggablePosition; if (position) { - draggablePosition = { - x: position.x - left, - y: position.y - top, - }; + switch (dragAxis) { + case "x": + draggablePosition = { + x: position.x - left, + y: position.y, + }; + break; + case "y": + draggablePosition = { + x: position.x, + y: position.y - top, + }; + break; + case "none": + draggablePosition = { + x: position.x, + y: position.y, + }; + break; + default: + draggablePosition = { + x: position.x - left, + y: position.y - top, + }; + break; + } } return ( Date: Thu, 4 Oct 2018 19:58:51 +1000 Subject: [PATCH 2/6] FIX:#454 Refactor --- src/index.tsx | 78 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 68732831..9b11d7dd 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -203,6 +203,40 @@ export class Rnd extends React.Component { return { x, y }; } + getPosition(position: any, dragAxis: any) { + const { left, top } = this.getOffsetFromParent(); + let draggablePosition; + if (position) { + switch (dragAxis) { + case "x": + draggablePosition = { + x: position.x - left, + y: position.y, + }; + break; + case "y": + draggablePosition = { + x: position.x, + y: position.y - top, + }; + break; + case "none": + draggablePosition = { + x: position.x, + y: position.y, + }; + break; + default: + draggablePosition = { + x: position.x - left, + y: position.y - top, + }; + break; + } + } + return draggablePosition; + } + getParent() { return this.resizable && (this.resizable as any).parentNode; } @@ -456,6 +490,11 @@ export class Rnd extends React.Component { top: selfRect.top - parentTop - position.y, }; } + snapToGrid(grid: [number, number], pendingX: number, pendingY: number): [number, number] { + const x = Math.round(pendingX / grid[0]) * grid[0]; + const y = Math.round(pendingY / grid[1]) * grid[1]; + return [x, y]; + } render() { const { @@ -473,9 +512,11 @@ export class Rnd extends React.Component { onResizeStart, onResize, onResizeStop, + snapOnResizeStop, onDragStart, onDrag, onDragStop, + snapOnDragStop, resizeHandleStyles, resizeHandleClasses, enableResizing, @@ -494,36 +535,9 @@ export class Rnd extends React.Component { ...cursorStyle, ...style, }; - const { left, top } = this.getOffsetFromParent(); - let draggablePosition; - if (position) { - switch (dragAxis) { - case "x": - draggablePosition = { - x: position.x - left, - y: position.y, - }; - break; - case "y": - draggablePosition = { - x: position.x, - y: position.y - top, - }; - break; - case "none": - draggablePosition = { - x: position.x, - y: position.y, - }; - break; - default: - draggablePosition = { - x: position.x - left, - y: position.y - top, - }; - break; - } - } + + const draggablePosition = this.getPosition(position, dragAxis); + return ( { @@ -539,7 +553,7 @@ export class Rnd extends React.Component { onStop={this.onDragStop} axis={dragAxis} disabled={disableDragging} - grid={dragGrid} + grid={snapOnDragStop ? undefined : dragGrid} bounds={bounds ? this.state.bounds : undefined} position={draggablePosition} enableUserSelectHack={enableUserSelectHack} @@ -563,7 +577,7 @@ export class Rnd extends React.Component { minHeight={this.props.minHeight} maxWidth={this.isResizing ? this.state.maxWidth : this.props.maxWidth} maxHeight={this.isResizing ? this.state.maxHeight : this.props.maxHeight} - grid={resizeGrid} + grid={snapOnResizeStop ? undefined : resizeGrid} handleWrapperClass={resizeHandleWrapperClass} handleWrapperStyle={resizeHandleWrapperStyle} lockAspectRatio={this.props.lockAspectRatio} From 5a7d10748c1ee102318367de31b76240c2a8c132 Mon Sep 17 00:00:00 2001 From: Chathura Date: Thu, 4 Oct 2018 20:02:44 +1000 Subject: [PATCH 3/6] FIX:#454 Refactor --- src/index.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 9b11d7dd..76654ef4 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -490,11 +490,6 @@ export class Rnd extends React.Component { top: selfRect.top - parentTop - position.y, }; } - snapToGrid(grid: [number, number], pendingX: number, pendingY: number): [number, number] { - const x = Math.round(pendingX / grid[0]) * grid[0]; - const y = Math.round(pendingY / grid[1]) * grid[1]; - return [x, y]; - } render() { const { @@ -553,7 +548,7 @@ export class Rnd extends React.Component { onStop={this.onDragStop} axis={dragAxis} disabled={disableDragging} - grid={snapOnDragStop ? undefined : dragGrid} + grid={dragGrid} bounds={bounds ? this.state.bounds : undefined} position={draggablePosition} enableUserSelectHack={enableUserSelectHack} @@ -577,7 +572,7 @@ export class Rnd extends React.Component { minHeight={this.props.minHeight} maxWidth={this.isResizing ? this.state.maxWidth : this.props.maxWidth} maxHeight={this.isResizing ? this.state.maxHeight : this.props.maxHeight} - grid={snapOnResizeStop ? undefined : resizeGrid} + grid={resizeGrid} handleWrapperClass={resizeHandleWrapperClass} handleWrapperStyle={resizeHandleWrapperStyle} lockAspectRatio={this.props.lockAspectRatio} From 026963a52b94f2400598cf8a101cd88b1e48af76 Mon Sep 17 00:00:00 2001 From: Chathura Date: Sat, 6 Oct 2018 08:46:33 +1000 Subject: [PATCH 4/6] FIXED: #454 Added a story for axis restriction --- src/index.tsx | 95 +++++++++++++--------- stories/index.tsx | 3 + stories/restrict-axis/restrict-drag.tsx | 102 ++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 38 deletions(-) create mode 100644 stories/restrict-axis/restrict-drag.tsx diff --git a/src/index.tsx b/src/index.tsx index 76654ef4..0b1b1779 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -203,40 +203,6 @@ export class Rnd extends React.Component { return { x, y }; } - getPosition(position: any, dragAxis: any) { - const { left, top } = this.getOffsetFromParent(); - let draggablePosition; - if (position) { - switch (dragAxis) { - case "x": - draggablePosition = { - x: position.x - left, - y: position.y, - }; - break; - case "y": - draggablePosition = { - x: position.x, - y: position.y - top, - }; - break; - case "none": - draggablePosition = { - x: position.x, - y: position.y, - }; - break; - default: - draggablePosition = { - x: position.x - left, - y: position.y - top, - }; - break; - } - } - return draggablePosition; - } - getParent() { return this.resizable && (this.resizable as any).parentNode; } @@ -310,9 +276,15 @@ export class Rnd extends React.Component { } onDragStop(e: Event, data: DraggableData) { + const { left, top } = this.getOffsetFromParent(); + + let draggablePosition = { + x: data.x + left, + y: data.y + top, + }; + if (this.props.onDragStop) { - const { left, top } = this.getOffsetFromParent(); - this.props.onDragStop(e, { ...data, x: data.x + left, y: data.y + top }); + this.props.onDragStop(e, { ...data, ...draggablePosition }); } } @@ -473,6 +445,7 @@ export class Rnd extends React.Component { } getOffsetFromParent(): { top: number; left: number } { + const { dragAxis } = this.props; const parent = this.getParent(); if (!parent) { return { @@ -485,10 +458,47 @@ export class Rnd extends React.Component { const parentTop = parentRect.top; const selfRect = this.getSelfElement().getBoundingClientRect(); const position = this.getDraggablePosition(); - return { + const rawPosition = { left: selfRect.left - parentLeft - position.x, top: selfRect.top - parentTop - position.y, }; + let adjustedPosition = rawPosition; + + switch (dragAxis) { + case "x": + adjustedPosition = { + ...rawPosition, + top: 0, + }; + break; + case "y": + adjustedPosition = { + ...rawPosition, + left: 0, + }; + break; + case "both": + adjustedPosition = { + ...rawPosition, + }; + break; + case "none": + adjustedPosition = { + ...rawPosition, + left: 0, + top: 0, + }; + break; + default: + adjustedPosition = { + ...rawPosition, + left: 0, + top: 0, + }; + break; + } + + return adjustedPosition; } render() { @@ -531,7 +541,16 @@ export class Rnd extends React.Component { ...style, }; - const draggablePosition = this.getPosition(position, dragAxis); + const { left, top } = this.getOffsetFromParent(); + let draggablePosition; + console.log("LEFT", left); + console.log("TOP", top); + if (position) { + draggablePosition = { + x: position.x - left, + y: position.y - top, + }; + } return ( ); storiesOf("basic", module) @@ -58,3 +60,4 @@ storiesOf("sandbox", module) .add("lock aspect ratio with bounds", () => ); storiesOf("ratio", module).add("lock aspect ratio", () => ); +storiesOf("restrict axis", module).add("restrict drag axis", () => ); diff --git a/stories/restrict-axis/restrict-drag.tsx b/stories/restrict-axis/restrict-drag.tsx new file mode 100644 index 00000000..1c83497c --- /dev/null +++ b/stories/restrict-axis/restrict-drag.tsx @@ -0,0 +1,102 @@ +import React from "react"; +import { Rnd } from "../../src"; + +type State = { + x: number; + y: number; + width: number; + height: number; + restrict: "x" | "y" | "both" | "none"; +}; + +const style = { + display: "flex", + alignItems: "center", + justifyContent: "center", + border: "solid 1px #ddd", + background: "#f0f0f0", +}; +export default class RestrictDrag extends React.Component<{}, State> { + constructor(props) { + super(props); + this.state = { + width: 200, + height: 200, + x: 0, + y: 80, + restrict: "x", + }; + } + handleDragStop = (e, d) => { + const restrictedAxis = this.state.restrict; + let pos = {}; + switch (restrictedAxis) { + case "x": + pos = { + x: d.x, + }; + break; + case "y": + pos = { + y: d.y, + }; + break; + case "both": + pos = { + x: d.x, + y: d.y, + }; + break; + case "none": + pos = {}; + break; + default: + pos = {}; + break; + } + this.setState({ ...pos }); + }; + + render() { + console.log("STATE", this.state); + return ( +
+ + { + this.setState({ + width: ref.offsetWidth, + height: ref.offsetHeight, + ...position, + }); + }} + > + 001 + +
+ ); + } +} From 364ea75db0b8ce0176da1020687b04516e396a02 Mon Sep 17 00:00:00 2001 From: Chathura Date: Sat, 6 Oct 2018 17:56:31 +1000 Subject: [PATCH 5/6] FIXED:#454 STORIES --- src/index.test.tsx | 36 +++++++++++----------- src/index.tsx | 8 ++--- stories/size/size-percent-uncontrolled.tsx | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/index.test.tsx b/src/index.test.tsx index ab3f8074..6c91d604 100755 --- a/src/index.test.tsx +++ b/src/index.test.tsx @@ -111,8 +111,8 @@ test("should call onDragStart when start dragging", async t => { .simulate("mousedown"); t.is(onDragStart.callCount, 1); t.is(onDragStart.firstCall.args[0].type, "mousedown"); - t.is(onDragStart.firstCall.args[1].x, 200); - t.is(onDragStart.firstCall.args[1].y, 200); + t.is(onDragStart.firstCall.args[1].x, 100); + t.is(onDragStart.firstCall.args[1].y, 100); }); test("should call onDrag when dragging", async t => { @@ -124,9 +124,9 @@ test("should call onDrag when dragging", async t => { .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(200, 220); t.is(onDrag.callCount, 1); - t.is(onDrag.firstCall.args[1].x, 600); - t.is(onDrag.firstCall.args[1].y, 620); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(400px, 420px)"), -1); + t.is(onDrag.firstCall.args[1].x, 300); + t.is(onDrag.firstCall.args[1].y, 320); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(300px, 320px)"), -1); }); test("should call onDragStop when drag stop", async t => { @@ -137,10 +137,10 @@ test("should call onDragStop when drag stop", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(200, 220); - mouseUp(100, 120); + mouseUp(200, 220); t.is(onDragStop.callCount, 1); - t.is(onDragStop.firstCall.args[1].x, -100); - t.is(onDragStop.firstCall.args[1].y, -100); + t.is(onDragStop.firstCall.args[1].x, 300); + t.is(onDragStop.firstCall.args[1].y, 320); }); test("should dragging disabled when axis equals none", async t => { @@ -208,7 +208,7 @@ test("should snap when dragging smaller than threshold", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(14, 49); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(108px, 108px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(100px, 100px)"), -1); }); test("should snap when dragging larger than threshold", async t => { @@ -220,7 +220,7 @@ test("should snap when dragging larger than threshold", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(15, 50); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(138px, 208px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(130px, 200px)"), -1); }); test("should limit position by parent bounds", async t => { @@ -244,7 +244,7 @@ test("should limit position by parent bounds", async t => { .childAt(0) .getDOMNode() .getAttribute("style") || "" - ).indexOf("transform: translate(708px, 508px)"), + ).indexOf("transform: translate(700px, 500px)"), -1, ); }); @@ -275,7 +275,7 @@ test("should limit position by selector bounds", async t => { .childAt(0) .getDOMNode() .getAttribute("style") || "" - ).indexOf("translate(908px, 708px)"), + ).indexOf("translate(900px, 700px)"), -1, ); }); @@ -468,7 +468,7 @@ test("should move x when resizing left", async t => { t.deepEqual(onResize.getCall(0).args[2].clientWidth, 150); t.deepEqual(onResize.getCall(0).args[2].clientHeight, 100); t.deepEqual(onResize.getCall(0).args[3], { width: 50, height: 0 }); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(58px, 108px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(50px, 100px)"), -1); }); test("should move y when resizing top", async t => { @@ -512,7 +512,7 @@ test("should move y when resizing top", async t => { t.deepEqual(onResize.getCall(0).args[2].clientWidth, 100); t.deepEqual(onResize.getCall(0).args[2].clientHeight, 150); t.deepEqual(onResize.getCall(0).args[3], { width: 0, height: 50 }); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(108px, 58px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(100px, 50px)"), -1); }); test("should snapped by original grid when x axis resizing smaller then threshold", async t => { @@ -742,8 +742,8 @@ test("should clamped by parent size", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(1200, 1200); - t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.width, "800px"); - t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.height, "600px"); + t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.width, "808px"); + t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.height, "608px"); }); test("should clamped by selector size", async t => { @@ -788,14 +788,14 @@ test("should clamped by selector size", async t => { .childAt(0) .childAt(0) .getDOMNode() as HTMLElement).style.width, - "1000px", + "1008px", ); t.is( (rnd .childAt(0) .childAt(0) .getDOMNode() as HTMLElement).style.height, - "800px", + "808px", ); }); diff --git a/src/index.tsx b/src/index.tsx index 0b1b1779..a38c3b71 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -447,6 +447,7 @@ export class Rnd extends React.Component { getOffsetFromParent(): { top: number; left: number } { const { dragAxis } = this.props; const parent = this.getParent(); + if (!parent) { return { top: 0, @@ -492,12 +493,10 @@ export class Rnd extends React.Component { default: adjustedPosition = { ...rawPosition, - left: 0, - top: 0, }; break; } - + console.log("POSITION", adjustedPosition); return adjustedPosition; } @@ -543,8 +542,7 @@ export class Rnd extends React.Component { const { left, top } = this.getOffsetFromParent(); let draggablePosition; - console.log("LEFT", left); - console.log("TOP", top); + if (position) { draggablePosition = { x: position.x - left, diff --git a/stories/size/size-percent-uncontrolled.tsx b/stories/size/size-percent-uncontrolled.tsx index 4593d73a..0e94dfc6 100644 --- a/stories/size/size-percent-uncontrolled.tsx +++ b/stories/size/size-percent-uncontrolled.tsx @@ -1,5 +1,5 @@ import React from "react"; -import Rnd from "../../src"; +import { Rnd } from "../../src"; import { style } from "../styles"; export default () => ( From 993ebe43c18788ba4b309cfdf4dcd385848ea6e7 Mon Sep 17 00:00:00 2001 From: Chathura Date: Sat, 6 Oct 2018 18:09:32 +1000 Subject: [PATCH 6/6] Removed console log --- src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.tsx b/src/index.tsx index a38c3b71..e8874048 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -496,7 +496,7 @@ export class Rnd extends React.Component { }; break; } - console.log("POSITION", adjustedPosition); + return adjustedPosition; }