Beautifl - Flash Gallery

Thumbnail : forked from: Basic Transform
forked from: Basic Transform
imajuk 2009-08-27 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package  
{
	import flash.filters.BlurFilter;
	import flash.display.PixelSnapping;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.display.BlendMode;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.events.Event;
	import flash.display.Sprite;

	[SWF(backgroundColor="#000000")]

	public class Main extends Sprite
	{
		private static const CENTER:Point = new Point(225, 220);
		private var time:Number = 0;
		private var point:Point = new Point();
		private var speed:Number = 6000;
		private var band:Number = 50;

		public function Main() 
		{
			stage.frameRate = 60;

			//キャンバス
			var canvas:BitmapData = new BitmapData(500, 400, false, 0);
			var fade:BitmapData = new BitmapData(500, 400, true, 0x04000000);
			var r:Rectangle = fade.rect;
			addChild(new Bitmap(canvas, PixelSnapping.AUTO, false));
			
			var rect:Rect = new Rect();
			rect.x = 150;
			rect.y = 150;
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, function(event:MouseEvent):void
			{
				speed = event.stageY / 400 * 4000 + 3000;
				band = event.stageX / 500 * 50;
			});
			
			addEventListener(Event.ENTER_FRAME, function():void
			{
				time += .01;
				
				var sin:Number = Math.sin(time);
				var cos:Number = Math.cos(time); 
				
				//トランスフォームの原点(Rectのローカル座標)
				var lOrigin:Point = new Point(cos * band + rect.half, sin * band + rect.half);
				var gOrigin:Point = rect.localToGlobal(lOrigin);
				
				//角の丸み
				rect.round = Math.abs(cos) * 100;
				
				//回転
				DisplayObjectUtil.rotate(rect, gOrigin, MathUtil.degreesToRadians(-time * speed));
				
				//拡大・縮小
				var scale:Number = Math.abs(sin) + .3;
				DisplayObjectUtil.scale(rect, gOrigin, scale, scale);
				
				//図形が画面定位置にとどまるように補正
				var diff:Point = CENTER.subtract(rect.localToGlobal(lOrigin));
				rect.x += diff.x;
				rect.y += diff.y;

				//キャンバスに描画
				canvas.lock();
				canvas.draw(rect, rect.transform.matrix, null, BlendMode.ADD);
				canvas.applyFilter(canvas, r, point, new BlurFilter(1.5, 1.5));
				canvas.copyPixels(fade, r, point);
				canvas.unlock();
			});
		}
	}
}

import flash.display.DisplayObjectContainer;
import flash.geom.Matrix;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.display.Graphics;
import flash.display.Sprite;

class Rect extends Sprite
{
	private var size:Number = 120;

	private var _round:Number = 4;

	public function set round(round:Number):void
	{
		_round = round;
		draw(getColor());
	}

	private var _half:Number = size * .5;

	public function get half():Number
	{
		return _half;
	}

	public function Rect() 
	{
		draw(getColor());
	}

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

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

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

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

	/**
	 * 対象となる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 p:DisplayObjectContainer = target.parent;
		var l:Point = (target.parent) ? p.globalToLocal(origin) : origin;
		var m:Matrix = target.transform.matrix;
		var x:Number = l.x;
		var y:Number = l.y;
		m.translate(-x, -y);
		m.scale(1 / target.scaleX, 1 / target.scaleY);
		m.scale(scaleX, scaleY);
		m.translate(x, y);
		target.transform.matrix = m;
        
		if (p)
                   revise(target, l, p.globalToLocal(origin));
	}

        /**
	 * Matrixによるトランスフォーム時の誤差補正
	 */
	private static function revise(target:DisplayObject, before:Point, after:Point):void
	{
		var diff:Point = before.subtract(after);
		target.x += diff.x;
		target.y += diff.y;
	}
}

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

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