In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

【ボツ】Bitmapの回転の中心を画像の中心に

まれによく使うけどすぐどっか行っちゃうのでメモ.
Before: 奥(赤) After: 手前(青)

後になって検証してみたら全然使えなかった...
メモリの節約になってるのかどうかすら怪しいので, 素直にDisplayObjectContainerに入れた方が良い.
http://wonderfl.net/c/wnD1
Get Adobe Flash player
by matacat 06 Jan 2011
    Embed
/**
 * Copyright matacat ( http://wonderfl.net/user/matacat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2U94
 */

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.GlowFilter;
    
    [SWF(frameRate = 10)]
    
    public class Test extends Sprite
    {
        private var bmp:Bitmap;
        private var cfb:CenterFixedBitmap;
        
        public function Test()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.BOTTOM_RIGHT;
            
            var bd:BitmapData = new BitmapData(100, 100, false, 0xC0C0C0);
            
            graphics.beginFill(0x000000);
            graphics.moveTo(50, 0);
            graphics.lineTo(0, 50);
            graphics.lineTo(30, 50);
            graphics.lineTo(30, 100);
            graphics.lineTo(70, 100);
            graphics.lineTo(70, 50);
            graphics.lineTo(100, 50);
            graphics.lineTo(50, 0);
            graphics.drawCircle(50, 50, 2);
            bd.draw(this);
            graphics.clear();
            
            bmp = new Bitmap(bd);
            cfb = new CenterFixedBitmap(bd);
            bmp.filters = [new GlowFilter()];
            cfb.filters = [new GlowFilter(0x00FFFF)];
            addChild(bmp);
            addChild(cfb);
            
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onMouseMove(e:MouseEvent):void
        {
            bmp.x = e.stageX;
            bmp.y = e.stageY;
            cfb.x = e.stageX;
            cfb.y = e.stageY;
            e.updateAfterEvent();
        }
        
        private function onEnterFrame(e:Event):void
        {
            bmp.rotation += 1;
            cfb.rotation += 1;
        }
    }
}


import flash.display.Bitmap;
import flash.display.BitmapData;
//    import flash.display.PixelSnapping;

class CenterFixedBitmap extends Bitmap
{
    // 角度を度数法から弧度法に直すのに用いる係数.
    private const DEG2PI:Number = Math.PI / 180;
    
    // 回転の中心.
    // 表示の基準点でもある(オーバーライドしたx, yプロパティは, 常にビットマップの中心を指す).
    private var cx:Number = 0;
    private var cy:Number = 0;
    
    // 回転後スーパークラスの基準点を, 中心から見たときの相対座標.
    private var rx:Number = 0;
    private var ry:Number = 0;
    
    // スーパークラスの基準点の回転半径. 対角線の半分.
    private var radius:Number = 0;
    
    // 三角関数の位相のずれ. 対角線と水平線のなす角のうち大きいほう.
    private var phaseOffset:Number = 0;
    
    override public function get x():Number { return cx; }
    override public function set x(value:Number):void
    {
        cx = value;
        apply();
    }
    
    override public function get y():Number { return cy; }
    override public function set y(value:Number):void
    {
        cy = value;
        apply();
    }
    
    override public function set rotation(value:Number):void
    {
        super.rotation = value;
        rx = radius * Math.cos(value * DEG2PI + phaseOffset);
        ry = radius * Math.sin(value * DEG2PI + phaseOffset);
        apply();
    }
    
    override public function set bitmapData(value:BitmapData):void
    {
        super.bitmapData = value;
        init();
    }
    
    private function init():void
    {
        var w:int = bitmapData.width;
        var h:int = bitmapData.height;
        
        radius = Math.sqrt(w * w + h * h) / 2;
        phaseOffset = Math.atan2(h / -2, w / -2);
        rotation = rotation;
    }
    
    private function apply():void
    {
        super.x = cx + rx;
        super.y = cy + ry;
    }
    
    public function CenterFixedBitmap
    (
        bitmapData:BitmapData = null,
        // 本当は“PixelSnapping.AUTO”って書きたいけど, FD3だとコンパイラに「定数じゃねえ」っておこらりた...
        // wonderfl上では試してない
        pixelSnapping:String = "auto",
        smoothing:Boolean = false
    )
    {
        super(bitmapData, pixelSnapping, smoothing);
        if (bitmapData) init();
    }
}