Draggable.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // TODO Draggable for group
  2. // FIXME Draggable on element which has parent rotation or scale
  3. function Draggable() {
  4. this.on('mousedown', this._dragStart, this);
  5. this.on('mousemove', this._drag, this);
  6. this.on('mouseup', this._dragEnd, this); // `mosuemove` and `mouseup` can be continue to fire when dragging.
  7. // See [Drag outside] in `Handler.js`. So we do not need to trigger
  8. // `_dragEnd` when globalout. That would brings better user experience.
  9. // this.on('globalout', this._dragEnd, this);
  10. // this._dropTarget = null;
  11. // this._draggingTarget = null;
  12. // this._x = 0;
  13. // this._y = 0;
  14. }
  15. Draggable.prototype = {
  16. constructor: Draggable,
  17. _dragStart: function (e) {
  18. var draggingTarget = e.target; // Find if there is draggable in the ancestor
  19. while (draggingTarget && !draggingTarget.draggable) {
  20. draggingTarget = draggingTarget.parent;
  21. }
  22. if (draggingTarget) {
  23. this._draggingTarget = draggingTarget;
  24. draggingTarget.dragging = true;
  25. this._x = e.offsetX;
  26. this._y = e.offsetY;
  27. this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
  28. }
  29. },
  30. _drag: function (e) {
  31. var draggingTarget = this._draggingTarget;
  32. if (draggingTarget) {
  33. var x = e.offsetX;
  34. var y = e.offsetY;
  35. var dx = x - this._x;
  36. var dy = y - this._y;
  37. this._x = x;
  38. this._y = y;
  39. draggingTarget.drift(dx, dy, e);
  40. this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);
  41. var dropTarget = this.findHover(x, y, draggingTarget).target;
  42. var lastDropTarget = this._dropTarget;
  43. this._dropTarget = dropTarget;
  44. if (draggingTarget !== dropTarget) {
  45. if (lastDropTarget && dropTarget !== lastDropTarget) {
  46. this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
  47. }
  48. if (dropTarget && dropTarget !== lastDropTarget) {
  49. this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
  50. }
  51. }
  52. }
  53. },
  54. _dragEnd: function (e) {
  55. var draggingTarget = this._draggingTarget;
  56. if (draggingTarget) {
  57. draggingTarget.dragging = false;
  58. }
  59. this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);
  60. if (this._dropTarget) {
  61. this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
  62. }
  63. this._draggingTarget = null;
  64. this._dropTarget = null;
  65. }
  66. };
  67. function param(target, e) {
  68. return {
  69. target: target,
  70. topTarget: e && e.topTarget
  71. };
  72. }
  73. var _default = Draggable;
  74. module.exports = _default;