2010年4月18日 星期日

拖曳基礎原理,AS3

顯示元件拖曳基礎原理
Fundamentals of Drag for DisplayObject.


基本觀念:
  • 會使用mouseDown、mouseMove、mouseUp,三個事件。
  • mouseDown時記錄住滑鼠在Stage上的座標,並加入mouseMove與mouseUp事件偵聽。
  • 當mouseMove時使用新的滑鼠座標減去mouseDown時座標求得offset。
  • 將拖曳對像的座標+offset。
  • mouseUp發生時移除mouseMove,與mouseUp事件偵聽。
以FB4來撰寫範例:
example:


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="application1_creationCompleteHandler(event)"
>
<s:layout>

     <s:BasicLayout/>
</s:layout>
   <fx:Script>
   <![CDATA[
       import mx.events.FlexEvent;
       protected function application1_creationCompleteHandler(event:FlexEvent):void
      {
          initList();
          initDragTargetPosition();
          //註冊可拖曳對像
          registrationDrag(dragTargetA);
          registrationDrag(dragTargetB);
       }
       //初始化拖曳對象列表
       protected function initList():void
       {
          _dragList = new Vector.<DisplayObject>;
       }
       //初始化顯示元件座標
       protected function initDragTargetPosition():void
       {
         dragTargetA.x = 0;
         dragTargetB.x = dragTargetA.x + dragTargetA.width;
       }

       //拖曳對象列表
       private var _dragList:Vector.<DisplayObject>;
       //註冊拖曳
       public function registrationDrag(dragTarget:DisplayObject):void
       {
         //從index0開始搜尋,若dragTarget存在傳回所在index,不存在傳回-1
         if( _dragList.indexOf(dragTarget) >= 0)             return;
         addMouseDownEL(dragTarget);
         _dragList.push(dragTarget);
       }
      //撤銷拖曳登記
      public function revocation(dragTarget:DisplayObject):void
      {
        var delIndex:int = _dragList.indexOf(dragTarget);
        if(delIndex < 0)
             return;
        delMouseDownEL(dragTarget);
        _dragList.splice(delIndex , 1);
      }
    
      private var originaMouseX:Number;
      private var originaMouseY:Number;
      /*另一種計算方式所需變數,稱之方式二        private var originaTargetX:Number;        private var originaTargetY:Number;
      */
      //mouseDwon時的目標
      private var target:DisplayObject;
      private function onDown(e:MouseEvent):void
      {
         target = e.currentTarget as DisplayObject;
         originaMouseX = e.stageX;
         originaMouseY = e.stageY;
         /*計算方式二,需要紀錄被拖曳元件原始未置
         //originaTargetX = target.x;
         //originaTargetY = target.y;
         */
         addMouseUpEL(this);
         addMouseMoveEL(this);
       }
       private var offsetX:Number;
       private var offsetY:Number;
       private function onMove(e:MouseEvent):void
       {
         offsetX = e.stageX - originaMouseX;
         //↓方式一的計算,每次更新新的值,計算完offset之後,將originaMouseX與Y更新。
         originaMouseX = e.stageX;
        
         offsetY = e.stageY - originaMouseY;         //↓方式一
         originaMouseY = e.stageY;


         //方式一
         target.x += offsetX;
         target.y += offsetY;
         //計算方式二
         //target.x = originaTargetX + offsetX;
         //target.y = originaTargetY + offsetY;
       }
       private function onUp(e:MouseEvent):void
       {
         delMouoseMoveEL(this);
         delMouseUpEL(this);
       }
       //偵聽代理method
       private function addMouseDownEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
       }
       private function delMouseDownEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.removeEventListener(MouseEvent.MOUSE_DOWN , onDown);
       }
       private function addMouseMoveEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.addEventListener(MouseEvent.MOUSE_MOVE , onMove);
       }
       private function delMouoseMoveEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.removeEventListener(MouseEvent.MOUSE_MOVE , onMove);
       }
       private function addMouseUpEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.addEventListener(MouseEvent.MOUSE_UP , onUp);
       }
       private function delMouseUpEL(obj:IEventDispatcher):void
       {
         if(!obj)return;
         obj.removeEventListener(MouseEvent.MOUSE_UP , onUp);
       }
      ]]>
      </fx:Script>
<s:Group id="dragTargetA" width="100" height="100">
    <s:layout>
      <s:BasicLayout/>
    </s:layout>
    <s:Rect width="100%" height="100%">
      <s:fill>
        <s:SolidColor color="#CCCCCC"/>
      </s:fill>
   </s:Rect>
</s:Group>
<s:Group id="dragTargetB" width="100" height="100">
  <s:layout>
    <s:BasicLayout/>
   </s:layout>
   <s:Rect width="100%" height="100%">
     <s:fill>
       <s:SolidColor color="#999999"/>
     </s:fill>
   </s:Rect>
</s:Group>
</s:Application>




基礎原理了解後就可以寫自己的drag drop Management,以便在於開始拖,開始放播放swf動畫等,可以將拖曳動作做得更細膩。

沒有留言:

張貼留言