1 /**
  2  * Hilo
  3  * Copyright 2015 alibaba.com
  4  * Licensed under the MIT License
  5  */
  6 
  7 /**
  8  * <iframe src='../../../examples/drag.html?noHeader' width = '550' height = '250' scrolling='no'></iframe>
  9  * <br/>
 10  * example:
 11  * <pre>
 12  * var bmp = new Bitmap({image:img});
 13  * Hilo.util.copy(bmp, Hilo.drag);
 14  * bmp.startDrag([0, 0, 550, 400]);
 15  * </pre>
 16  * @class drag A mixin that contains drag method.You can mix drag method to the visual target by use Class.mix(target, drag) or Hilo.util.copy(target, drag).
 17  * @mixin
 18  * @static
 19  * @module hilo/util/drag
 20  * @requires hilo/core/Hilo
 21  */
 22 var drag = {
 23     _isDragStart:false,
 24     /**
 25      * 是否需要 transform,父元素有 transform 时需要设置为true
 26      * @default false
 27      * @type {Boolean}
 28      */
 29     dragNeedTransform:false,
 30     /**
 31      * start drag.
 32       * @param {Array} bounds The bounds area that the view can move, relative to the coordinates of the view's parent, [x, y, width, height], default is no limit.
 33     */
 34     startDrag:function(bounds){
 35         var that = this;
 36         
 37         if(that._isDragStart){
 38             that.stopDrag();
 39         }
 40         that._isDragStart = true;
 41 
 42         var stage;
 43         bounds = bounds||[-Infinity, -Infinity, Infinity, Infinity];
 44         var mouse = {
 45             x:0,
 46             y:0,
 47             preX:0,
 48             preY:0
 49         };
 50         var minX = bounds[0];
 51         var minY = bounds[1];
 52         var maxX = bounds[2] == Infinity?Infinity:minX + bounds[2];
 53         var maxY = bounds[3] == Infinity?Infinity:minY + bounds[3];
 54 
 55         var worldPoint = {
 56             x:0, 
 57             y:0
 58         };
 59 
 60         function onStart(e){
 61             e.stopPropagation();
 62             updateMouse(e);
 63             that.off(Hilo.event.POINTER_START, onStart);
 64 
 65             worldPoint.x = that.x;
 66             worldPoint.y = that.y;
 67             
 68             if(that.dragNeedTransform && that.parent){
 69                 that.parent.getConcatenatedMatrix().transformPoint(worldPoint);
 70             }
 71 
 72             that.__dragX = worldPoint.x - mouse.x;
 73             that.__dragY = worldPoint.y - mouse.y;
 74 
 75             if(!stage){
 76                 stage = that.getStage();
 77             }
 78             stage.on(Hilo.event.POINTER_MOVE, onMove);
 79             document.addEventListener(Hilo.event.POINTER_END, onStop);
 80             that.fire("dragStart", mouse);
 81         }
 82 
 83         function onStop(e){
 84             document.removeEventListener(Hilo.event.POINTER_END, onStop);
 85             stage && stage.off(Hilo.event.POINTER_MOVE, onMove);
 86 
 87             that.on(Hilo.event.POINTER_START, onStart);
 88             that.fire("dragEnd", mouse);
 89         }
 90 
 91         function onMove(e){
 92             updateMouse(e);
 93 
 94             worldPoint.x = mouse.x + that.__dragX;
 95             worldPoint.y = mouse.y + that.__dragY;
 96 
 97             if(that.dragNeedTransform && that.parent){
 98                 that.parent.getConcatenatedMatrix().invert().transformPoint(worldPoint);
 99             }
100 
101             that.x = Math.max(minX, Math.min(maxX, worldPoint.x));
102             that.y = Math.max(minY, Math.min(maxY, worldPoint.y));
103             that.fire("dragMove", mouse);
104         }
105 
106         function updateMouse(e){
107             mouse.preX = mouse.x;
108             mouse.preY = mouse.y;
109             mouse.x = e.stageX;
110             mouse.y = e.stageY;
111         }
112 
113         function stopDrag(){
114             that._isDragStart = false;
115             document.removeEventListener(Hilo.event.POINTER_END, onStop);
116             stage && stage.off(Hilo.event.POINTER_MOVE, onMove);
117             that.off(Hilo.event.POINTER_START, onStart);
118         }
119         that.on(Hilo.event.POINTER_START, onStart);
120 
121         that.stopDrag = stopDrag;
122     },
123     /**
124      * stop drag.
125     */
126     stopDrag:function(){
127         this._isDragStart = false;
128     }
129 };