2013-11-14 37 views
0

我知道對任何給定過濾器的數量進行動畫處理很簡單,但假設您在舞臺的特定區域(矩形)上有過濾器。 你將如何動畫(補間)這個過濾區域的位置,使效果在舞臺上移動?AS3-過濾區域的動畫位置(位圖數據)

+0

你有一些代碼示例嗎? – Fygo

回答

0

實現想到的效果的一種方法是將舞臺的內容繪製到BitmapData,然後使用BitmapData.applyFilter()。 applyFilter()讓你指定一個sourceRect和一個destPoint。所以在你的情況下,你可以動畫sourceRect的屬性。在這種情況下,destPoint的x和y應該與sourceRect的x和y相同。

這裏有一個工作示例:

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

    public class Main extends Sprite { 

     public function Main():void { 
      if (stage) init(); 
      else addEventListener(Event.ADDED_TO_STAGE, init); 
     } 

     private function init(e:Event = null):void { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 

      var bitmapData : BitmapData = new BitmapData(this.stage.stageWidth, this.stage.stageHeight); 
      var sourceRectVelocity : Point = new Point(3, 2); 
      var sourceRect : Rectangle = new Rectangle(50, 100, 200, 150); 
      var bitmap : Bitmap = new Bitmap(bitmapData); 

      // draw some random circles on the stage 
      for (var i:int = 0; i < 100; i++) { 
       this.graphics.beginFill((Math.floor(Math.random()*255) << 16) + (Math.floor(Math.random()*255) << 8) + Math.floor(Math.random()*255), 1); 
       this.graphics.drawCircle(Math.random()*this.stage.stageWidth, Math.random()*this.stage.stageHeight, 50 + Math.random()*50); 
      } 

      this.addChild(bitmap); 

      this.addEventListener(Event.ENTER_FRAME, function(event : Event):void { 
       sourceRect.x = Math.min(Math.max(sourceRect.x + sourceRectVelocity.x, 0), bitmapData.width - sourceRect.width); 
       sourceRect.y = Math.min(Math.max(sourceRect.y + sourceRectVelocity.y, 0), bitmapData.height - sourceRect.height); 

       if (sourceRect.right >= bitmapData.width) { 
        sourceRectVelocity.x = -Math.abs(sourceRectVelocity.x); 
       } else if (sourceRect.left <= 0) { 
        sourceRectVelocity.x = Math.abs(sourceRectVelocity.x); 
       } 

       if (sourceRect.bottom >= bitmapData.height) { 
        sourceRectVelocity.y = -Math.abs(sourceRectVelocity.y); 
       } else if (sourceRect.top <= 0) { 
        sourceRectVelocity.y = Math.abs(sourceRectVelocity.y); 
       } 

       // clear the bitmap with white (not needed if the stage doesn't have any transparency) 
       bitmapData.fillRect(bitmapData.rect, 0xffffff); 

       // draw the stage to the bitmapData, but make sure the Bitmap display object showing the BitmapData isn't visible 
       bitmap.visible = false; 
       bitmapData.draw(stage); 
       bitmap.visible = true; 

       // apply greyscale filter 
       bitmapData.applyFilter(bitmapData, sourceRect, new Point(sourceRect.x, sourceRect.y), new ColorMatrixFilter([0.3, 0.59, 0.11, 0, 0,0.3, 0.59, 0.11, 0, 0,0.3, 0.59, 0.11, 0, 0,0, 0, 0, 1, 0])); 
      }); 
     } 
    } 
} 

這個例子繪製整個階段爲BitmapData但後來只有過濾器應用到的區域。更優化的方法(特別是如果區域從不/很少更改大小)僅限於繪製要過濾到具有區域大小的BitmapData的區域,然後將過濾器應用於整個BitmapData。