208 lines
5.4 KiB
JavaScript
208 lines
5.4 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.canDragX = canDragX;
|
|
exports.canDragY = canDragY;
|
|
exports.createCoreData = createCoreData;
|
|
exports.createDraggableData = createDraggableData;
|
|
exports.getBoundPosition = getBoundPosition;
|
|
exports.getControlPosition = getControlPosition;
|
|
exports.snapToGrid = snapToGrid;
|
|
|
|
var _shims = require("./shims");
|
|
|
|
var _domFns = require("./domFns");
|
|
|
|
function getBoundPosition(draggable
|
|
/*: Draggable*/
|
|
, x
|
|
/*: number*/
|
|
, y
|
|
/*: number*/
|
|
)
|
|
/*: [number, number]*/
|
|
{
|
|
// If no bounds, short-circuit and move on
|
|
if (!draggable.props.bounds) return [x, y]; // Clone new bounds
|
|
|
|
var bounds = draggable.props.bounds;
|
|
bounds = typeof bounds === 'string' ? bounds : cloneBounds(bounds);
|
|
var node = findDOMNode(draggable);
|
|
|
|
if (typeof bounds === 'string') {
|
|
var ownerDocument = node.ownerDocument;
|
|
var ownerWindow = ownerDocument.defaultView;
|
|
var boundNode;
|
|
|
|
if (bounds === 'parent') {
|
|
boundNode = node.parentNode;
|
|
} else {
|
|
boundNode = ownerDocument.querySelector(bounds);
|
|
}
|
|
|
|
if (!(boundNode instanceof ownerWindow.HTMLElement)) {
|
|
throw new Error('Bounds selector "' + bounds + '" could not find an element.');
|
|
}
|
|
|
|
var boundNodeEl
|
|
/*: HTMLElement*/
|
|
= boundNode; // for Flow, can't seem to refine correctly
|
|
|
|
var nodeStyle = ownerWindow.getComputedStyle(node);
|
|
var boundNodeStyle = ownerWindow.getComputedStyle(boundNodeEl); // Compute bounds. This is a pain with padding and offsets but this gets it exactly right.
|
|
|
|
bounds = {
|
|
left: -node.offsetLeft + (0, _shims.int)(boundNodeStyle.paddingLeft) + (0, _shims.int)(nodeStyle.marginLeft),
|
|
top: -node.offsetTop + (0, _shims.int)(boundNodeStyle.paddingTop) + (0, _shims.int)(nodeStyle.marginTop),
|
|
right: (0, _domFns.innerWidth)(boundNodeEl) - (0, _domFns.outerWidth)(node) - node.offsetLeft + (0, _shims.int)(boundNodeStyle.paddingRight) - (0, _shims.int)(nodeStyle.marginRight),
|
|
bottom: (0, _domFns.innerHeight)(boundNodeEl) - (0, _domFns.outerHeight)(node) - node.offsetTop + (0, _shims.int)(boundNodeStyle.paddingBottom) - (0, _shims.int)(nodeStyle.marginBottom)
|
|
};
|
|
} // Keep x and y below right and bottom limits...
|
|
|
|
|
|
if ((0, _shims.isNum)(bounds.right)) x = Math.min(x, bounds.right);
|
|
if ((0, _shims.isNum)(bounds.bottom)) y = Math.min(y, bounds.bottom); // But above left and top limits.
|
|
|
|
if ((0, _shims.isNum)(bounds.left)) x = Math.max(x, bounds.left);
|
|
if ((0, _shims.isNum)(bounds.top)) y = Math.max(y, bounds.top);
|
|
return [x, y];
|
|
}
|
|
|
|
function snapToGrid(grid
|
|
/*: [number, number]*/
|
|
, pendingX
|
|
/*: number*/
|
|
, pendingY
|
|
/*: number*/
|
|
)
|
|
/*: [number, number]*/
|
|
{
|
|
var x = Math.round(pendingX / grid[0]) * grid[0];
|
|
var y = Math.round(pendingY / grid[1]) * grid[1];
|
|
return [x, y];
|
|
}
|
|
|
|
function canDragX(draggable
|
|
/*: Draggable*/
|
|
)
|
|
/*: boolean*/
|
|
{
|
|
return draggable.props.axis === 'both' || draggable.props.axis === 'x';
|
|
}
|
|
|
|
function canDragY(draggable
|
|
/*: Draggable*/
|
|
)
|
|
/*: boolean*/
|
|
{
|
|
return draggable.props.axis === 'both' || draggable.props.axis === 'y';
|
|
} // Get {x, y} positions from event.
|
|
|
|
|
|
function getControlPosition(e
|
|
/*: MouseTouchEvent*/
|
|
, touchIdentifier
|
|
/*: ?number*/
|
|
, draggableCore
|
|
/*: DraggableCore*/
|
|
)
|
|
/*: ?ControlPosition*/
|
|
{
|
|
var touchObj = typeof touchIdentifier === 'number' ? (0, _domFns.getTouch)(e, touchIdentifier) : null;
|
|
if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch
|
|
|
|
var node = findDOMNode(draggableCore); // User can provide an offsetParent if desired.
|
|
|
|
var offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body;
|
|
return (0, _domFns.offsetXYFromParent)(touchObj || e, offsetParent, draggableCore.props.scale);
|
|
} // Create an data object exposed by <DraggableCore>'s events
|
|
|
|
|
|
function createCoreData(draggable
|
|
/*: DraggableCore*/
|
|
, x
|
|
/*: number*/
|
|
, y
|
|
/*: number*/
|
|
)
|
|
/*: DraggableData*/
|
|
{
|
|
var state = draggable.state;
|
|
var isStart = !(0, _shims.isNum)(state.lastX);
|
|
var node = findDOMNode(draggable);
|
|
|
|
if (isStart) {
|
|
// If this is our first move, use the x and y as last coords.
|
|
return {
|
|
node: node,
|
|
deltaX: 0,
|
|
deltaY: 0,
|
|
lastX: x,
|
|
lastY: y,
|
|
x: x,
|
|
y: y
|
|
};
|
|
} else {
|
|
// Otherwise calculate proper values.
|
|
return {
|
|
node: node,
|
|
deltaX: x - state.lastX,
|
|
deltaY: y - state.lastY,
|
|
lastX: state.lastX,
|
|
lastY: state.lastY,
|
|
x: x,
|
|
y: y
|
|
};
|
|
}
|
|
} // Create an data exposed by <Draggable>'s events
|
|
|
|
|
|
function createDraggableData(draggable
|
|
/*: Draggable*/
|
|
, coreData
|
|
/*: DraggableData*/
|
|
)
|
|
/*: DraggableData*/
|
|
{
|
|
var 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,
|
|
lastX: draggable.state.x,
|
|
lastY: draggable.state.y
|
|
};
|
|
} // A lot faster than stringify/parse
|
|
|
|
|
|
function cloneBounds(bounds
|
|
/*: Bounds*/
|
|
)
|
|
/*: Bounds*/
|
|
{
|
|
return {
|
|
left: bounds.left,
|
|
top: bounds.top,
|
|
right: bounds.right,
|
|
bottom: bounds.bottom
|
|
};
|
|
}
|
|
|
|
function findDOMNode(draggable
|
|
/*: Draggable | DraggableCore*/
|
|
)
|
|
/*: HTMLElement*/
|
|
{
|
|
var node = draggable.findDOMNode();
|
|
|
|
if (!node) {
|
|
throw new Error('<DraggableCore>: Unmounted during event!');
|
|
} // $FlowIgnore we can't assert on HTMLElement due to tests... FIXME
|
|
|
|
|
|
return node;
|
|
} |