
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; } }