Draggable.js 2.8 KB

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