Skip to content

fix: scale property should be applied on the deltas of DraggableCore … #442

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ class App extends React.Component {
</Draggable>
</div>
</div>
<div className="box"
style={{height: '200px', width: '200px', position: 'relative', transform: 'scale(2)', transformOrigin: '0 0 0'}}>
<Draggable bounds="parent" {...dragHandlers} onStop={this.onControlledDragStop} scale={2}>
<div className="box" style={{height: '100px', width: '100px' }}>
<div style={{ width: '160px', transform: 'scale(0.5)', transformOrigin: '0 0 0'}}>
My position can be changed programmatically. <br />
My parent has a transform scaled to 2.
</div>
</div>
</Draggable>
</div>
<Draggable bounds="body" {...dragHandlers}>
<div className="box">
I can only be moved within the confines of the body element.
Expand Down Expand Up @@ -164,7 +175,6 @@ class App extends React.Component {
</p>
</div>
</Draggable>

</div>
);
}
Expand Down
2 changes: 0 additions & 2 deletions lib/Draggable.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ class Draggable extends React.Component<DraggableProps, DraggableState> {
defaultClassNameDragged: 'react-draggable-dragged',
defaultPosition: {x: 0, y: 0},
position: null,
scale: 1
};

// React 16.3+
Expand Down Expand Up @@ -329,7 +328,6 @@ class Draggable extends React.Component<DraggableProps, DraggableState> {
defaultClassNameDragged,
position,
positionOffset,
scale,
...draggableCoreProps
} = this.props;

Expand Down
8 changes: 8 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,12 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
*/
onMouseDown: PropTypes.func,

/**
* `scale` specifies the scale of canvas you are dragging this node on,
* which should be applied on core deltas
*/
scale: PropTypes.number,

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

state = {
Expand Down
9 changes: 5 additions & 4 deletions lib/utils/domFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,15 @@ 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 = 1): 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 validScale = scale || 1;
const x = (evt.clientX + offsetParent.scrollLeft - offsetParentRect.left) / validScale;
const y = (evt.clientY + offsetParent.scrollTop - offsetParentRect.top) / validScale;

return {x, y};
return {x , y};
}

export function createCSSTransform(controlPos: ControlPosition, positionOffset: PositionOffsetControlPosition): Object {
Expand Down
18 changes: 9 additions & 9 deletions lib/utils/positionFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,14 @@ 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
export function createCoreData(draggable: DraggableCore, x: number, y: number): DraggableData {
const state = draggable.state;
const isStart = !isNum(state.lastX);
const node = findDOMNode(draggable);

if (isStart) {
// If this is our first move, use the x and y as last coords.
return {
Expand All @@ -94,22 +93,23 @@ export function createCoreData(draggable: DraggableCore, x: number, y: number):
// Otherwise calculate proper values.
return {
node,
deltaX: x - state.lastX, deltaY: y - state.lastY,
lastX: state.lastX, lastY: state.lastY,
deltaX: x - state.lastX,
deltaY: y - state.lastY,
lastX: state.lastX,
lastY: state.lastY,
x, y,
};
}
}

// Create an data exposed by <Draggable>'s events
export function createDraggableData(draggable: Draggable, coreData: DraggableData): DraggableData {
const scale = draggable.props.scale;
return {
node: coreData.node,
x: draggable.state.x + (coreData.deltaX / scale),
y: draggable.state.y + (coreData.deltaY / scale),
deltaX: (coreData.deltaX / scale),
deltaY: (coreData.deltaY / scale),
x: draggable.state.x + coreData.deltaX,
y: draggable.state.y + coreData.deltaY,
deltaX: coreData.deltaX,
deltaY: coreData.deltaY,
lastX: draggable.state.x,
lastY: draggable.state.y
};
Expand Down
22 changes: 22 additions & 0 deletions specs/draggable.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,32 @@ describe('react-draggable', function () {
assert(drag.props.onStop === handleStop);
});

it('should adjust draggablecore data output when `scale` prop supplied', function () {
function onDrag(event, data) {
assert(data.x === 50);
assert(data.y === 50);
assert(data.lastX === 0);
assert(data.lastY === 0);
assert(data.deltaX === 50);
assert(data.deltaY === 50);
}
drag = TestUtils.renderIntoDocument(
<DraggableCore
scale={2}
onDrag={onDrag}>
<div />
</DraggableCore>
);

simulateMovementFromTo(drag, 0, 0, 100, 100);
});

it('should adjust draggable data output when `scale` prop supplied', function () {
function onDrag(event, data) {
assert(data.x === 200);
assert(data.y === 200);
assert(data.lastX === 0);
assert(data.lastY === 0);
assert(data.deltaX === 200);
assert(data.deltaY === 200);
}
Expand Down