Ribbons: forked from: 鯉のぼり
forked from: 光るリボン(Ribbon Light)
/**
* Copyright QuercusFlorida ( http://wonderfl.net/user/QuercusFlorida )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/cT72
*/
// forked from aebf's LASSO forked from: 鯉のぼり
// forked from Akiyah's 鯉のぼり
// forked from codefl's with wind and gravity ff: IK Fiber
// forked from whirlpower's IK Fiber
// forked from: 光るリボン(Ribbon Light)
package {
import flash.events.*;
import flash.display.*;
import flash.net.*;
import flash.system.*;
import flash.filters.BlurFilter;
import flash.geom.*;
[SWF(backgroundColor="0x000000",frameRate=60)]
public class FlashTest extends Sprite {
private var _sketch:CurveSketch;
private var bmd:BitmapData;
private var _bmd:BitmapData;
private var _bm:Bitmap;
private var _container:Sprite = new Sprite();
private var loader:Loader = new Loader();
Security.loadPolicyFile("http://assets.wonderfl.net/crossdomain.xml");
public function FlashTest() {
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadDone);
loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/3/3d/3d30/3d30196c1a61f9296bb7dfcc5d330ea4a2570e79"));
}
private function loadDone(e:Event):void {
bmd = new BitmapData(loader.width,loader.height,true,0x000000);
bmd.draw(loader);
// write as3 code here..
addChild(_container);
graphics.beginFill(0)
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight)
graphics.endFill()
//
_sketch = new CurveSketch();
_bmd = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0);
_container.addChild(_sketch);
_container.addChild(_bm = new Bitmap(_bmd) as Bitmap);
_bm.blendMode = "add";
//
addEventListener(Event.ENTER_FRAME, update);
stage.addChild( new TailLine(bmd) );
}
private function update(e:Event):void{
_bmd.draw(_sketch, null, null, "add");
_bmd.applyFilter(_bmd, _bmd.rect, new Point(), new BlurFilter(8, 8, 3));
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
internal class TailLine extends Bitmap
{
private var lines :Array;
private var bmd:BitmapData;
public function TailLine(bmd:BitmapData):void
{
this.bmd = bmd;
addEventListener( Event.ADDED_TO_STAGE, init );
}
private function init( e:Event ):void
{
removeEventListener( Event.ADDED_TO_STAGE, init );
bitmapData = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0x00000000 );
lines = [];
for (var i:int = 0; i < 2; i++)
{
var radius :Number = 20;
var radian :Number = -i * Math.PI*2 / 8;
var line:IKline = new IKline(60, 20);
line.x = Math.sin( radian ) * radius / 3;
line.y = Math.cos( radian ) * radius;
line.gravity = 0;
line.friction = Math.random() * 0.05 + 0.7;
line.color = 0x123456//0x334422;
lines.push( line );
}
addEventListener( Event.ENTER_FRAME, loop );
}
private var g:Number = 5, tg:Number = 5;
private var wd:Number = 0, twd:Number = 10;
private function loop( evt:Event ):void
{
var _x :Number = stage.mouseX;
var _y :Number = stage.mouseY;
bitmapData.lock();
bitmapData.fillRect( bitmapData.rect, 0x00 );
if(Math.random() < 0.1) tg = Math.random()*9.8;
if(Math.random() < 0.1) twd = Math.random()*10;
g += 0.1 * (tg - g)
wd += 0.1 * (twd - wd);
for each(var line:IKline in lines )
{
line.gravity = g;
line.wind = 0;
line.nextFrame( _x, _y );
}
bitmapData.draw( drawMouth(lines));
var i:Number = 0;
for each(line in lines )
{
var line2:IKline = lines[(i + 1) % lines.length];
bitmapData.draw( drawLine(i, line, line2));
i++;
}
bitmapData.unlock();
}
private function drawMouth(lines:Array):Shape
{
var shape :Shape = new Shape();
var g :Graphics = shape.graphics;
//g.lineStyle(3, 0x808080);
var i:Number = lines.length - 1;
var line:IKline = lines[i];
g.beginFill(0x808080);
g.moveTo( line.x + line.segments[0].x, line.y + line.segments[0].y );
for ( i = 0; i < lines.length; i++ )
{
line = lines[i];
g.lineTo( line.x + line.segments[0].x, line.y + line.segments[0].y );
}
g.endFill();
return shape;
}
private function drawLine(j:Number, line:IKline, line2:IKline):Shape
{
var segments:Array = line.segments;
var segments2:Array = line2.segments;
var leng :int = segments.length;
var shape :Shape = new Shape();
var g :Graphics = shape.graphics;
//g.lineStyle(1, 0xff0000);
for ( var i :int = 0; i < leng-1; i++ )
{
drawSquare(g, bmd, new Point(280 / 8 * i, 280 / 8 * j), 280 / 8,
new Point(line.x + segments[i].x, line.y + segments[i].y),
new Point(line.x + segments[i+1].x, line.y + segments[i+1].y),
new Point(line2.x + segments2[i].x, line2.y + segments2[i].y),
new Point(line2.x + segments2[i+1].x, line2.y + segments2[i+1].y));
}
return shape;
}
private function drawSquare(g:Graphics, bmd:BitmapData, start:Point, len:Number,
p0:Point, p1:Point, p2:Point, p3:Point):void{
var a:Triangle;
var b:Triangle;
a = new Triangle(start,
start.add(new Point(len, 0)),
start.add(new Point(0, len)));
b = new Triangle(p0, p1, p2);
drawTriangle(g, bmd, Triangle.transformMatrix(a, b), b);
a = new Triangle(start.add(new Point(len, 0)),
start.add(new Point(len, len)),
start.add(new Point(0, len)));
b = new Triangle(p1, p3, p2);
drawTriangle(g, bmd, Triangle.transformMatrix(a, b), b);
}
private function drawTriangle(g:Graphics, bmd:BitmapData,
m:Matrix, b:Triangle):void{
if(b.order()) {
g.beginBitmapFill(bmd, m);
g.moveTo(b.p0.x, b.p0.y);
g.lineTo(b.p1.x, b.p1.y);
g.lineTo(b.p2.x, b.p2.y);
g.lineTo(b.p0.x, b.p0.y);
g.endFill();
}
}
}
internal class IKline
{
public var segments /*Segment*/:Array = [];
public var x :Number = 0;
public var y :Number = 0;
public var segmentLeng :int = 5;
public var segmentNum :int = 8;
public var wind:Number = 0
public var gravity :Number = 0;
public var friction :Number = 1;
public var color :uint = 0x888888;
public function IKline(len:int, num:int):void
{
segmentLeng = len
segmentNum = num
var segment:Segment = new Segment( 0 * i );
segments.push( segment );
for (var i:int = 1; i < segmentNum; i++)
{
segment = new Segment( segmentLeng-0.5 * i );
segments.push( segment );
}
}
public function nextFrame( _x:int, _y:int ):void
{
drag( segments[0], _x, _y );
for ( var i:int = 1; i < segmentNum; i++ )
{
var segmentA:Segment = segments[i];
var segmentB:Segment = segments[i - 1];
drag( segmentA, segmentB.x, segmentB.y );
}
}
private function drag( segment:Segment, xpos:Number, ypos:Number ):void
{
segment.next();
var dx :Number = xpos - segment.x;
var dy :Number = ypos - segment.y;
var radian :Number = Math.atan2( dy, dx );
segment.rotation = radian * 180 / Math.PI;
var pin :Point = segment.getPin();
var w :Number = pin.x - segment.x;
var h :Number = pin.y - segment.y;
segment.x = xpos - w;
segment.y = ypos - h;
segment.setVector();
segment.vx *= friction;
segment.vy *= friction;
segment.vx += wind
segment.vy += gravity;
}
}
internal class Segment extends Sprite
{
private var segmentLeng :Number;
public var vx :Number = 0;
public var vy :Number = 0;
private var prevX :Number = 0;
private var prevY :Number = 0;
public function Segment( segmentLeng:Number ):void
{
this.segmentLeng = segmentLeng;
}
public function next():void
{
x += vx;
y += vy;
}
public function setVector():void
{
if( prevX ) vx = x - prevX;
if( prevY ) vy = y - prevY;
prevX = x;
prevY = y;
}
public function getPin():Point
{
var angle :Number = rotation * Math.PI / 180;
var xpos :Number = x + Math.cos( angle ) * segmentLeng;
var ypos :Number = y + Math.sin( angle ) * segmentLeng;
return new Point( xpos, ypos );
}
}
class Triangle {
public var p0:Point;
public var p1:Point;
public var p2:Point;
function Triangle(p0:Point, p1:Point, p2:Point) {
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
}
public function matrix():Matrix {
return new Matrix(
p1.x - p0.x, p1.y - p0.y,
p2.x - p0.x, p2.y - p0.y);
}
public function order():Boolean {
return (p2.x - p0.x) * (p2.y - p1.y) - (p2.y - p0.y) * (p2.x - p1.x) >= 0 ;
}
public static function transformMatrix(a:Triangle, b:Triangle):Matrix {
var ma : Matrix = a.matrix();
ma.invert();
var mb : Matrix = b.matrix();
var m : Matrix = new Matrix();
m.translate(-a.p0.x, -a.p0.y);
m.concat(ma);
m.concat(mb);
m.translate(b.p0.x, b.p0.y);
return m;
}
}
//package {
import frocessing.display.F5MovieClip2D;
import frocessing.geom.FGradientMatrix;
import frocessing.color.ColorHSV
class CurveSketch extends F5MovieClip2D
{
//加速度運動の変数
//位置
private var xx:Number;
private var yy:Number;
//速度
private var vx:Number;
private var vy:Number;
//加速度の係数
private var ac:Number;
//速度の減衰係数
private var de:Number;
//描画座標
private var px0:Array;
private var py0:Array;
private var px1:Array;
private var py1:Array;
private var t:Number = 0
//描画グループ
private var shapes:Array;
public function CurveSketch()
{
//初期化
vx = vy = 0.0;
xx = mouseX;
yy = mouseY;
ac = 0.06;
de = 0.9;
px0 = [xx, xx, xx, xx];
py0 = [yy, yy, yy, yy];
px1 = [xx, xx, xx, xx];
py1 = [yy, yy, yy, yy];
shapes = [];
//線と塗りの色指定
noStroke();
}
public function draw():void
{
//加速度運動
xx += vx += ( mouseX - xx ) * ac;
yy += vy += ( mouseY - yy ) * ac;
var len:Number = mag( vx, vy );
//新しい描画座標
var x0:Number = xx + 1 + len * 0.1;
var y0:Number = yy - 1 - len * 0.1;
var x1:Number = xx - 1 - len * 0.1;
var y1:Number = yy + 1 + len * 0.1;
//描画座標
px0.shift(); px0.push( x0 );
py0.shift(); py0.push( y0 );
px1.shift(); px1.push( x1 );
py1.shift(); py1.push( y1 );
var _px0:Array = [px0[0], px0[1], px0[2], px0[3]];
var _py0:Array = [py0[0], py0[1], py0[2], py0[3]];
var _px1:Array = [px1[0], px1[1], px1[2], px1[3]];
var _py1:Array = [py1[0], py1[1], py1[2], py1[3]];
shapes.push( { px0:_px0, py0:_py0, px1:_px1, py1:_py1, mtx:null} );
if (shapes.length >= 50) shapes.shift();
var shapesLength:int = shapes.length;
for (var i:int = shapesLength-1; i >= 0; i--)
{
var sh:Object = shapes[i];
var color:ColorHSV = new ColorHSV(t, 0.8, 1, 0.1)
t += 0.05;
beginFill(int(color), 0.2)
beginShape();
curveVertex( sh.px0[0], sh.py0[0] );
curveVertex( sh.px0[1], sh.py0[1] );
curveVertex( sh.px0[2], sh.py0[2] );
curveVertex( sh.px0[3], sh.py0[3] );
vertex( sh.px1[2], sh.py1[2] );
curveVertex( sh.px1[3], sh.py1[3] );
curveVertex( sh.px1[2], sh.py1[2] );
curveVertex( sh.px1[1], sh.py1[1] );
curveVertex( sh.px1[0], sh.py1[0] );
endShape();
}
//減衰処理
vx *= de;
vy *= de;
}
}
//}