react-draggable
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72073
1050