forked from: Basic Transform
/**
* Copyright imajuk ( http://wonderfl.net/user/imajuk )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/yXev
*/
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;
}
}