Draggable.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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;
  19. if (draggingTarget && draggingTarget.draggable) {
  20. this._draggingTarget = draggingTarget;
  21. draggingTarget.dragging = true;
  22. this._x = e.offsetX;
  23. this._y = e.offsetY;
  24. this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
  25. }
  26. },
  27. _drag: function (e) {
  28. var draggingTarget = this._draggingTarget;
  29. if (draggingTarget) {
  30. var x = e.offsetX;
  31. var y = e.offsetY;
  32. var dx = x - this._x;
  33. var dy = y - this._y;
  34. this._x = x;
  35. this._y = y;
  36. draggingTarget.drift(dx, dy, e);
  37. this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);
  38. var dropTarget = this.findHover(x, y, draggingTarget).target;
  39. var lastDropTarget = this._dropTarget;
  40. this._dropTarget = dropTarget;
  41. if (draggingTarget !== dropTarget) {
  42. if (lastDropTarget && dropTarget !== lastDropTarget) {
  43. this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
  44. }
  45. if (dropTarget && dropTarget !== lastDropTarget) {
  46. this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
  47. }
  48. }
  49. }
  50. },
  51. _dragEnd: function (e) {
  52. var draggingTarget = this._draggingTarget;
  53. if (draggingTarget) {
  54. draggingTarget.dragging = false;
  55. }
  56. this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);
  57. if (this._dropTarget) {
  58. this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
  59. }
  60. this._draggingTarget = null;
  61. this._dropTarget = null;
  62. }
  63. };
  64. function param(target, e) {
  65. return {
  66. target: target,
  67. topTarget: e && e.topTarget
  68. };
  69. }
  70. var _default = Draggable;
  71. module.exports = _default;