# Draggable 类

# 概述

赋予类实例可拖动的特性,派生类只有 Handler 类

# 构造函数

function Draggable() {
    this.on('mousedown', this._dragStart, this);
    this.on('mousemove', this._drag, this);
    this.on('mouseup', this._dragEnd, this);
}

# 关系

# 派生

# Handler

Handler mvc 中的 controller

# 方法

# _dragStart

开始拖动

_dragStart: function (e) {
    var draggingTarget = e.target;
    // Find if there is draggable in the ancestor
    while (draggingTarget && !draggingTarget.draggable) {
        draggingTarget = draggingTarget.parent;
    }
    if (draggingTarget) {
        this._draggingTarget = draggingTarget;
        draggingTarget.dragging = true;
        this._x = e.offsetX;
        this._y = e.offsetY;

        this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
    }
}

# _drag

正在拖动

_drag: function (e) {
    var draggingTarget = this._draggingTarget;
    if (draggingTarget) {

        var x = e.offsetX;
        var y = e.offsetY;

        var dx = x - this._x;
        var dy = y - this._y;
        this._x = x;
        this._y = y;

        draggingTarget.drift(dx, dy, e);
        this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);

        var dropTarget = this.findHover(x, y, draggingTarget).target;
        var lastDropTarget = this._dropTarget;
        this._dropTarget = dropTarget;

        if (draggingTarget !== dropTarget) {
            if (lastDropTarget && dropTarget !== lastDropTarget) {
                this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
            }
            if (dropTarget && dropTarget !== lastDropTarget) {
                this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
            }
        }
    }
}

# _dragEnd

拖动结束

_dragEnd: function (e) {
    var draggingTarget = this._draggingTarget;

    if (draggingTarget) {
        draggingTarget.dragging = false;
    }

    this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);

    if (this._dropTarget) {
        this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
    }

    this._draggingTarget = null;
    this._dropTarget = null;
}