react-draggable
Advanced tools
Comparing version
@@ -21,2 +21,6 @@ # Changelog | ||
- Exporting as ReactDraggable | ||
- Exporting as ReactDraggable | ||
### 0.3.0 (Oct 21, 2014) | ||
- Adding support for touch devices |
@@ -89,22 +89,66 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
function isFunction(fn) { | ||
return typeof fn === 'function'; | ||
function isFunction(func) { | ||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]' | ||
} | ||
// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc | ||
function findInArray(array, callback) { | ||
for (var i = 0, length = array.length, element = null; i < length, element = array[i]; i++) { | ||
if (callback.apply(callback, [element, i, array])) return element; | ||
} | ||
} | ||
function matchesSelector(el, selector) { | ||
if (isFunction(el.matches)) { | ||
return el.matches(selector); | ||
} else if (isFunction(el.webkitMatchesSelector)) { | ||
return el.webkitMatchesSelector(selector); | ||
} else if (isFunction(el.mozMatchesSelector)) { | ||
return el.mozMatchesSelector(selector); | ||
} else if (isFunction(el.msMatchesSelector)) { | ||
return el.msMatchesSelector(selector); | ||
} else if (isFunction(el.oMatchesSelector)) { | ||
return el.oMatchesSelector(selector); | ||
} else if (isFunction(el.webkitMatchesSelector)) { | ||
return el.webkitMatchesSelector(selector); | ||
} | ||
var method = findInArray([ | ||
'matches', | ||
'webkitMatchesSelector', | ||
'mozMatchesSelector', | ||
'msMatchesSelector', | ||
'oMatchesSelector' | ||
], function(method){ | ||
return isFunction(el[method]); | ||
}); | ||
return el[method].call(el, selector); | ||
} | ||
// @credits: http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886 | ||
var isTouchDevice = 'ontouchstart' in window // works on most browsers | ||
|| 'onmsgesturechange' in window; // works on ie10 on ms surface | ||
// look ::handleDragStart | ||
//function isMultiTouch(e) { | ||
// return e.touches && Array.isArray(e.touches) && e.touches.length > 1 | ||
//} | ||
/** | ||
* simple abstraction for dragging events names | ||
* */ | ||
var dragEventFor = (function () { | ||
var eventsFor = { | ||
touch: { | ||
start: 'touchstart', | ||
move: 'touchmove', | ||
end: 'touchend' | ||
}, | ||
mouse: { | ||
start: 'mousedown', | ||
move: 'mousemove', | ||
end: 'mouseup' | ||
} | ||
}; | ||
return eventsFor[isTouchDevice ? 'touch' : 'mouse']; | ||
})(); | ||
/** | ||
* get {clientX, clientY} positions of control | ||
* */ | ||
function getControlPosition(e) { | ||
var position = !isTouchDevice ? e : e.touches[0]; | ||
return { | ||
clientX: position.clientX, | ||
clientY: position.clientY | ||
} | ||
} | ||
function addEvent(el, event, handler) { | ||
@@ -317,4 +361,4 @@ if (!el) { return; } | ||
// Remove any leftover event handlers | ||
removeEvent(window, 'mousemove', this.handleMouseMove); | ||
removeEvent(window, 'mouseup', this.handleMouseUp); | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
@@ -356,3 +400,10 @@ | ||
handleMouseDown: function (e) { | ||
handleDragStart: function (e) { | ||
// todo: write right implementation to prevent multitouch drag | ||
// prevent multi-touch events | ||
// if (isMultiTouch(e)) { | ||
// this.handleDragEnd.apply(e, arguments); | ||
// return | ||
// } | ||
// Make it possible to attach event handlers on top of this one | ||
@@ -369,7 +420,9 @@ this.props.onMouseDown(e); | ||
var dragPoint = getControlPosition(e); | ||
// Initiate dragging | ||
this.setState({ | ||
dragging: true, | ||
offsetX: e.clientX, | ||
offsetY: e.clientY, | ||
offsetX: dragPoint.clientX, | ||
offsetY: dragPoint.clientY, | ||
startX: parseInt(node.style.left, 10) || 0, | ||
@@ -383,7 +436,7 @@ startY: parseInt(node.style.top, 10) || 0 | ||
// Add event handlers | ||
addEvent(window, 'mousemove', this.handleMouseMove); | ||
addEvent(window, 'mouseup', this.handleMouseUp); | ||
addEvent(window, dragEventFor['move'], this.handleDrag); | ||
addEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
handleMouseUp: function (e) { | ||
handleDragEnd: function (e) { | ||
// Short circuit if not currently dragging | ||
@@ -403,10 +456,12 @@ if (!this.state.dragging) { | ||
// Remove event handlers | ||
removeEvent(window, 'mousemove', this.handleMouseMove); | ||
removeEvent(window, 'mouseup', this.handleMouseUp); | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
handleMouseMove: function (e) { | ||
handleDrag: function (e) { | ||
var dragPoint = getControlPosition(e); | ||
// Calculate top and left | ||
var clientX = (this.state.startX + (e.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (e.clientY - this.state.offsetY)); | ||
var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY)); | ||
@@ -457,4 +512,11 @@ // Snap to grid if prop has been provided | ||
className: 'react-draggable', | ||
onMouseUp: this.handleMouseUp, | ||
onMouseDown: this.handleMouseDown | ||
onMouseDown: this.handleDragStart, | ||
onTouchStart: function(ev){ | ||
ev.preventDefault(); // prevent for scroll | ||
return this.handleDragStart.apply(this, arguments); | ||
}.bind(this), | ||
onMouseUp: this.handleDragEnd, | ||
onTouchEnd: this.handleDragEnd | ||
}); | ||
@@ -461,0 +523,0 @@ } |
@@ -1,2 +0,2 @@ | ||
!function(root,factory){"object"==typeof exports&&"object"==typeof module?module.exports=factory(require("React")):"function"==typeof define&&define.amd?define(["React"],factory):"object"==typeof exports?exports.ReactDraggable=factory(require("React")):root.ReactDraggable=factory(root.React)}(this,function(__WEBPACK_EXTERNAL_MODULE_2__){return function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){module.exports=__webpack_require__(1)},function(module,exports,__webpack_require__){"use strict";function createUIEvent(draggable){return{position:{top:draggable.state.clientY,left:draggable.state.clientX}}}function canDragY(draggable){return"both"===draggable.props.axis||"y"===draggable.props.axis}function canDragX(draggable){return"both"===draggable.props.axis||"x"===draggable.props.axis}function isFunction(fn){return"function"==typeof fn}function matchesSelector(el,selector){return isFunction(el.matches)?el.matches(selector):isFunction(el.webkitMatchesSelector)?el.webkitMatchesSelector(selector):isFunction(el.mozMatchesSelector)?el.mozMatchesSelector(selector):isFunction(el.msMatchesSelector)?el.msMatchesSelector(selector):isFunction(el.oMatchesSelector)?el.oMatchesSelector(selector):isFunction(el.webkitMatchesSelector)?el.webkitMatchesSelector(selector):void 0}function addEvent(el,event,handler){el&&(el.attachEvent?el.attachEvent("on"+event,handler):el.addEventListener?el.addEventListener(event,handler,!0):el["on"+event]=handler)}function removeEvent(el,event,handler){el&&(el.detachEvent?el.detachEvent("on"+event,handler):el.removeEventListener?el.removeEventListener(event,handler,!0):el["on"+event]=null)}var React=__webpack_require__(2),emptyFunction=__webpack_require__(3);module.exports=React.createClass({displayName:"Draggable",propTypes:{axis:React.PropTypes.oneOf(["both","x","y"]),handle:React.PropTypes.string,cancel:React.PropTypes.string,grid:React.PropTypes.arrayOf(React.PropTypes.number),start:React.PropTypes.object,zIndex:React.PropTypes.number,onStart:React.PropTypes.func,onDrag:React.PropTypes.func,onStop:React.PropTypes.func,onMouseDown:React.PropTypes.func},componentWillUnmount:function(){removeEvent(window,"mousemove",this.handleMouseMove),removeEvent(window,"mouseup",this.handleMouseUp)},getDefaultProps:function(){return{axis:"both",handle:null,cancel:null,grid:null,start:{x:0,y:0},zIndex:0/0,onStart:emptyFunction,onDrag:emptyFunction,onStop:emptyFunction,onMouseDown:emptyFunction}},getInitialState:function(){return{dragging:!1,startX:0,startY:0,offsetX:0,offsetY:0,clientX:this.props.start.x,clientY:this.props.start.y}},handleMouseDown:function(e){this.props.onMouseDown(e);var node=this.getDOMNode();this.props.handle&&!matchesSelector(e.target,this.props.handle)||this.props.cancel&&matchesSelector(e.target,this.props.cancel)||(this.setState({dragging:!0,offsetX:e.clientX,offsetY:e.clientY,startX:parseInt(node.style.left,10)||0,startY:parseInt(node.style.top,10)||0}),this.props.onStart(e,createUIEvent(this)),addEvent(window,"mousemove",this.handleMouseMove),addEvent(window,"mouseup",this.handleMouseUp))},handleMouseUp:function(e){this.state.dragging&&(this.setState({dragging:!1}),this.props.onStop(e,createUIEvent(this)),removeEvent(window,"mousemove",this.handleMouseMove),removeEvent(window,"mouseup",this.handleMouseUp))},handleMouseMove:function(e){var clientX=this.state.startX+(e.clientX-this.state.offsetX),clientY=this.state.startY+(e.clientY-this.state.offsetY);Array.isArray(this.props.grid)&&(clientX=Math.abs(clientX-this.state.clientX)>=this.props.grid[0]?clientX:this.state.clientX,clientY=Math.abs(clientY-this.state.clientY)>=this.props.grid[1]?clientY:this.state.clientY),this.setState({clientX:clientX,clientY:clientY}),this.props.onDrag(e,createUIEvent(this))},render:function(){var style={top:canDragY(this)?this.state.clientY:this.state.startY,left:canDragX(this)?this.state.clientX:this.state.startX};return this.state.dragging&&!isNaN(this.props.zIndex)&&(style.zIndex=this.props.zIndex),React.addons.cloneWithProps(React.Children.only(this.props.children),{style:style,className:"react-draggable",onMouseUp:this.handleMouseUp,onMouseDown:this.handleMouseDown})}})},function(module){module.exports=__WEBPACK_EXTERNAL_MODULE_2__},function(module,exports,__webpack_require__){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}var copyProperties=__webpack_require__(4);copyProperties(emptyFunction,{thatReturns:makeEmptyFunction,thatReturnsFalse:makeEmptyFunction(!1),thatReturnsTrue:makeEmptyFunction(!0),thatReturnsNull:makeEmptyFunction(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(arg){return arg}}),module.exports=emptyFunction},function(module,exports,__webpack_require__){(function(process){function copyProperties(obj,a,b,c,d,e,f){if(obj=obj||{},"production"!==process.env.NODE_ENV&&f)throw new Error("Too many arguments passed to copyProperties");for(var v,args=[a,b,c,d,e],ii=0;args[ii];){v=args[ii++];for(var k in v)obj[k]=v[k];v.hasOwnProperty&&v.hasOwnProperty("toString")&&"undefined"!=typeof v.toString&&obj.toString!==v.toString&&(obj.toString=v.toString)}return obj}module.exports=copyProperties}).call(exports,__webpack_require__(5))},function(module){function noop(){}var process=module.exports={};process.nextTick=function(){var canSetImmediate="undefined"!=typeof window&&window.setImmediate,canPost="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(canSetImmediate)return function(f){return window.setImmediate(f)};if(canPost){var queue=[];return window.addEventListener("message",function(ev){var source=ev.source;if((source===window||null===source)&&"process-tick"===ev.data&&(ev.stopPropagation(),queue.length>0)){var fn=queue.shift();fn()}},!0),function(fn){queue.push(fn),window.postMessage("process-tick","*")}}return function(fn){setTimeout(fn,0)}}(),process.title="browser",process.browser=!0,process.env={},process.argv=[],process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.binding=function(){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(){throw new Error("process.chdir is not supported")}}])}); | ||
!function(root,factory){"object"==typeof exports&&"object"==typeof module?module.exports=factory(require("React")):"function"==typeof define&&define.amd?define(["React"],factory):"object"==typeof exports?exports.ReactDraggable=factory(require("React")):root.ReactDraggable=factory(root.React)}(this,function(__WEBPACK_EXTERNAL_MODULE_2__){return function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){module.exports=__webpack_require__(1)},function(module,exports,__webpack_require__){"use strict";function createUIEvent(draggable){return{position:{top:draggable.state.clientY,left:draggable.state.clientX}}}function canDragY(draggable){return"both"===draggable.props.axis||"y"===draggable.props.axis}function canDragX(draggable){return"both"===draggable.props.axis||"x"===draggable.props.axis}function isFunction(func){return"function"==typeof func||"[object Function]"===Object.prototype.toString.call(func)}function findInArray(array,callback){for(var i=0,element=(array.length,null);element=array[i];i++)if(callback.apply(callback,[element,i,array]))return element}function matchesSelector(el,selector){var method=findInArray(["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"],function(method){return isFunction(el[method])});return el[method].call(el,selector)}function getControlPosition(e){var position=isTouchDevice?e.touches[0]:e;return{clientX:position.clientX,clientY:position.clientY}}function addEvent(el,event,handler){el&&(el.attachEvent?el.attachEvent("on"+event,handler):el.addEventListener?el.addEventListener(event,handler,!0):el["on"+event]=handler)}function removeEvent(el,event,handler){el&&(el.detachEvent?el.detachEvent("on"+event,handler):el.removeEventListener?el.removeEventListener(event,handler,!0):el["on"+event]=null)}var React=__webpack_require__(2),emptyFunction=__webpack_require__(3),isTouchDevice="ontouchstart"in window||"onmsgesturechange"in window,dragEventFor=function(){var eventsFor={touch:{start:"touchstart",move:"touchmove",end:"touchend"},mouse:{start:"mousedown",move:"mousemove",end:"mouseup"}};return eventsFor[isTouchDevice?"touch":"mouse"]}();module.exports=React.createClass({displayName:"Draggable",propTypes:{axis:React.PropTypes.oneOf(["both","x","y"]),handle:React.PropTypes.string,cancel:React.PropTypes.string,grid:React.PropTypes.arrayOf(React.PropTypes.number),start:React.PropTypes.object,zIndex:React.PropTypes.number,onStart:React.PropTypes.func,onDrag:React.PropTypes.func,onStop:React.PropTypes.func,onMouseDown:React.PropTypes.func},componentWillUnmount:function(){removeEvent(window,dragEventFor.move,this.handleDrag),removeEvent(window,dragEventFor.end,this.handleDragEnd)},getDefaultProps:function(){return{axis:"both",handle:null,cancel:null,grid:null,start:{x:0,y:0},zIndex:0/0,onStart:emptyFunction,onDrag:emptyFunction,onStop:emptyFunction,onMouseDown:emptyFunction}},getInitialState:function(){return{dragging:!1,startX:0,startY:0,offsetX:0,offsetY:0,clientX:this.props.start.x,clientY:this.props.start.y}},handleDragStart:function(e){this.props.onMouseDown(e);var node=this.getDOMNode();if(!(this.props.handle&&!matchesSelector(e.target,this.props.handle)||this.props.cancel&&matchesSelector(e.target,this.props.cancel))){var dragPoint=getControlPosition(e);this.setState({dragging:!0,offsetX:dragPoint.clientX,offsetY:dragPoint.clientY,startX:parseInt(node.style.left,10)||0,startY:parseInt(node.style.top,10)||0}),this.props.onStart(e,createUIEvent(this)),addEvent(window,dragEventFor.move,this.handleDrag),addEvent(window,dragEventFor.end,this.handleDragEnd)}},handleDragEnd:function(e){this.state.dragging&&(this.setState({dragging:!1}),this.props.onStop(e,createUIEvent(this)),removeEvent(window,dragEventFor.move,this.handleDrag),removeEvent(window,dragEventFor.end,this.handleDragEnd))},handleDrag:function(e){var dragPoint=getControlPosition(e),clientX=this.state.startX+(dragPoint.clientX-this.state.offsetX),clientY=this.state.startY+(dragPoint.clientY-this.state.offsetY);Array.isArray(this.props.grid)&&(clientX=Math.abs(clientX-this.state.clientX)>=this.props.grid[0]?clientX:this.state.clientX,clientY=Math.abs(clientY-this.state.clientY)>=this.props.grid[1]?clientY:this.state.clientY),this.setState({clientX:clientX,clientY:clientY}),this.props.onDrag(e,createUIEvent(this))},render:function(){var style={top:canDragY(this)?this.state.clientY:this.state.startY,left:canDragX(this)?this.state.clientX:this.state.startX};return this.state.dragging&&!isNaN(this.props.zIndex)&&(style.zIndex=this.props.zIndex),React.addons.cloneWithProps(React.Children.only(this.props.children),{style:style,className:"react-draggable",onMouseDown:this.handleDragStart,onTouchStart:function(ev){return ev.preventDefault(),this.handleDragStart.apply(this,arguments)}.bind(this),onMouseUp:this.handleDragEnd,onTouchEnd:this.handleDragEnd})}})},function(module){module.exports=__WEBPACK_EXTERNAL_MODULE_2__},function(module,exports,__webpack_require__){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}var copyProperties=__webpack_require__(4);copyProperties(emptyFunction,{thatReturns:makeEmptyFunction,thatReturnsFalse:makeEmptyFunction(!1),thatReturnsTrue:makeEmptyFunction(!0),thatReturnsNull:makeEmptyFunction(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(arg){return arg}}),module.exports=emptyFunction},function(module,exports,__webpack_require__){(function(process){function copyProperties(obj,a,b,c,d,e,f){if(obj=obj||{},"production"!==process.env.NODE_ENV&&f)throw new Error("Too many arguments passed to copyProperties");for(var v,args=[a,b,c,d,e],ii=0;args[ii];){v=args[ii++];for(var k in v)obj[k]=v[k];v.hasOwnProperty&&v.hasOwnProperty("toString")&&"undefined"!=typeof v.toString&&obj.toString!==v.toString&&(obj.toString=v.toString)}return obj}module.exports=copyProperties}).call(exports,__webpack_require__(5))},function(module){function noop(){}var process=module.exports={};process.nextTick=function(){var canSetImmediate="undefined"!=typeof window&&window.setImmediate,canPost="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(canSetImmediate)return function(f){return window.setImmediate(f)};if(canPost){var queue=[];return window.addEventListener("message",function(ev){var source=ev.source;if((source===window||null===source)&&"process-tick"===ev.data&&(ev.stopPropagation(),queue.length>0)){var fn=queue.shift();fn()}},!0),function(fn){queue.push(fn),window.postMessage("process-tick","*")}}return function(fn){setTimeout(fn,0)}}(),process.title="browser",process.browser=!0,process.env={},process.argv=[],process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.binding=function(){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(){throw new Error("process.chdir is not supported")}}])}); | ||
//# sourceMappingURL=react-draggable.min.map |
@@ -26,22 +26,66 @@ 'use strict'; | ||
function isFunction(fn) { | ||
return typeof fn === 'function'; | ||
function isFunction(func) { | ||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]' | ||
} | ||
// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc | ||
function findInArray(array, callback) { | ||
for (var i = 0, length = array.length, element = null; i < length, element = array[i]; i++) { | ||
if (callback.apply(callback, [element, i, array])) return element; | ||
} | ||
} | ||
function matchesSelector(el, selector) { | ||
if (isFunction(el.matches)) { | ||
return el.matches(selector); | ||
} else if (isFunction(el.webkitMatchesSelector)) { | ||
return el.webkitMatchesSelector(selector); | ||
} else if (isFunction(el.mozMatchesSelector)) { | ||
return el.mozMatchesSelector(selector); | ||
} else if (isFunction(el.msMatchesSelector)) { | ||
return el.msMatchesSelector(selector); | ||
} else if (isFunction(el.oMatchesSelector)) { | ||
return el.oMatchesSelector(selector); | ||
} else if (isFunction(el.webkitMatchesSelector)) { | ||
return el.webkitMatchesSelector(selector); | ||
} | ||
var method = findInArray([ | ||
'matches', | ||
'webkitMatchesSelector', | ||
'mozMatchesSelector', | ||
'msMatchesSelector', | ||
'oMatchesSelector' | ||
], function(method){ | ||
return isFunction(el[method]); | ||
}); | ||
return el[method].call(el, selector); | ||
} | ||
// @credits: http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886 | ||
var isTouchDevice = 'ontouchstart' in window // works on most browsers | ||
|| 'onmsgesturechange' in window; // works on ie10 on ms surface | ||
// look ::handleDragStart | ||
//function isMultiTouch(e) { | ||
// return e.touches && Array.isArray(e.touches) && e.touches.length > 1 | ||
//} | ||
/** | ||
* simple abstraction for dragging events names | ||
* */ | ||
var dragEventFor = (function () { | ||
var eventsFor = { | ||
touch: { | ||
start: 'touchstart', | ||
move: 'touchmove', | ||
end: 'touchend' | ||
}, | ||
mouse: { | ||
start: 'mousedown', | ||
move: 'mousemove', | ||
end: 'mouseup' | ||
} | ||
}; | ||
return eventsFor[isTouchDevice ? 'touch' : 'mouse']; | ||
})(); | ||
/** | ||
* get {clientX, clientY} positions of control | ||
* */ | ||
function getControlPosition(e) { | ||
var position = !isTouchDevice ? e : e.touches[0]; | ||
return { | ||
clientX: position.clientX, | ||
clientY: position.clientY | ||
} | ||
} | ||
function addEvent(el, event, handler) { | ||
@@ -254,4 +298,4 @@ if (!el) { return; } | ||
// Remove any leftover event handlers | ||
removeEvent(window, 'mousemove', this.handleMouseMove); | ||
removeEvent(window, 'mouseup', this.handleMouseUp); | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
@@ -293,3 +337,10 @@ | ||
handleMouseDown: function (e) { | ||
handleDragStart: function (e) { | ||
// todo: write right implementation to prevent multitouch drag | ||
// prevent multi-touch events | ||
// if (isMultiTouch(e)) { | ||
// this.handleDragEnd.apply(e, arguments); | ||
// return | ||
// } | ||
// Make it possible to attach event handlers on top of this one | ||
@@ -306,7 +357,9 @@ this.props.onMouseDown(e); | ||
var dragPoint = getControlPosition(e); | ||
// Initiate dragging | ||
this.setState({ | ||
dragging: true, | ||
offsetX: e.clientX, | ||
offsetY: e.clientY, | ||
offsetX: dragPoint.clientX, | ||
offsetY: dragPoint.clientY, | ||
startX: parseInt(node.style.left, 10) || 0, | ||
@@ -320,7 +373,7 @@ startY: parseInt(node.style.top, 10) || 0 | ||
// Add event handlers | ||
addEvent(window, 'mousemove', this.handleMouseMove); | ||
addEvent(window, 'mouseup', this.handleMouseUp); | ||
addEvent(window, dragEventFor['move'], this.handleDrag); | ||
addEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
handleMouseUp: function (e) { | ||
handleDragEnd: function (e) { | ||
// Short circuit if not currently dragging | ||
@@ -340,10 +393,12 @@ if (!this.state.dragging) { | ||
// Remove event handlers | ||
removeEvent(window, 'mousemove', this.handleMouseMove); | ||
removeEvent(window, 'mouseup', this.handleMouseUp); | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
handleMouseMove: function (e) { | ||
handleDrag: function (e) { | ||
var dragPoint = getControlPosition(e); | ||
// Calculate top and left | ||
var clientX = (this.state.startX + (e.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (e.clientY - this.state.offsetY)); | ||
var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY)); | ||
@@ -394,6 +449,13 @@ // Snap to grid if prop has been provided | ||
className: 'react-draggable', | ||
onMouseUp: this.handleMouseUp, | ||
onMouseDown: this.handleMouseDown | ||
onMouseDown: this.handleDragStart, | ||
onTouchStart: function(ev){ | ||
ev.preventDefault(); // prevent for scroll | ||
return this.handleDragStart.apply(this, arguments); | ||
}.bind(this), | ||
onMouseUp: this.handleDragEnd, | ||
onTouchEnd: this.handleDragEnd | ||
}); | ||
} | ||
}); |
{ | ||
"name": "react-draggable", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "React draggable component", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
72073
10.52%1050
10.99%