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

クリックされた位置が中心にくるようにオブジェクトを拡大縮小する

クリックされた位置を中心にオブジェクトを拡大縮小するテストです.

Tweener のショートカットに _matrix を追加する fladdict さんの
MatrixShortcuts クラスを利用させていただいています.

fladdict » Tweener拡張で、MovieClipをMatrixで超変形をできるようにした
http://fladdict.net/blog/2008/03/tweenermovieclipmatrix_1.html
Get Adobe Flash player
by schrift 25 May 2010
package
{
    import caurina.transitions.Tweener;
    import flash.display.DisplayObject;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.TextField;

    [SWF(backgroundColor="0x000000")]
    /**
     * クリックされた位置を中心にオブジェクトを拡大縮小するテストです.
     *
     * Tweener のショートカットに _matrix を追加する fladdict さんの
     * MatrixShortcuts クラスを利用させていただいています.
     *
     * fladdict » Tweener拡張で、MovieClipをMatrixで超変形をできるようにした
     * http://fladdict.net/blog/2008/03/tweenermovieclipmatrix_1.html
     */
    public class MatrixTest extends Sprite
    {
        /**
         * 
         */
        public function MatrixTest()
        {
            // ステージモードを設定します.
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            // Tweener を初期化します.
            Tweener.init();
            MatrixShortcuts.init();

            // 青
            blue = new DraggableSprite;
            g = blue.graphics;
            g.beginFill(0x0000FF);
            g.drawRect(0, 0, 100, 100);
            g.endFill();
            blue.x = 100;
            blue.y = 100;
            addChild(blue);
            blue.addEventListener(MouseEvent.MOUSE_UP, blue_onMouseUp);

            // 赤
            red = new DraggableSprite;
            g = red.graphics;
            g.beginFill(0xFF0000);
            g.drawRect(0, 0, 100, 100);
            g.endFill();
            red.x = 200;
            red.y = 200;
            addChild(red);
            red.addEventListener(MouseEvent.MOUSE_UP, red_onMouseUp);

            // 黄
            yellow = new DraggableSprite;
            g = yellow.graphics;
            g.beginFill(0xFFFF00);
            g.drawRect(0, 0, 100, 100);
            g.endFill();
            yellow.x = 300;
            yellow.y = 300;
            addChild(yellow);
            yellow.addEventListener(MouseEvent.MOUSE_UP, yellow_onMouseUp);
        }

        /** @private */
        private var blue:DraggableSprite;

        /** @private */
        private var g:Graphics;

        /** @private */
        private var red:DraggableSprite;

        /** @private */
        private var yellow:DraggableSprite;

        /**
         * オブジェクトの中心を基点として, 拡大/縮小します.
         */
        public function zoom(event:MouseEvent, toScale:Number):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                bounds:Rectangle = target.getBounds(stage),
                matrix:Matrix = new Matrix;

            // オブジェクトを拡大/縮小.
            matrix.scale(toScale, toScale);

            // オブジェクトを元あった位置に移動.
            matrix.translate(bounds.x, bounds.y);

            // オブジェクトの中心位置を拡大/縮小前と同一に調整.
            matrix.translate((bounds.width - (target.width / target.scaleX * toScale)) / 2, (bounds.height - target.height / target.scaleY * toScale) / 2);

            // トゥイーン実行
            Tweener.addTween(target, { time: 1.5, _matrix: matrix });
        }

        /**
         * マウスイベント発生時のカーソル位置がオブジェクトの中心に来るように, 拡大/縮小します.
         */
        public function zoomTo(event:MouseEvent, toScale:Number):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                bounds:Rectangle = target.getBounds(stage),
                matrix:Matrix = new Matrix;

            // オブジェクトを拡大/縮小.
            matrix.scale(toScale, toScale);

            // オブジェクトの位置をカーソル位置に移動.
            matrix.translate(event.stageX, event.stageY);

            // カーソル位置とオブジェクトの中心位置を揃える.
            matrix.translate(-(target.width / target.scaleX * toScale) / 2, -(target.height / target.scaleY * toScale) / 2);

            // トゥイーン実行
            Tweener.addTween(target, { time: 1.5, _matrix: matrix });
        }

        /**
         * マウスイベント発生時のカーソル位置を中心に, 拡大/縮小します.
         */
        public function zoomWith(event:MouseEvent, toScale:Number):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                bounds:Rectangle = target.getBounds(stage),
                matrix:Matrix = new Matrix;

            // オブジェクトを拡大/縮小.
            matrix.scale(toScale, toScale);

            // オブジェクトを元あった位置に移動.
            matrix.translate(bounds.x, bounds.y);

            // 縮尺を変えても, localX, localY が同一になるように調整.
            matrix.translate((event.localX * target.scaleX) - (event.localX * toScale), (event.localY * target.scaleY) - (event.localY * toScale));

            // トゥイーン実行
            Tweener.addTween(target, { time: 1.5, _matrix: matrix });
        }

        /** @private
         * 青四角.
         */
        private function blue_onMouseUp(event:MouseEvent):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                toScale:Number = target.scaleX > 1 ? 1 / target.scaleX : target.scaleX * 2;

            zoom(event, toScale);
        }

        /** @private
         * 赤四角.
         */
        private function red_onMouseUp(event:MouseEvent):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                toScale:Number = target.scaleX > 1 ? 1 / target.scaleX : target.scaleX * 2;

            zoomTo(event, toScale);
        }

        /** @private
         * 黄四角.
         */
        private function yellow_onMouseUp(event:MouseEvent):void
        {
            var target:DisplayObject = event.target as DisplayObject,
                toScale:Number = target.scaleX > 1 ? 1 / target.scaleX : target.scaleX * 2;

            zoomWith(event, toScale);
        }
    }
}

import caurina.transitions.Tweener;

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;

internal class DraggableSprite extends Sprite
{
    /**
     * ドラッグ可能な Sprite です.
     */
    public function DraggableSprite():void
    {
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
    }

	/** @private */
    private function onAddedToStage(event:Event):void
    {
        addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    }

	/** @private */
    private function onMouseDown(event:MouseEvent):void
    {
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    }

	/** @private */
    private function onMouseMove(event:MouseEvent):void
    {
		var target:DisplayObject = event.target as DisplayObject;
		
		// トゥイーン実行中の場合は, 停止します.
		if (Tweener.isTweening(target))
			Tweener.removeTweens(target);
		
		event.updateAfterEvent();
		
        startDrag();
    }

	/** @private */
    private function onMouseUp(event:MouseEvent):void
    {
        event.updateAfterEvent();
		
		stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);

        stopDrag();
    }

	/** @private */
    private function onRemovedFromStage(event:Event):void
    {
        removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

        if (stage.hasEventListener(MouseEvent.MOUSE_MOVE))
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);

        if (stage.hasEventListener(MouseEvent.MOUSE_UP))
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    }
}

/**
 * List of special matrix properties (normal and splitter properties) for the Tweener class.
 *
 * <p>When you call init() method. This class register following special properties to the Tweener.</p>
 *
 * <dl>
 * 	<dt>_matrix_a</dt><dd>Controls transform.matrix.a</dd>
 *  <dt>_matrix_b</dt><dd>Controls transform.matrix.b</dd>
 *  <dt>_matrix_c</dt><dd>Controls transform.matrix.c</dd>
 *  <dt>_matrix_d</dt><dd>Controls transform.matrix.d</dd>
 *  <dt>_matrix_tx</dt><dd>Controls transform.matrix.tx</dd>
 *  <dt>_matrix_ty</dt><dd>Controls transform.matrix.ty</dd>
 *  <dt>_matrix</dt><dd>Controls transform.matrix</dd>
 *  <dt>_global_matrix_a</dt><dd>Controls transform.matrix.a with Global Coordinate</dd>
 *  <dt>_global_matrix_b</dt><dd>Controls transform.matrix.b with Global Coordinate</dd>
 *  <dt>_global_matrix_c</dt><dd>Controls transform.matrix.c with Global Coordinate</dd>
 *  <dt>_global_matrix_d</dt><dd>Controls transform.matrix.d with Global Coordinate</dd>
 *  <dt>_global_matrix_tx</dt><dd>Controls transform.matrix.tx with Global Coordinate</dd>
 *  <dt>_global_matrix_ty</dt><dd>Controls transform.matrix.ty with Global Coordinate</dd>
 *  <dt>_global_matrix</dt><dd>Controls transform.matrix with Global Coordinate</dd>
 *  <dt>_global_x</dt><dd>Controls DisplayObject's x with Global Coordinate</dd>
 *  <dt>_global_y</dt><dd>Controls DisplayObject's y with Global Coordinate</dd>
 *  <dt>_global_rotation</dt><dd>Controls DisplayObject's rotation with Global Coordinate</dd>
 *  <dt>_global_scaleX</dt><dd>Controls DisplayObject's scaleX with Global Coordinate</dd>
 *  <dt>_global_scaleY</dt><dd>Controls DisplayObject's scaleY with Global Coordinate</dd>
 *  <dt>_global_scale</dt><dd>Controls DisplayObject's both scaleX and scaleY with Global Coordinate</dd>
 * </dl>
 *
 * @example following code move DisplayObject to global coordinate (100,100).
 * <listing version="3.0">MatrixShortcuts.init();
 * Tweener.addTween(myDisplayObject,{time:1, _global_x:100, _global_y:100});</listing>
 *
 * @author		Takayuki Fukatsu, fladdict.net
 * @version		1.0.0
 */
internal class MatrixShortcuts
{
    /**
     * Initialization method.
     * This method register some special properties to the Tweener.
     */
    public static function init():void
    {
        Tweener.registerSpecialProperty("_matrix_a", _matrix_prop_get, _matrix_prop_set, [ "a" ]);
        Tweener.registerSpecialProperty("_matrix_b", _matrix_prop_get, _matrix_prop_set, [ "b" ]);
        Tweener.registerSpecialProperty("_matrix_c", _matrix_prop_get, _matrix_prop_set, [ "c" ]);
        Tweener.registerSpecialProperty("_matrix_d", _matrix_prop_get, _matrix_prop_set, [ "d" ]);
        Tweener.registerSpecialProperty("_matrix_tx", _matrix_prop_get, _matrix_prop_set, [ "tx" ]);
        Tweener.registerSpecialProperty("_matrix_ty", _matrix_prop_get, _matrix_prop_set, [ "ty" ]);
        Tweener.registerSpecialPropertySplitter("_matrix", _matrix_splitter);

        Tweener.registerSpecialProperty("_global_matrix_a", _global_matrix_prop_get, _global_matrix_prop_set, [ "a" ]);
        Tweener.registerSpecialProperty("_global_matrix_b", _global_matrix_prop_get, _global_matrix_prop_set, [ "b" ]);
        Tweener.registerSpecialProperty("_global_matrix_c", _global_matrix_prop_get, _global_matrix_prop_set, [ "c" ]);
        Tweener.registerSpecialProperty("_global_matrix_d", _global_matrix_prop_get, _global_matrix_prop_set, [ "d" ]);
        Tweener.registerSpecialProperty("_global_matrix_tx", _global_matrix_prop_get, _global_matrix_prop_set, [ "tx" ]);
        Tweener.registerSpecialProperty("_global_matrix_ty", _global_matrix_prop_get, _global_matrix_prop_set, [ "ty" ]);
        Tweener.registerSpecialPropertySplitter("_global_matrix", _global_matrix_splitter);

        Tweener.registerSpecialProperty("_global_x", _global_xy_prop_get, _global_xy_prop_set, [ "x" ]);
        Tweener.registerSpecialProperty("_global_y", _global_xy_prop_get, _global_xy_prop_set, [ "y" ]);
        Tweener.registerSpecialProperty("_global_rotation", _global_rotation_prop_get, _global_rotation_prop_set);
        Tweener.registerSpecialProperty("_global_scaleX", _global_scale_prop_get, _global_scale_prop_set, [ "scaleX" ]);
        Tweener.registerSpecialProperty("_global_scaleY", _global_scale_prop_get, _global_scale_prop_set, [ "scaleY" ]);
        Tweener.registerSpecialPropertySplitter("_global_scale", _global_scale_splitter);
    }

    /*
       -----------------------------------------------------------------------------------------
       Global Coordinate Matrix Control Getter / Setter / Splitter
       -----------------------------------------------------------------------------------------
     */

    /**
     * 
     * @param p_obj
     * @param p_parameters
     * @param p_extra
     * @return 
     */
    protected static function _global_matrix_prop_get(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        return p_obj.transform.concatenatedMatrix[p_parameters[0]]
    }

    /**
     * 
     * @param p_obj
     * @param p_value
     * @param p_parameters
     * @param p_extra
     */
    protected static function _global_matrix_prop_set(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        var cmat:Matrix = p_obj.transform.concatenatedMatrix,
            pcmat:Matrix = p_obj.parent.transform.concatenatedMatrix;

        pcmat.invert();

        cmat[p_parameters[0]] = p_value;
        cmat.concat(pcmat);

        p_obj.transform.matrix = cmat;
    }

    /**
     * 
     * @param p_value
     * @param p_parameters
     * @return 
     */
    protected static function _global_matrix_splitter(p_value:Object, p_parameters:Array):Array
    {
        var nArray:Array = new Array();

        if (p_value == null)
        {
            nArray.push({ name: "_global_matrix_a", value: 1 });
            nArray.push({ name: "_global_matrix_b", value: 0 });
            nArray.push({ name: "_global_matrix_c", value: 0 });
            nArray.push({ name: "_global_matrix_d", value: 1 });
            nArray.push({ name: "_global_matrix_tx", value: 0 });
            nArray.push({ name: "_global_matrix_ty", value: 0 });
        }
        else
        {
            nArray.push({ name: "_global_matrix_a", value: Matrix(p_value).a });
            nArray.push({ name: "_global_matrix_b", value: Matrix(p_value).b });
            nArray.push({ name: "_global_matrix_c", value: Matrix(p_value).c });
            nArray.push({ name: "_global_matrix_d", value: Matrix(p_value).d });
            nArray.push({ name: "_global_matrix_tx", value: Matrix(p_value).tx });
            nArray.push({ name: "_global_matrix_ty", value: Matrix(p_value).ty });
        }
        return nArray;
    }

    /**
     * 
     * @param p_obj
     * @param p_parameters
     * @param p_extra
     * @return 
     */
    protected static function _global_rotation_prop_get(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        var rot:Number = 0,
            dobj:DisplayObject = DisplayObject(p_obj);

        while (dobj)
        {
            rot += dobj.rotation;
            dobj = dobj.parent;
        }

        return rot;
    }

    /**
     * 
     * @param p_obj
     * @param p_value
     * @param p_parameters
     * @param p_extra
     */
    protected static function _global_rotation_prop_set(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        var rot:Number = p_value,
            dobj:DisplayObject = DisplayObject(p_obj).parent;

        while (dobj.parent)
        {
            rot -= dobj.rotation;
            dobj = dobj.parent;
        }

        dobj.rotation = rot;
    }

    /**
     * 
     * @param p_obj
     * @param p_parameters
     * @param p_extra
     * @return 
     */
    protected static function _global_scale_prop_get(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        var scl:Number = 0,
            dobj:Object = p_obj;

        while (dobj)
        {
            scl *= dobj[p_parameters[0]];
            dobj = dobj.parent;
        }

        return scl;
    }

    /**
     * 
     * @param p_obj
     * @param p_value
     * @param p_parameters
     * @param p_extra
     */
    protected static function _global_scale_prop_set(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        var scl:Number = p_value,
            dobj:DisplayObject = DisplayObject(p_obj).parent;

        while (dobj.parent)
        {
            scl /= dobj[p_parameters[0]];
            dobj = dobj.parent;
        }

        dobj[p_parameters[0]] = scl;
    }

    /**
     * 
     * @param p_value
     * @param p_parameters
     * @return 
     */
    protected static function _global_scale_splitter(p_value:Object, p_parameters:Array):Array
    {
        var nArray:Array = new Array();

        if (p_value == null)
        {
            nArray.push({ name: "_global_scaleX", value: 1 });
            nArray.push({ name: "_global_scaleY", value: 1 });
        }
        else
        {
            nArray.push({ name: "_global_scaleX", value: p_value });
            nArray.push({ name: "_global_scaleY", value: p_value });
        }

        return nArray;
    }

    /*
       -----------------------------------------------------------------------------------------
       Global Coordinate Control Getter / Setter / Splitter
       -----------------------------------------------------------------------------------------
     */

    /**
     * 
     * @param p_obj
     * @param p_parameters
     * @param p_extra
     * @return 
     */
    protected static function _global_xy_prop_get(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        var pt:Point = new Point(p_obj.x, p_obj.y);

        pt = DisplayObject(p_obj).parent.localToGlobal(pt);

        return pt[p_parameters[0]];
    }

    /**
     * 
     * @param p_obj
     * @param p_value
     * @param p_parameters
     * @param p_extra
     */
    protected static function _global_xy_prop_set(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        var dobj:DisplayObject = DisplayObject(p_obj),
            pt:Point = new Point(dobj.x, dobj.y);

        pt = dobj.parent.localToGlobal(pt);
        pt[p_parameters[0]] = p_value;
        pt = dobj.parent.globalToLocal(pt);

        dobj.x = pt.x;
        dobj.y = pt.y;
    }

    /*
       -----------------------------------------------------------------------------------------------------
       Normal Matrix Getter / Setter / Splitter
       -----------------------------------------------------------------------------------------------------
     */

    /**
     * 
     * @param p_obj
     * @param p_parameters
     * @param p_extra
     * @return 
     */
    protected static function _matrix_prop_get(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        return p_obj.transform.matrix[p_parameters[0]]
    }

    /**
     * 
     * @param p_obj
     * @param p_value
     * @param p_parameters
     * @param p_extra
     */
    protected static function _matrix_prop_set(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        var mat:Matrix = p_obj.transform.matrix;

        mat[p_parameters[0]] = p_value;

        p_obj.transform.matrix = mat;
    }

    /**
     * 
     * @param p_value
     * @param p_parameters
     * @return 
     */
    protected static function _matrix_splitter(p_value:Object, p_parameters:Array):Array
    {
        var arr:Array = new Array();

        if (p_value == null)
        {
            arr.push({ name: "_matrix_a", value: 1 });
            arr.push({ name: "_matrix_b", value: 0 });
            arr.push({ name: "_matrix_c", value: 0 });
            arr.push({ name: "_matrix_d", value: 1 });
            arr.push({ name: "_matrix_tx", value: 0 });
            arr.push({ name: "_matrix_ty", value: 0 });
        }
        else
        {
            arr.push({ name: "_matrix_a", value: Matrix(p_value).a });
            arr.push({ name: "_matrix_b", value: Matrix(p_value).b });
            arr.push({ name: "_matrix_c", value: Matrix(p_value).c });
            arr.push({ name: "_matrix_d", value: Matrix(p_value).d });
            arr.push({ name: "_matrix_tx", value: Matrix(p_value).tx });
            arr.push({ name: "_matrix_ty", value: Matrix(p_value).ty });
        }

        return arr;
    }
}