123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import Handler from '../Handler';
- import Element, { ElementEvent } from '../Element';
- import Displayable from '../graphic/Displayable';
- class Param {
- target: Element
- topTarget: Element
- constructor(target: Element, e?: ElementEvent) {
- this.target = target;
- this.topTarget = e && e.topTarget;
- }
- }
- // FIXME Draggable on element which has parent rotation or scale
- export default class Draggable {
- handler: Handler
- _draggingTarget: Element
- _dropTarget: Element
- _x: number
- _y: number
- constructor(handler: Handler) {
- this.handler = handler;
- handler.on('mousedown', this._dragStart, this);
- handler.on('mousemove', this._drag, this);
- handler.on('mouseup', this._dragEnd, this);
- // `mosuemove` and `mouseup` can be continue to fire when dragging.
- // See [DRAG_OUTSIDE] in `Handler.js`. So we do not need to trigger
- // `_dragEnd` when globalout. That would brings better user experience.
- // this.on('globalout', this._dragEnd, this);
- // this._dropTarget = null;
- // this._draggingTarget = null;
- // this._x = 0;
- // this._y = 0;
- }
- _dragStart(e: ElementEvent) {
- let draggingTarget = e.target;
- // Find if there is draggable in the ancestor
- while (draggingTarget && !draggingTarget.draggable) {
- draggingTarget = draggingTarget.parent || draggingTarget.__hostTarget;
- }
- if (draggingTarget) {
- this._draggingTarget = draggingTarget;
- draggingTarget.dragging = true;
- this._x = e.offsetX;
- this._y = e.offsetY;
- this.handler.dispatchToElement(
- new Param(draggingTarget, e), 'dragstart', e.event
- );
- }
- }
- _drag(e: ElementEvent) {
- const draggingTarget = this._draggingTarget;
- if (draggingTarget) {
- const x = e.offsetX;
- const y = e.offsetY;
- const dx = x - this._x;
- const dy = y - this._y;
- this._x = x;
- this._y = y;
- draggingTarget.drift(dx, dy, e);
- this.handler.dispatchToElement(
- new Param(draggingTarget, e), 'drag', e.event
- );
- const dropTarget = this.handler.findHover(
- x, y, draggingTarget as Displayable // PENDING
- ).target;
- const lastDropTarget = this._dropTarget;
- this._dropTarget = dropTarget;
- if (draggingTarget !== dropTarget) {
- if (lastDropTarget && dropTarget !== lastDropTarget) {
- this.handler.dispatchToElement(
- new Param(lastDropTarget, e), 'dragleave', e.event
- );
- }
- if (dropTarget && dropTarget !== lastDropTarget) {
- this.handler.dispatchToElement(
- new Param(dropTarget, e), 'dragenter', e.event
- );
- }
- }
- }
- }
- _dragEnd(e: ElementEvent) {
- const draggingTarget = this._draggingTarget;
- if (draggingTarget) {
- draggingTarget.dragging = false;
- }
- this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragend', e.event);
- if (this._dropTarget) {
- this.handler.dispatchToElement(new Param(this._dropTarget, e), 'drop', e.event);
- }
- this._draggingTarget = null;
- this._dropTarget = null;
- }
- }
|