Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DraggableCore): apply scale property while dragging an element #438

Merged
merged 1 commit into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/DraggableCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export type DraggableCoreProps = {
onDrag: DraggableEventHandler,
onStop: DraggableEventHandler,
onMouseDown: (e: MouseEvent) => void,
scale: number,
};

//
Expand Down Expand Up @@ -185,6 +186,11 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
*/
onMouseDown: PropTypes.func,

/**
* `scale`, if set, applies scaling while dragging an element
*/
scale: PropTypes.number,

/**
* These properties should be defined on the child, not here.
*/
Expand All @@ -206,6 +212,7 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
onDrag: function(){},
onStop: function(){},
onMouseDown: function(){},
scale: 1,
};

state = {
Expand Down
6 changes: 3 additions & 3 deletions lib/utils/domFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ export function innerWidth(node: HTMLElement): number {
}

// Get from offsetParent
export function offsetXYFromParent(evt: {clientX: number, clientY: number}, offsetParent: HTMLElement): ControlPosition {
export function offsetXYFromParent(evt: {clientX: number, clientY: number}, offsetParent: HTMLElement, scale: number): ControlPosition {
const isBody = offsetParent === offsetParent.ownerDocument.body;
const offsetParentRect = isBody ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();

const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;
const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;
const x = (evt.clientX + offsetParent.scrollLeft - offsetParentRect.left) / scale;
const y = (evt.clientY + offsetParent.scrollTop - offsetParentRect.top) / scale;

return {x, y};
}
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/positionFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function getControlPosition(e: MouseTouchEvent, touchIdentifier: ?number,
const node = findDOMNode(draggableCore);
// User can provide an offsetParent if desired.
const offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body;
return offsetXYFromParent(touchObj || e, offsetParent);
return offsetXYFromParent(touchObj || e, offsetParent, draggableCore.props.scale);
}

// Create an data object exposed by <DraggableCore>'s events
Expand Down
76 changes: 76 additions & 0 deletions specs/draggable.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,44 @@ describe('react-draggable', function () {

simulateMovementFromTo(drag, 200, 200, 300, 300);
});

it('should call back with correct position when parent element is 2x scaled', function() {
function onDrag(event, data) {
// visually it will look like 100, because parent is 2x scaled
assert(data.x === 50);
assert(data.y === 50);
assert(data.deltaX === 50);
assert(data.deltaY === 50);
assert(data.node === ReactDOM.findDOMNode(drag));
}
drag = TestUtils.renderIntoDocument(
<Draggable onDrag={onDrag} scale={2}>
<div />
</Draggable>
);

// (element, fromX, fromY, toX, toY)
simulateMovementFromTo(drag, 0, 0, 100, 100);
});

it('should call back with correct position when parent element is 0.5x scaled', function() {
function onDrag(event, data) {
// visually it will look like 100, because parent is 0.5x scaled
assert(data.x === 200);
assert(data.y === 200);
assert(data.deltaX === 200);
assert(data.deltaY === 200);
assert(data.node === ReactDOM.findDOMNode(drag));
}
drag = TestUtils.renderIntoDocument(
<Draggable onDrag={onDrag} scale={0.5}>
<div />
</Draggable>
);

// (element, fromX, fromY, toX, toY)
simulateMovementFromTo(drag, 0, 0, 100, 100);
});
});

describe('DraggableCore callbacks', function () {
Expand All @@ -703,6 +741,44 @@ describe('react-draggable', function () {
// (element, fromX, fromY, toX, toY)
simulateMovementFromTo(drag, 0, 0, 100, 100);
});

it('should call back with correct position when parent element is 2x scaled', function() {
function onDrag(event, data) {
// visually it will look like 100, because parent is 2x scaled
assert(data.x === 50);
assert(data.y === 50);
assert(data.deltaX === 50);
assert(data.deltaY === 50);
assert(data.node === ReactDOM.findDOMNode(drag));
}
drag = TestUtils.renderIntoDocument(
<DraggableCore onDrag={onDrag} scale={2}>
<div />
</DraggableCore>
);

// (element, fromX, fromY, toX, toY)
simulateMovementFromTo(drag, 0, 0, 100, 100);
});

it('should call back with correct position when parent element is 0.5x scaled', function() {
function onDrag(event, data) {
// visually it will look like 100, because parent is 0.5x scaled
assert(data.x === 200);
assert(data.y === 200);
assert(data.deltaX === 200);
assert(data.deltaY === 200);
assert(data.node === ReactDOM.findDOMNode(drag));
}
drag = TestUtils.renderIntoDocument(
<DraggableCore onDrag={onDrag} scale={0.5}>
<div />
</DraggableCore>
);

// (element, fromX, fromY, toX, toY)
simulateMovementFromTo(drag, 0, 0, 100, 100);
});
});


Expand Down