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

Basic Transform

任意の点を中心に拡大、縮小、回転.
四角形をクリックするとトランスフォームの基準点を変更.
Get Adobe Flash player
by imajuk 09 Aug 2009
/**
 * Copyright imajuk ( http://wonderfl.net/user/imajuk )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1G3c
 */

package  
{
	import flash.geom.Point;
	import flash.events.Event;
	import flash.display.Sprite;

	/**
	 * 任意の点を中心に拡大、縮小、回転.
	 * 四角形をクリックするとトランスフォームの基準点を変更.
	 */
	[SWF(backgroundColor="#000000")]
	public class Main extends Sprite
	{
		private var value:Number = 0;

		public function Main() 
		{
			stage.frameRate = 60;
			
			var rect:Rect = addChild(new Rect()) as Rect;
			rect.translate(stage.width * .5, stage.height * .5);			
			addEventListener(Event.ENTER_FRAME, function():void
			{
				value += .01;
				var scale:Number = Math.sin(value);
				var center:Point = rect.center;
				//回転
				DisplayObjectUtil.rotate(rect, center, MathUtil.degreesToRadians(value * 1000));
				//拡大・縮小
				DisplayObjectUtil.scale(rect, center, scale, scale);
				/**
				 * 誤差補正 
				 * Matrixによるトランスフォームはどうしても100分の1ピクセル単位の誤差が出てしまうためここで補正.
				 * もっといい方法はないだろうか?
				 */
				rect.revisePosition();
			});
		}
	}
}

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

class Rect extends Sprite
{
	private var size:Number = 150;
	private var clickedLocal:Point = new Point(size * .5, size * .5);

	
	private var clickedGlobal:Point = center;

	public function get center():Point
	{
		return localToGlobal(clickedLocal);
	}

	private function getColor():Number
	{
		return Math.random() * 0xFFFFFF;
	}

	public function Rect() 
	{
		draw(getColor());
		
		addEventListener(MouseEvent.CLICK, clickHandler);
	}

	public function translate(tx:Number, ty:Number):void
	{
		x = tx;
		y = ty;
		clickedLocal.add(new Point(tx, ty));
		clickedGlobal = center;	
	}

	private function draw(color:Number):void
	{
		graphics.clear();
		drawShape(size, color);
		drawCenterPoint(clickedLocal, color);
	}

	private function drawShape(size:Number, color:uint):void
	{
		var g:Graphics = graphics;
		g.lineStyle(1, color);
		g.beginFill(color, .3);
		g.drawRoundRectComplex(0, 0, size, size, 4, 4, 4, 4);
		g.endFill();
	}

	private function drawCenterPoint(localPos:Point, color:uint):void
	{
		var markSize:int = 2;
		var lx:Number = localPos.x; 
		var ly:Number = localPos.y;
		var g:Graphics = graphics;
		g.lineStyle(1, color);
		g.moveTo(lx - markSize, ly - markSize);
		g.lineTo(lx + markSize, ly + markSize);
		g.moveTo(lx + markSize, ly - markSize);
		g.lineTo(lx - markSize, ly + markSize);
	}

	public function revisePosition():void
	{
		var p1:Point = clickedGlobal; 
		var p2:Point = center;
		var dx:Number = p1.x - p2.x; 
		var dy:Number = p1.y - p2.y; 
		x += dx; 
		y += dy;
	}

	private function clickHandler(event:MouseEvent):void
	{
		clickedLocal = new Point(event.localX, event.localY);
		clickedGlobal = new Point(event.stageX, event.stageY);
		draw(getColor());
	}
}

class DisplayObjectUtil
{
	/**
	 * 対象となるDisplayObjectを、任意の点を原点として回転させます.
	 * @param target    対象となるDisplayObject
	 * @param origin    回転の中心となるグローバル座標
	 * @param radians   新しい角度.これは絶対値です.
	 */
	public static function rotate(target:DisplayObject, origin:Point, radians:Number):void
	{
		var m:Matrix = target.transform.matrix;
		var x:Number = origin.x;
		var y:Number = origin.y;
		m.concat(new Matrix(1, 0, 0, 1, -x, -y));
		m.rotate(radians - MathUtil.degreesToRadians(target.rotation));
		m.concat(new Matrix(1, 0, 0, 1, x, y));
		target.transform.matrix = m;
	}

	/**
	 * 対象となるDisplayObjectを、任意の点を原点として拡大・縮小させます.
	 * @param target    対象となるDisplayObject
	 * @param origin    拡大・縮小の中心となるグローバル座標
	 * @param scaleX   新しいスケールX.これは絶対値です.
	 * @param scaleY   新しいスケールY.これは絶対値です.
	 */
	public static function scale(target:DisplayObject, origin:Point, scaleX:Number, scaleY:Number):void
	{
		var m:Matrix = target.transform.matrix;
		var x:Number = origin.x;
		var y:Number = origin.y;
		m.concat(new Matrix(1, 0, 0, 1, -x, -y));
		m.scale(1 / target.scaleX, 1 / target.scaleY);
		m.scale(scaleX, scaleY);
		m.concat(new Matrix(1, 0, 0, 1, x, y));
		target.transform.matrix = m;
	}
}

class MathUtil
{
	private static const PI:Number = Math.PI;

	/**
	 * 渡された任意の角度をラジアンに変換します.
	 * 
	 * @param degrees ラジアンに変換したい角度を渡します.
	 * @return 角度からラジアンに変換された値を返します.
	 */
	public static function degreesToRadians(degrees:Number):Number 
	{
		return degrees * PI / 180;
	}
}