forked from: LISA
/**
* Copyright Ogoshi ( http://wonderfl.net/user/Ogoshi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jUXb
*/
// forked from Murai's LISA
package {
import caurina.transitions.Equations;
import caurina.transitions.Tweener;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0x000000")]
public class LISA extends Sprite {
private var _container:Sprite;
private var _canvas:Sprite;
private var _bmdCurrent:BitmapData;
private var _stageW:Number = 465;
private var _stageH:Number = 465;
private var _w:Number;
private var _cP0:CirclePoint;
private var _cP1:CirclePoint;
private var _cP2:CirclePoint;
private var _cP3:CirclePoint;
private var _matrixArrayCurrent:Array;
private var _pointsArray:Array;
private var Pice:int = 15;
private var Reaction:uint = 100;
private var spring:Number = 0.75;
private var friction:Number = 0.85;
private const IMAGE_URL:String = "http://4.bp.blogspot.com/-Oj9i-hYRjx4/TZWKtpK_JYI/AAAAAAAADJI/ihwBjr52muY/s1600/EE+Rostos+%25289%2529%255B1%255D.JPG";
private var f:Fukidashi;
private var stg:Sprite;
private var sW:int;
private var sH:int;
public function LISA() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
sW = 465;
sH = 465;
addChild(stg = new Sprite());
removeEventListener(Event.ADDED_TO_STAGE, init);
var req:URLRequest = new URLRequest(IMAGE_URL);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
loader.load(req, new LoaderContext(true));
f = new Fukidashi(70, 250, 330, "");
f.cacheAsBitmap = true;
stg.addChild(f);
f.visible = false;
f.scaleX = 1;
f.scaleY = 1.2;
addEventListener(MouseEvent.MOUSE_OVER, click);
stage.addEventListener(Event.RESIZE, resize);
resize();
}
private function resize(e:Event = null):void {
var nS:Number = (stage.stageWidth > stage.stageHeight) ? stage.stageHeight / 465 : stage.stageWidth / 465;
stg.scaleX = stg.scaleY = nS;
stg.x = stage.stageWidth / 2 - sW * nS / 2;
stg.y = stage.stageHeight / 2 - sH * nS / 2;
}
private function click(e:MouseEvent):void {
// f.visible = true;
Tweener.addTween(f, {scaleX:1, scaleY:1, rotation:0, time:1, delay:2, transition:Equations.easeOutElastic, useFrames:false, onUpdate:function():void {
f.visible = true;
}});
removeEventListener(MouseEvent.MOUSE_OVER, click);
}
private function loadComplete(e:Event):void {
e.target.removeEventListener(Event.COMPLETE, loadComplete);
_bmdCurrent = new BitmapData(465, 465, true, 0xFFFFFF);
_bmdCurrent.draw(e.target.loader.content.bitmapData);
_canvas = new Sprite();
_container = new Sprite();
_container.addChild(_canvas);
stg.addChildAt(_container, 0);
_container.x = 0;
_container.y = 0;
_w = _bmdCurrent.width / Pice;
_matrixArrayCurrent = new Array();
_pointsArray = new Array();
for (var j:int = 0; j <= _bmdCurrent.width; j += _w) {
for (var i:int = 0; i <= _bmdCurrent.height; i += _w) {
var cp1:CirclePoint = new CirclePoint(i, j);
_matrixArrayCurrent.push(cp1);
_container.addChild(cp1);
var _points:Points = new Points(i, j);
_pointsArray.push(_points);
}
}
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
private function onEnterFrameHandler(e:Event):void {
var mousePoint:Point = new Point(stg.mouseX, stg.mouseY);
var i:int;
for each (var _point:Points in _pointsArray) {
_point.update(mousePoint, Reaction, spring, friction);
_matrixArrayCurrent[i].x = _point.x;
_matrixArrayCurrent[i].y = _point.y;
i++;
}
_draw();
}
private function _draw():void {
/**
* 0--------1
* ----------
* ----------
* 2--------3
*/
_canvas.graphics.clear();
for (var k:String in _matrixArrayCurrent) {
if (int(k) > _matrixArrayCurrent.length - (Pice + 3)) break;
if ((int(k) + 1) % (Pice + 1) == 0) continue;
_cP0 = _matrixArrayCurrent[int(k)];
_cP1 = _matrixArrayCurrent[int(k) + 1];
_cP2 = _matrixArrayCurrent[int(k) + (Pice + 1)];
_cP3 = _matrixArrayCurrent[int(k) + (Pice + 2)];
var aP0:Point = _cP0.initPoint;
var aP1:Point = _cP1.initPoint;
var aP2:Point = _cP2.initPoint;
var aP3:Point = _cP3.initPoint;
var bP0:Point = new Point(_cP0.x, _cP0.y);
var bP1:Point = new Point(_cP1.x, _cP1.y);
var bP2:Point = new Point(_cP2.x, _cP2.y);
var bP3:Point = new Point(_cP3.x, _cP3.y);
var indices:Vector.<int> = new Vector.<int>();
var uvtData:Vector.<Number> = new Vector.<Number>();
indices.push(0, 1, 2);
indices.push(1, 3, 2);
uvtData.push(aP0.x / _stageW, aP0.y / _stageH);
uvtData.push(aP1.x / _stageW, aP1.y / _stageH);
uvtData.push(aP2.x / _stageW, aP2.y / _stageH);
uvtData.push(aP3.x / _stageW, aP3.y / _stageH);
var vertices:Vector.<Number> = new Vector.<Number>();
vertices.push(bP0.x, bP0.y);
vertices.push(bP1.x, bP1.y);
vertices.push(bP2.x, bP2.y);
vertices.push(bP3.x, bP3.y);
_canvas.graphics.beginBitmapFill(_bmdCurrent, null, true, true);
_canvas.graphics.drawTriangles(vertices, indices, uvtData);
}
}
private function _getTransformMatrix($pt0:Point, $pt1:Point, $pt2:Point):Matrix {
var w:Number = _w;
var h:Number = _w;
var mat:Matrix = new Matrix();
mat.a = ($pt1.x - $pt0.x) / w;
mat.b = ($pt1.y - $pt0.y) / w;
mat.c = ($pt2.x - $pt0.x) / h;
mat.d = ($pt2.y - $pt0.y) / h;
mat.tx = $pt0.x;
mat.ty = $pt0.y;
return mat;
}
private function _cPMouseDownHandler(e:MouseEvent):void {
CirclePoint(e.target).startDrag();
CirclePoint(e.target).addEventListener(MouseEvent.MOUSE_MOVE, _cPMouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, _cPMouseUpHandler);
}
private function _cPMouseUpHandler(e:MouseEvent):void {
CirclePoint(e.target).stopDrag();
CirclePoint(e.target).removeEventListener(MouseEvent.MOUSE_MOVE, _cPMouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, _cPMouseUpHandler);
}
private function _cPMouseMoveHandler(e:MouseEvent):void {
_draw();
}
}
}
import flash.display.*;
import flash.geom.Point;
import flash.text.*;
class CirclePoint extends Sprite {
public var initPoint:Point;
public function CirclePoint($x:Number, $y:Number) {
x = $x;
y = $y;
this.initPoint = new Point($x, $y);
}
}
class Points {
private var localX:Number;
private var localY:Number;
private var vx:Number = 0;
private var vy:Number = 0;
private var _x:Number;
private var _y:Number;
public function Points(x:Number, y:Number) {
_x = localX = x;
_y = localY = y;
}
public function update(mousePoint:Point, Reaction:uint, spring:Number, friction:Number):void {
var dx:Number;
var dy:Number;
var distance:Number = Point.distance(mousePoint, new Point(localX, localY));
if (distance < Reaction) {
var diff:Number = distance * -1 * (Reaction - distance) / Reaction;
var radian:Number = Math.atan2(mousePoint.y - localY, mousePoint.x - localX);
var diffPoint:Point = Point.polar(diff, radian);
dx = localX + diffPoint.x;
dy = localY + diffPoint.y;
} else {
dx = localX;
dy = localY;
}
vx += (dx - _x) * spring;
vy += (dy - _y) * spring;
vx *= friction;
vy *= friction;
_x += vx;
_y += vy;
}
public function get x():Number {
return _x;
}
public function get y():Number {
return _y;
}
}
internal class Fukidashi extends Sprite {
public var bottomSheet:Sprite;
public const REP_LENGTH:Number = 2;
public const PADDING:Number = 5;
public const TAIL_POSITION:uint = 5;
public const TAIL_POSITION_RATE:Number = 0.5;
public const TAIL_WIDTH_RATE:Number = 0.04;
public var commentTF:TextField;
public function Fukidashi(tailX0:Number, tailY0:Number, w0:Number, textStr:String, fDebug:Boolean = false) {
var ii:uint;
var h0:Number;
bottomSheet = new Sprite();
addChild(bottomSheet);
bottomSheet.visible = true;
if (fDebug) {
var debugSheet:Sprite = new Sprite();
}
if (fDebug) {
var tailTopSpr:Sprite = new Sprite();
tailTopSpr.graphics.beginFill(0xFF0000);
tailTopSpr.graphics.drawCircle(tailX0, tailY0, 3);
tailTopSpr.graphics.endFill();
addChild(tailTopSpr);
}
commentTF = new TextField();
commentTF.text = textStr;
commentTF.setTextFormat(new TextFormat(null,14,0x000000,true));
commentTF.width = w0 + 4;
commentTF.multiline = true;
commentTF.wordWrap = true;
h0 = commentTF.textHeight + 4;
commentTF.height = h0;
if (fDebug) {
var displayArea:Sprite = new Sprite();
displayArea.graphics.beginFill(0xEEEEEE);
displayArea.graphics.drawRect(0, 0, w0, h0);
displayArea.graphics.endFill();
debugSheet.addChild(displayArea);
var displayFrame:Sprite = new Sprite();
displayFrame.graphics.lineStyle(0, 0xAAAAAA);
displayFrame.graphics.drawRect(-PADDING, -PADDING, w0 + 2 * PADDING, h0 + 2 * PADDING);
debugSheet.addChild(displayFrame);
}
var anchorPoint:Array = new Array();
anchorPoint.push(new Point(w0 * 0.11, -PADDING)) ;
anchorPoint.push(new Point(w0 * 0.675, -PADDING)) ;
anchorPoint.push(new Point(w0 + PADDING, h0 * 0.21));
anchorPoint.push(new Point(w0 + PADDING, h0 * 0.9));
anchorPoint.push(new Point(w0 * 0.825, h0 + PADDING)) ;
anchorPoint.push(new Point(w0 * 0.36, h0 + PADDING)) ;
anchorPoint.push(new Point(-PADDING, h0 * 0.85));
anchorPoint.push(new Point(-PADDING, h0 * 0.25));
var nAnchorPoint:int = anchorPoint.length;
if (fDebug) {
for (ii = 0; ii < nAnchorPoint; ii++) drawDebugDot(anchorPoint[ii].x, anchorPoint[ii].y, 0x0000CC);
}
var keisuuArr:Array = new Array();
keisuuArr.push({x:1.6, y:-2.4});
keisuuArr.push({x:-2.4, y:-2});
keisuuArr.push({x:8.2, y:-2});
keisuuArr.push({x:1.8, y:-5.6});
keisuuArr.push({x:1.6, y:2.8});
keisuuArr.push({x:1.4, y:-2.6});
keisuuArr.push({x:0.8, y:3.6});
keisuuArr.push({x:3.8, y:1.2});
keisuuArr.push({x:-3.2, y:1.8});
keisuuArr.push({x:3.4, y:2});
keisuuArr.push({x:-5.4, y:2.4});
keisuuArr.push({x:-1.6, y:5});
keisuuArr.push({x:-1.4, y:-2});
keisuuArr.push({x:-1.6, y:2.4});
keisuuArr.push({x:-1, y:-2.4});
keisuuArr.push({x:-5.2, y:-0.8});
var controlPoint:Array = new Array();
var ite1:int, ite2:int, xx:Number, yy:Number;
for (ii = 0; ii < nAnchorPoint; ii++) {
ite2 = ii * 2;
ite1 = (ite2 - 1 == -1) ? 15 : ite2 - 1;
xx = REP_LENGTH * keisuuArr[ite1].x;
yy = REP_LENGTH * keisuuArr[ite1].y;
controlPoint.push(new Point(xx, yy));
xx = REP_LENGTH * keisuuArr[ite2].x;
yy = REP_LENGTH * keisuuArr[ite2].y;
controlPoint.push(new Point(xx, yy));
}
var nControlPoint:int = controlPoint.length;
var tailTopPt:Point;
var p0:Point, p1:Point, p2:Point, p3:Point , t:Number, pt:Point , dt:Number = 0.02;
var nextnn:uint;
var bezierCurveSpr:Sprite = new Sprite();
bottomSheet.addChild(bezierCurveSpr);
bezierCurveSpr.graphics.beginFill(0xFFFFFF);
bezierCurveSpr.graphics.lineStyle(0, 0x333333);
for (ii = 0; ii < nAnchorPoint; ii++) {
drawBezierCurve(ii);
}
bezierCurveSpr.graphics.endFill();
function drawBezierCurve(nn:uint):void {
p0 = new Point(anchorPoint[nn].x, anchorPoint[nn].y);
nextnn = (nn + 1 == nAnchorPoint) ? 0 : nn + 1;
p3 = new Point(anchorPoint[nextnn].x, anchorPoint[nextnn].y);
ite1 = nn * 2 + 1;
ite2 = (ite1 + 1 == nControlPoint) ? 0 : ite1 + 1;
p1 = new Point(p0.x + controlPoint[ite1].x, p0.y + controlPoint[ite1].y);
p2 = new Point(p3.x + controlPoint[ite2].x, p3.y + controlPoint[ite2].y);
if (fDebug) {
drawDebugDot(p1.x, p1.y, 0x990000);
drawDebugDot(p2.x, p2.y, 0x990000);
}
if (nn == 0) bezierCurveSpr.graphics.moveTo(p0.x, p0.y);
for (t = 0.0; t <= 1.0; t += dt) {
if ( (nn == TAIL_POSITION) && (TAIL_POSITION_RATE - TAIL_WIDTH_RATE < t) && (t < TAIL_POSITION_RATE + TAIL_WIDTH_RATE) ) {
if ( (TAIL_POSITION_RATE - dt / 2 < t) && (t < TAIL_POSITION_RATE + dt / 2) ) {
drawTail(getBezierPoint(TAIL_POSITION_RATE - TAIL_WIDTH_RATE), getBezierPoint(t), getBezierPoint(TAIL_POSITION_RATE + TAIL_WIDTH_RATE));
}
} else {
pt = getBezierPoint(t);
bezierCurveSpr.graphics.lineTo(pt.x, pt.y);
}
}
bezierCurveSpr.graphics.lineTo(p3.x, p3.y);
}
function drawTail(tailPtA:Point, tailPtC:Point, tailPtB:Point):void {
tailTopPt = new Point(tailPtC.x + 5, tailPtC.y + 20);
drawATailCurve(1, tailPtA, tailTopPt);
drawATailCurve(2, tailTopPt, tailPtB);
function drawATailCurve(curveNumber:uint, p0:Point, p1:Point):void {
var pCent:Point;
var pCont:Point;
pCent = new Point((p0.x + p1.x) / 2, (p0.y + p1.y) / 2);
var tpt1:Point , tpt2:Point, rad:Number = 10 * Math.PI / 180;
if (curveNumber == 2) rad *= -1;
var xl1:Number = p0.x - pCent.x;
var yl1:Number = p0.y - pCent.y;
tpt1 = new Point(pCent.x + Math.cos(rad) * xl1 - Math.sin(rad) * yl1, pCent.y + Math.sin(rad) * xl1 + Math.cos(rad) * yl1);
rad *= -1;
xl1 = p1.x - pCent.x;
yl1 = p1.y - pCent.y;
tpt2 = new Point(pCent.x + Math.cos(rad) * xl1 - Math.sin(rad) * yl1, pCent.y + Math.sin(rad) * xl1 + Math.cos(rad) * yl1);
pCont = new Point((tpt1.x + tpt2.x) / 2, (tpt1.y + tpt2.y) / 2);
bezierCurveSpr.graphics.curveTo(pCont.x, pCont.y, p1.x, p1.y);
}
}
function getBezierPoint(t:Number):Point {
return new Point(Math.pow(1 - t, 3) * p0.x + 3 * t * Math.pow(1 - t, 2) * p1.x + 3 * t * t * (1 - t) * p2.x + t * t * t * p3.x, Math.pow(1 - t, 3) * p0.y + 3 * t * Math.pow(1 - t, 2) * p1.y + 3 * t * t * (1 - t) * p2.y + t * t * t * p3.y);
}
bottomSheet.x = tailX0 - tailTopPt.x;
bottomSheet.y = tailY0 - tailTopPt.y;
if (fDebug) bottomSheet.addChild(debugSheet);
bottomSheet.addChild(commentTF);
function drawDebugDot(xx:Number, yy:Number, color:Number):void {
var dot:Sprite = new Sprite();
dot.graphics.beginFill(color);
dot.graphics.drawCircle(xx, yy, 3);
dot.graphics.endFill();
debugSheet.addChild(dot);
}
}
}