/**
* Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/44fD
*/
package
{
/**
* インボリュート曲線
*
* さりげなくマスク処理に手間かけてます。
* 簡単にアルファ値を反転する方法か、
* アルファチャンネル以外で特定の部位にマスクをかける方法とかってないですかね?
*
* --- 参考 ---
*
* Wikipedia - インボリュート曲線
* http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%88%E6%9B%B2%E7%B7%9A
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ColorMatrixFilter;
import flash.geom.Matrix;
import flash.geom.Point;
[SWF(width=465,height=465,frameRate=60,backgroundColor=0xeeeeff)]
/**
* ...
* @author tkinjo
*/
public class Main extends Sprite
{
private const speed:Number = 5;
private const a:Number = 30;
private var canvas:Sprite;
private var canvasMask:Bitmap;
private var canvasMaskCanvas:Sprite;
private var draw:Boolean = true;
private var angle:Number = 0;
/**
* ラジアン角に対するインボリュート曲線の x 座標を返します。
*
* @param a
* @param radian
* @return
*/
private function involuteX( radian:Number, a:Number = 1 ):Number {
return a * ( Math.cos( radian) + radian * Math.sin( radian ) );
}
/**
* ラジアン角に対するインボリュート曲線の y 座標を返します。
*
* @param a
* @param radian
* @return
*/
private function involuteY( radian:Number, a:Number = 1 ):Number {
return a * ( Math.sin( radian ) - radian * Math.cos( radian) );
}
/**
* 以下演出処理
*/
/**
*
*/
public function Main()
{
canvas = new Sprite();
canvas.x = stage.stageWidth / 2;
canvas.y = stage.stageHeight / 2;
canvas.cacheAsBitmap = true;
canvas.scaleY = -1;
canvasMask = new Bitmap();
canvasMask.y = stage.stageHeight;
canvasMask.cacheAsBitmap = true;
canvasMask.scaleY = -1;
canvasMaskCanvas = new Sprite();
canvasMaskCanvas.cacheAsBitmap = true;
addEventListener( Event.ENTER_FRAME, drawEnterFrameHandler );
addChild( canvas );
addChild( canvasMask );
}
private function drawEnterFrameHandler( event:Event ):void {
var radian:Number = angleToRadian( angle );
if ( draw ) {
if ( angle == 0 ) {
canvas.graphics.lineStyle( 1 );
canvas.graphics.moveTo( 0, 0 );
}
canvas.graphics.lineTo( involuteX( radian, a ), involuteY( radian, a ) );
} else {
if ( angle == 0 ) {
canvasMaskCanvas.graphics.lineStyle( 3 );
canvasMaskCanvas.graphics.moveTo( 0, 0 );
canvas.mask = canvasMask;
}
canvasMaskCanvas.graphics.lineTo( involuteX( radian, a ), involuteY( radian, a ) );
var bitmapData:BitmapData = new BitmapData( stage.stageWidth, stage.stageHeight, true );
bitmapData.draw( canvasMaskCanvas, new Matrix( 1, 0, 0, 1, stage.stageWidth / 2, stage.stageHeight / 2 ) );
bitmapData = inversion( bitmapData );
bitmapData = brightnessToAlpha( bitmapData );
canvasMask.bitmapData = bitmapData;
}
angle += speed;
if ( 360 < angle ) {
if ( !draw ) {
canvas.graphics.clear();
canvas.mask = null;
canvasMask.bitmapData = null;
canvasMaskCanvas.graphics.clear();
}
angle = 0;
draw = !draw;
}
}
/**
*
* @param angle
* @return
*/
private function angleToRadian( angle:Number ):Number {
return angle * Math.PI / 180;
}
/**
* 反転
*
* @param bitmapData
* @return
*/
private function inversion( bitmapData:BitmapData ):BitmapData {
bitmapData.applyFilter( bitmapData, bitmapData.rect, new Point(), new ColorMatrixFilter( [
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
] ) );
return bitmapData;
}
/**
* 明度アルファ変換?
*
* @param bitmapData
* @return
*/
private function brightnessToAlpha( bitmapData:BitmapData ):BitmapData {
bitmapData.applyFilter( bitmapData, bitmapData.rect, new Point(), new ColorMatrixFilter( [
-1, 0, 0, 0, 0,
0, -1, 0, 0, 0,
0, 0, -1, 0, 0,
-0.33, -0.33, -0.33, 1, 0
] ) );
return bitmapData;
}
}
}