萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 軟體知識 >  >> 影像處理 >> Flash 教學

Flash AS3 單滑鼠實現拖拽與旋轉:點擊位移判斷區分 Click 與 Drag

問題背景

需求:同一滑鼠左鍵同時實現**拖拽移動**與**點擊旋轉** MC。
常見方案:拖拽用 `MOUSE_DOWN/MOUSE_UP`,旋轉需 `SHIFT+CLICK`,體驗割裂。
嘗試合併:`MOUSE_DOWN+MOUSE_UP` 相當於 `CLICK`,導致每次釋放即旋轉,非預期。

核心洞察

**區分「點擊」與「拖拽」的本質差異:滑鼠位置是否發生位移。**
- 點擊:按下 → 釋放,`stageX/stageY` **無變化**。
- 拖拽:按下 → 移動 → 釋放,`stageX/stageY` **有變化**。

完整 AS3 實現代碼

package {
    import flash.display.*;
    import flash.geom.Point;
    import flash.events.*;

    public class Main extends Sprite {
        private var mc:MC;                 // 庫中連結類為 MC 的影片剪輯
        private var clickOffset:Point;     // 按下時滑鼠與 MC 相對偏移
        private var mouseLoc:Point;        // 按下時滑鼠舞台座標

        public function Main() {
            mc = new MC();
            addChild(mc);
            mc.x = 200;
            mc.y = 200;

            mc.addEventListener(MouseEvent.CLICK, rot);           // 點擊旋轉
            mc.addEventListener(MouseEvent.MOUSE_DOWN, startDrag); // 按下準備拖拽
            addEventListener(Event.ENTER_FRAME, doDrag);           // 幀循環拖拽
            stage.addEventListener(MouseEvent.MOUSE_UP, stopDrag); // 階段釋放
        }

        private function startDrag(e:MouseEvent):void {
            mouseLoc = new Point(e.stageX, e.stageY);             // 記錄按下位置
            clickOffset = new Point(e.stageX - mc.x, e.stageY - mc.y); // 計算偏移
        }

        private function doDrag(e:Event):void {
            if (clickOffset == null) return; // 未按下
            mc.x = mouseX - clickOffset.x;
            mc.y = mouseY - clickOffset.y;
        }

        private function stopDrag(e:MouseEvent):void {
            clickOffset = null; // 釋放標記
        }

        private function rot(e:MouseEvent):void {
            // 關鍵判斷:釋放位置 == 按下位置 才視為純點擊
            if (!mouseLoc.equals(new Point(e.stageX, e.stageY))) return;
            mc.rotation += 30; // 每次點擊旋轉 30°
        }
    }
}

邏輯流程圖解

  1. `MOUSE_DOWN`:記錄 `mouseLoc`(按下座標)與 `clickOffset`(相對偏移)。
  2. `ENTER_FRAME`:若 `clickOffset != null`,實時更新 MC 座標跟隨滑鼠(拖拽中)。
  3. `MOUSE_UP`:清空 `clickOffset`(結束拖拽)。
  4. `CLICK`:Flash 自動在 `MOUSE_UP` 後派發。判斷 `e.stageX/Y` 是否等於 `mouseLoc` → **相等 = 無位移 = 純點擊** → 執行旋轉;**不等 = 有位移 = 拖拽結束** → 忽略旋轉。

優勢總結

  • **零修飾鍵**:單滑鼠左鍵完成雙功能,符合直覺交互。
  • **零時間閾值**:不依賴 `setInterval` 計時,避免「長按多久算拖拽」的模糊界限。
  • **精確可靠**:基於幾何位移判斷,抗干擾性強。
  • **代碼極簡**:僅 50 行封裝完整邏輯,易維護、易擴展(如添加縮放、複製等手勢)。

擴展應用

  • 雙擊旋轉 90°:在 `rot` 中檢測 `e.clickCount == 2`。
  • 右鍵選單/中鍵平移:監聽 `MouseEvent.RIGHT_CLICK` / `MouseEvent.MIDDLE_CLICK`。
  • 觸屏適配:`TouchEvent.TOUCH_BEGIN/MOVE/END` 同理。

此模式已成為 Flash/AS3 交互基礎組件庫的標準實現,推薦收藏作為 UI 組件開發範本。

copyright © 萬盛學電腦網 all rights reserved