as3 图片透明区域不接受鼠标事件的工具类

转自 http://blog.sina.com.cn/s/blog_6919c12201019o44.html

一牛人写的工具类,使透明图片转化为原件,原件继承了该类,就能使透明区域不接受鼠标事件,


package com.mosesSupposes.bitmap {
 import flash.display.Bitmap;
 import flash.display.BitmapData;
 import flash.display.MovieClip;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.geom.Matrix;
 import flash.geom.Point;
 import flash.geom.Rectangle; 
 
 
 public class InteractivePNG extends MovieClip {
  
  // -== Public Properties ==-
  
  
  public function get interactivePngActive() : Boolean {
   return _interactivePngActive;
  }
  
  
  public function get alphaTolerance() : uint {
   return _threshold;
  }
  public function set alphaTolerance(value : uint) : void {
   _threshold = Math.min(255, value);
  }
  
  // Excluded from documentation for simplicity, a note is provided under disableInteractivePNG.
  
  override public function set hitArea(value : Sprite) : void {
   if (value!=null && super.hitArea==null) {
    disableInteractivePNG();
   }
   else if (value==null && super.hitArea!=null) {
    enableInteractivePNG();
   }
   super.hitArea = value;
  }
  
  // Excluded from documentation for simplicity, a note is provided under disableInteractivePNG.
  
  override public function set mouseEnabled(enabled : Boolean) : void {
   if (isNaN(_buttonModeCache)==false) { // indicates that mouse has entered clip bounds.
    disableInteractivePNG();
   }
   super.mouseEnabled = enabled;
  }
  
  // -== Private Properties ==-
  
  
  protected var _threshold : uint = 128;
  
  protected var _transparentMode : Boolean = false;
  
  protected var _interactivePngActive : Boolean = false;
  
  protected var _bitmapHit : Boolean = false;
  
  protected var _basePoint : Point;
  
  protected var _mousePoint : Point;
  
  protected var _bitmapForHitDetection : Bitmap;
  
  protected var _buttonModeCache : Number = NaN;
  
  // -== Public Methods ==-
  
  
  public function InteractivePNG():void {
   super();
   _basePoint = new Point();
   _mousePoint = new Point();
   enableInteractivePNG();
  }
  
  
  public function drawBitmapHitArea(event:Event=null) : void
  {
   var isRedraw:Boolean = (_bitmapForHitDetection!=null);
   if (isRedraw) {
    try { removeChild(_bitmapForHitDetection); }catch(e:Error) { }
   }
   var bounds:Rectangle = getBounds(this);
   var left:Number = bounds.left;
   var top:Number = bounds.top;
   var b:BitmapData = new BitmapData(bounds.width, bounds.height, true, 0);
   _bitmapForHitDetection = new Bitmap(b);
   _bitmapForHitDetection.name = "interactivePngHitMap"; // (So that it is not a mystery if the displaylist is being inspected!)
   _bitmapForHitDetection.visible = false;
   var mx:Matrix = new Matrix();
   mx.translate(-left, -top);
   b.draw(this, mx);
   addChildAt(_bitmapForHitDetection, 0);
   _bitmapForHitDetection.x = left;
   _bitmapForHitDetection.y = top;
  }
  
  
  public function disableInteractivePNG(): void {
   deactivateMouseTrap();
   removeEventListener(Event.ENTER_FRAME, trackMouseWhileInBounds);
   try { removeChild(_bitmapForHitDetection); }catch(e:Error) { }
   _bitmapForHitDetection==null;
   super.mouseEnabled = true;
   _transparentMode = false;
   setButtonModeCache(true);
   _bitmapHit = false;
   _interactivePngActive = false;
  }
  
  
  public function enableInteractivePNG(): void {
   disableInteractivePNG();
   if (hitArea!=null)
    return;
   activateMouseTrap();
   _interactivePngActive = true;
  }
   
  // -== Private Methods ==-
  
  
  protected function activateMouseTrap() : void {
   addEventListener(MouseEvent.ROLL_OVER, captureMouseEvent, false, 10000, true); //useCapture=true, priority=high, weakRef=true
   addEventListener(MouseEvent.MOUSE_OVER, captureMouseEvent, false, 10000, true);
   addEventListener(MouseEvent.ROLL_OUT, captureMouseEvent, false, 10000, true); 
   addEventListener(MouseEvent.MOUSE_OUT, captureMouseEvent, false, 10000, true);
   addEventListener(MouseEvent.MOUSE_MOVE, captureMouseEvent, false, 10000, true);
  }
  
  
  protected function deactivateMouseTrap() : void {
   removeEventListener(MouseEvent.ROLL_OVER, captureMouseEvent);
   removeEventListener(MouseEvent.MOUSE_OVER, captureMouseEvent);
   removeEventListener(MouseEvent.ROLL_OUT, captureMouseEvent); 
   removeEventListener(MouseEvent.MOUSE_OUT, captureMouseEvent);
   removeEventListener(MouseEvent.MOUSE_MOVE, captureMouseEvent);
  }
  
  
  protected function captureMouseEvent(event : Event) : void
  {
   if (!_transparentMode) {
    if (event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.ROLL_OVER) {
     // The buttonMode state is cached then disabled to avoid a cursor flicker
     // at the movieclip bounds. Reenabled when bitmap is hit.
     setButtonModeCache();
     _transparentMode = true;
     super.mouseEnabled = false;
     addEventListener(Event.ENTER_FRAME, trackMouseWhileInBounds, false, 10000, true); // activates bitmap hit & exit tracking
     trackMouseWhileInBounds(); // important: Immediate response, and sets _bitmapHit to correct state for event suppression.
    }
   }
   
   if (!_bitmapHit)
    event.stopImmediatePropagation();
  }
  
  
  protected function trackMouseWhileInBounds(event:Event=null):void
  {
   if (bitmapHitTest() != _bitmapHit)
   {
    _bitmapHit = !_bitmapHit;
    
    // Mouse is now on a nonclear pixel based on alphaTolerance. Reenable mouse events.
    if (_bitmapHit) {
     deactivateMouseTrap();
     setButtonModeCache(true, true);
     _transparentMode = false;
     super.mouseEnabled = true; // This will trigger rollOver & mouseOver events
    }
    
    // Mouse is now on a clear pixel based on alphaTolerance. Disable mouse events but .
    else if (!_bitmapHit) {
     _transparentMode = true;
     super.mouseEnabled = false; // This will trigger rollOut & mouseOut events
    }
   }
   
   // When mouse exits this MovieClip's bounds, end tracking & restore all.
   var localMouse:Point = _bitmapForHitDetection.localToGlobal(_mousePoint);
   if (hitTestPoint( localMouse.x, localMouse.y)==false) {
    removeEventListener(Event.ENTER_FRAME, trackMouseWhileInBounds);
    _transparentMode = false;
    setButtonModeCache(true);
    super.mouseEnabled = true;
    activateMouseTrap();
   }
  }
  
  
  protected function bitmapHitTest():Boolean {
   if (_bitmapForHitDetection==null)
    drawBitmapHitArea();
   _mousePoint.x = _bitmapForHitDetection.mouseX;
   _mousePoint.y = _bitmapForHitDetection.mouseY;
   return _bitmapForHitDetection.bitmapData.hitTest(_basePoint, _threshold, _mousePoint);
  }
  
  
  protected function setButtonModeCache(restore:Boolean=false, retain:Boolean=false) : void {
   if (restore) {
    if (_buttonModeCache==1)
     buttonMode = true;
    if (!retain)
     _buttonModeCache = NaN;
    return;
   }
   _buttonModeCache = (buttonMode==true ? 1 : 0);
   buttonMode = false;
  }
 }
}

原文地址:https://www.cnblogs.com/lingLuoChengMi/p/9264534.html