drawTrianglesであそぼ - スライドエフェクトサンプル - モーフィング1
/**
* Copyright HaraMakoto ( http://wonderfl.net/user/HaraMakoto )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7JUl
*/
package {
import __AS3__.vec.Vector;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.Security;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")]
public class DrawMorphing extends Sprite
{
private var counter:int = 0;
// private var distort1:DistortUnit = new DistortUnit("data/nuko_mini.jpg","TL");
// private var distort2:DistortUnit = new DistortUnit("data/fukuro_mini.jpg","MC");
private var distort1:DistortUnit = new DistortUnit("http://swimmingbird.heteml.jp/wonderfl/assets/drawtriangles/nuko_mini.jpg","TL");
private var distort2:DistortUnit = new DistortUnit("http://swimmingbird.heteml.jp/wonderfl/assets/drawtriangles/fukuro_mini.jpg","MC");
public function DrawMorphing() {
Security.loadPolicyFile("http://swimmingbird.heteml.jp/crossdomain.xml");
distort1.setNext( distort2 );
distort2.setNext( distort1 );
addChild( distort1 );
addChild( distort2 );
distort2.Distorter.alpha=0;
var btn:PushButton = new PushButton(this, 50,50,"slide", clickHandler);
}
private function clickHandler(event:MouseEvent):void {
if(counter%2==0) {
distort1.fadeOut();
distort2.fadeIn();
} else {
distort1.fadeIn();
distort2.fadeOut();
}
counter++;
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.display.Graphics;
import __AS3__.vec.Vector;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.core.easing.IEasing;
import org.libspark.betweenas3.core.easing.CubicEaseOut;
import org.libspark.betweenas3.easing.Cubic;
import org.libspark.betweenas3.easing.Quint;
class DistortUnit extends Sprite {
//頂点分割数
private var cutNum:int = 3;
//頂点ポイント配列
private var PtArray:Array;
private var loader:Loader = new Loader();
private var bmp:Bitmap;
//4点の配列
private var pList:Array = new Array();
//4点の描画レイヤー
private var pLayerList:Array = new Array();
//初期の座標
private var firstPosList:Array = new Array();
//Distorter
public var Distorter:Distort = new Distort();
private var _xMin:Number;
private var _yMin:Number;
private var _xMax:Number;
private var _yMax:Number;
private var _w:Number;
private var _h:Number;
private var _facePos:String = "MC";
private var _nextDistort:DistortUnit;
public function DistortUnit(_url:String, pos:String = "MC") {
addChild(Distorter);
_facePos = pos;
for(var i:int=0; i<4; i++) {
pLayerList.push(new Sprite());
addChild(pLayerList[i]);
}
loader.load(new URLRequest(_url));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComp);
}
public function setNext(d:DistortUnit):void {
_nextDistort = d;
}
private function setPoints():void
{
//Distort.pointNumCulc:分割数に対応した頂点数を返す
PtArray = new Array( Distort.pointNumCulc(cutNum) );
var i:int;
var len:int = PtArray.length;
//頂点座標設定
for(i=0; i<len; i++) {
//4隅を保存する
if(i==0||i==cutNum||i==len-1||i==len-1-cutNum) {
PtArray[i] = new handleTouchPoint();
pList.push(PtArray[i]);
} else {
PtArray[i] = new touchPoint();
}
addChild(PtArray[i]);
}
for(i=0; i<pList.length; i++) {
pList[i].drawLayer = pLayerList[i];
pList[i].build(0xFFFFFF);
}
}
private function loadComp(e:Event):void
{
bmp = Bitmap(loader.content);
_xMin = _yMin = 0;
_xMax = bmp.width;
_yMax = bmp.height;
this.x = 464/2 - _xMax/2;
this.y = 464/2 - _yMax/2;
//頂点設定
setPoints();
//ディストーションクラス設定
Distorter.setDistortion(cutNum, PtArray, bmp.bitmapData, _facePos);
Distorter.render();
addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}
private function handleEnterFrame(event:Event):void {
Distorter.render();
}
//--------------------------------------------------------------------------------//
// パブリック メソッド
//--------------------------------------------------------------------------------//
public function fadeOut():void {
var i:int = 0;
for each(var p:touchPoint in PtArray) {
BetweenAS3.delay(
BetweenAS3.tween(p,{x:_nextDistort.PtArray[i].baseX,y:_nextDistort.PtArray[i].baseY},null,1,Quint.easeOut),
0.0*i
).play();
i++;
}
BetweenAS3.tween(Distorter,{alpha:0},null,1,Quint.easeOut).play();
}
public function fadeIn():void {
var i:int = 0;
var p:touchPoint;
for each(p in PtArray) {
BetweenAS3.delay(
BetweenAS3.tween(p,{x:p.baseX,y:p.baseY},null,0.5,Quint.easeOut),
0.0*i
).play();
i++;
}
BetweenAS3.tween(Distorter,{alpha:1},null,1,Quint.easeOut).play();
}
}
class Distort extends Sprite {
//4×4分割のフィールド
private var fieldMC:Sprite = new Sprite();
private var cutNum:int; //頂点分割数
private var vertNum:int; //頂点数
private var slong:Number; //横縦幅
private var vlong:Number; //頂点
private var verticies:Vector.<Number>; //uvポイントMC
private var ptArray:Array; //vertポイント配列
private var vertPtArray:Array; //頂点番号
private var indicies:Vector.<int>; //テクスチャ
private var uvData:Vector.<Number>;
private var bmd:BitmapData;
public static var SSS:String = "SSS!";
private var _facePosition:String = "MC"; //top bottom
//コンストラクタ
public function Distort() {}
//頂点分割数と配列を得る
public function setDistortion(c:int, vtArray:Array, _bmd:BitmapData, pos:String="MC"):void
{
addChild(fieldMC);
bmd = _bmd;
_facePosition = pos;
slong = bmd.width;
vlong = bmd.height;
cutNum = c;
vertPtArray = vtArray;
setVertices();
}
//分割数に対応した頂点数を返す
public static function pointNumCulc(n:int):int {
var vnum:int = (n+1)*(n+1);
return vnum;
}
//頂点設定
public function setVertices():void
{
vertNum = (cutNum+1)*(cutNum+1);
ptArray = new Array(vertNum);
//ブロック単位
var bUnit:Number = 1 / cutNum;
var i:int; var t:int;
//頂点座標をPointに設定
for(i=0; i<cutNum+1; i++) {
for(t=0; t<cutNum+1; t++) {
ptArray[i*(cutNum+1)+t] = new Point(bUnit*t, bUnit*i);
vertPtArray[i*(cutNum+1)+t].setPt( bUnit*t*slong,bUnit*i*vlong );
//顔が上か、真ん中か、下かでかたよらせる
var coefX:Number=0;
var coefY:Number=0;
switch(_facePosition) {
case "TL":
coefX = -bUnit*0.5;
coefY = -bUnit*0.5;
break;
case "TR":
coefX = bUnit*0.5;
coefY = -bUnit*0.5;
break;
case "TC":
coefX = 0;
coefY = -bUnit*0.5;
break;
case "ML":
coefX = -bUnit*0.5;
coefY = 0;
break;
case "MR":
coefX = bUnit*0.5;
coefY = 0;
break;
case "MC":
coefX = 0;
coefY = 0;
break;
case "BR":
coefX = bUnit*0.5;
coefY = bUnit*0.5;
break;
case "BL":
coefX = -bUnit*0.5;
coefY = bUnit*0.5;
break;
case "BC":
coefX = 0;
coefY = bUnit*0.5;
break;
}
if(i!=0&&i!=cutNum&&t!=0&&t!=cutNum) {
ptArray[i*(cutNum+1)+t].x += coefX;
ptArray[i*(cutNum+1)+t].y += coefY;
vertPtArray[i*(cutNum+1)+t].setPt( (bUnit*t+coefX)*slong,(bUnit*i+coefY)*vlong );
}
}
}
//vertice
verticies = new Vector.<Number>(vertNum*2);
//uvts
uvData = new Vector.<Number>(vertNum*2);
//indicies
indicies = new Vector.<int>(cutNum*cutNum*6);
}
//テクスチャの反映
public function render():void {
var i:int; var t:int;
for(i=0; i<vertNum; i++) {
verticies[(i << 1) ] = vertPtArray[i].x;
verticies[(i << 1) + 1] = vertPtArray[i].y;
}
//uvts
for(i=0; i<vertNum; i++) {
uvData[(i << 1) ] = ptArray[i].x;
uvData[(i << 1) + 1] = ptArray[i].y;
}
//indicies
for(i=0; i<cutNum; i++) {
var iad:int = i*6;
for(t=0; t<cutNum; t++) {
var tad:int = t*6;
indicies[iad*(cutNum)+tad] = t+i*(cutNum+1);
indicies[iad*(cutNum)+tad+1] = t+1+i*(cutNum+1);
indicies[iad*(cutNum)+tad+2] = t+(i+1)*(cutNum+1);
indicies[iad*(cutNum)+tad+3] = t+1+i*(cutNum+1);
indicies[iad*(cutNum)+tad+4] = t+(i+1)*(cutNum+1);
indicies[iad*(cutNum)+tad+5] = t+1+(i+1)*(cutNum+1);
}
}
fieldMC.graphics.clear();
fieldMC.graphics.beginBitmapFill(bmd);
fieldMC.graphics.drawTriangles(verticies, indicies, uvData);
fieldMC.graphics.endFill();
}
}
//各頂点のポイント
class touchPoint extends Sprite {
public var baseX:Number;
public var baseY:Number;
public function touchPoint() {
this.buttonMode = true;
build();
this.addEventListener(MouseEvent.MOUSE_DOWN,downHandler);
this.addEventListener(MouseEvent.MOUSE_UP,upHandler);
}
public function setPt(_x:Number, _y:Number):void
{
this.x = _x;
this.y = _y;
baseX = _x;
baseY = _y;
}
protected function downHandler(e:MouseEvent):void
{
this.startDrag();
}
protected function upHandler(e:MouseEvent):void {
this.stopDrag();
}
public function build(col:Number=0xFF0000):void
{
// this.graphics.clear();
// this.graphics.beginFill(col);
// this.graphics.drawCircle(0,0,5);
// this.graphics.endFill();
}
}
class handleTouchPoint extends touchPoint {
public var ptList:Array = new Array();
private var ox:Number, oy:Number;
public var drawLayer:Sprite = new Sprite();
public function handleTouchPoint() {
}
//ドラッグ開始
protected override function downHandler(e:MouseEvent):void
{
ox = drawLayer.mouseX;
oy = drawLayer.mouseY;
drawLayer.graphics.clear();
drawLayer.graphics.moveTo(ox, oy);
this.startDrag();
this.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}
//ドラッグ終了
protected override function upHandler(e:MouseEvent):void {
this.stopDrag();
this.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
}
private function handleEnterFrame(event:Event):void {
var nx:Number = drawLayer.mouseX;
var ny:Number = drawLayer.mouseY;
drawLayer.graphics.lineStyle(1,0xFFFFFF);
//drawLayer.graphics.moveTo(nx, ny);
drawLayer.graphics.moveTo(halfNum(nx,ox), halfNum(ny,oy));
this.graphics.curveTo( nx, ny,halfNum(nx,ox), halfNum(ny,oy) );
//drawLayer.graphics.lineTo(ox, oy);
ox = nx;
oy = ny;
}
private function halfNum(a:Number, b:Number):Number {
return a+(b-a)/2;
}
}