Famous Triangle Trick
My first use of Tweener. Brilliant library!
/**
* Copyright k0rin ( http://wonderfl.net/user/k0rin )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/8fyY
*/
package {
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.Matrix;
import flash.text.*;
// My first use of Tweener. Brilliant library!
import caurina.transitions.Tweener;
import caurina.transitions.properties.CurveModifiers;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor="0x38502A")]
public class TriangleTrick extends Sprite {
private const W:Number = stage.stageWidth;
private const H:Number = stage.stageHeight;
private const ORIGIN_X:Number = W * 0.06;
private const ORIGIN_Y:Number = H * 0.63;
private const GRID_SPACING:int = 30;
private var polygons:Vector.<Shape> = new Vector.<Shape>();
private var polygonData:Array = [
{ x:[0, 5], y:[0, 2], bezier:{ x:0, y:9, rotation:20 }, color:0xFF3300, vertices:[0, 0, 8, 0, 8, 3] },
{ x:[8, 0], y:[3, 0], bezier:{ x:4, y:4, rotation:-5 }, color:0x0033FF, vertices:[0, 0, 5, 0, 5, 2] },
{ x:[8, 5], y:[1, 0], bezier:{ x:5, y:1, rotation:10 }, color:0xFFFF33, vertices:[0, 0, 2, 0, 2, 1, 5, 1, 5, 2, 0, 2] },
{ x:[8, 8], y:[0, 0], bezier:{ x:9, y:-2.5, rotation:20 }, color:0x00FF00, vertices:[0, 0, 5, 0, 5, 2, 2, 2, 2, 1, 0, 1] },
];
private var triangleState:int = 0;
private const MESSAGES:Array = [
// Want some nifty messages but I'm not good at English... Please help!
"Click it!",
"What the hell happened!?",
"Check it carefully!",
"Don't you understand?",
];
private var messageNo:int = 0;
private var textField:TextField = new TextField();
private var circle:Shape = new Shape();
private var cursor:Shape = new Shape();
private const CURSOR_Y:Number = H * 0.95;
public function TriangleTrick():void {
CurveModifiers.init();
var grid:Shape = new Shape();
var g:Graphics = grid.graphics;
g.lineStyle(1, 0x000000, 0.2);
for (var i:int = -30; i < 30; i++) {
g.drawRect(ORIGIN_X + GRID_SPACING * i + 2, -400, 0, 1600);
g.drawRect(-400, ORIGIN_Y + GRID_SPACING * i + 2, 1600, 0);
}
addChild(grid);
textField.defaultTextFormat = new TextFormat("Helvetica", 20, 0x444444, true, false);
textField.text = MESSAGES[messageNo];
textField.autoSize = TextFieldAutoSize.CENTER;
textField.selectable = false;
textField.x = W * 0.42;
textField.y = H * 0.73;
textField.filters = [ new GlowFilter(0xFFFFFF, 1, 40, 30, 8) ];
addChild(textField);
// Couldn't use DisplayObject.transform to zoom because lines' thickness is treated as integer.
function toPixelX(graphX:Number):Number { return ORIGIN_X + graphX * GRID_SPACING; }
function toPixelY(graphY:Number):Number { return ORIGIN_Y - graphY * GRID_SPACING; }
var triangle:Sprite = new Sprite();
for (i = 0; i < polygonData.length; i++) {
var pd:Object = polygonData[i];
// scale polygon data
for (var j:int = 0; j < pd.x.length; j++) {
pd.x[j] = toPixelX(pd.x[j]);
pd.y[j] = toPixelY(pd.y[j]);
}
pd.bezier.x = toPixelX(pd.bezier.x);
pd.bezier.y = toPixelY(pd.bezier.y);
for (j = 0; j < pd.vertices.length; j += 2) {
pd.vertices[j ] *= GRID_SPACING;
pd.vertices[j + 1] *= -GRID_SPACING;
}
// create a polygon
var polygon:Shape = new Shape();
g = polygon.graphics;
g.lineStyle(4, 0xFFFFFF);
var matrix:Matrix = new Matrix();
matrix.createGradientBox(GRID_SPACING * 4, GRID_SPACING * 4, 70 * Math.PI / 180, 0, -95);
g.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, pd.color], [0.5, 0.6], [0, 255], matrix);
var commands:Vector.<int> = Vector.<int>([GraphicsPathCommand.MOVE_TO]);
for (j = 0; j < pd.vertices.length / 2; j++) {
commands.push(GraphicsPathCommand.LINE_TO);
}
g.drawPath(commands, Vector.<Number>(pd.vertices.concat(pd.vertices[0], pd.vertices[1])));
g.endFill();
polygon.x = pd.x[0];
polygon.y = pd.y[0];
triangle.addChild(polygon);
polygons.push(polygon);
}
triangle.filters = [ new DropShadowFilter(4, 45, 0x000000, 0.5, 0, 0) ];
addChild(triangle);
g = circle.graphics;
g.lineStyle(8, 0xFF0000, 0.8);
g.drawCircle(toPixelX(7.5), toPixelY(0.5), 1.2 * GRID_SPACING);
circle.alpha = 0;
addChild(circle);
g = cursor.graphics;
g.beginFill(0xFFFFFF);
g.drawPath(Vector.<int>([1, 2, 2, 2]), Vector.<Number>([0, 0, -1, -1.7, 1, -1.7, 0, 0]));
cursor.x = W * 0.945;
cursor.y = CURSOR_Y;
cursor.scaleX = cursor.scaleY = 5;
cursor.filters = [ new DropShadowFilter(3, 45, 0x000000, 0.5, 0, 0) ];
addChild(cursor);
enableClick();
}
private function enableClick():void {
stage.addEventListener(MouseEvent.CLICK, clickHandler);
tickCursor();
}
private function disableClick():void {
stage.removeEventListener(MouseEvent.CLICK, clickHandler);
Tweener.removeTweens(cursor);
cursor.alpha = 0;
}
private function clickHandler(event:MouseEvent):void {
disableClick();
// an easy way to flip integers
triangleState = 1 - triangleState;
for (var i:int = 0; i < polygons.length; i++) {
Tweener.addTween(polygons[i], {
// Which transition type do you like?
time:0.7, transition:"easeOutCubic",
x:polygonData[i].x[triangleState],
y:polygonData[i].y[triangleState],
rotation:0,
_bezier:polygonData[i].bezier} );
}
if (triangleState == 1) {
circle.x = -0;
circle.y = -30;
Tweener.addTween(circle, { delay:0.7, time:0.6, transition:"easeOutElastic", x:0, y:0 } );
Tweener.addTween(circle, { delay:0.7, time:0.2, transition:"easeOutQuart", alpha:1 });
} else {
Tweener.addTween(circle, { time:0.2, transition:"easeOutQuart", alpha:0 });
}
if (++messageNo >= MESSAGES.length) {
messageNo = 1;
}
textField.text = MESSAGES[messageNo];
textField.alpha = 0;
Tweener.addTween(textField, { delay:0.6, time:0.2, transition:"easeInQuart", alpha:1, onComplete:enableClick } );
}
private function tickCursor():void {
cursor.y = CURSOR_Y;
Tweener.addTween(cursor, { time:0.25, transition:"linear", y:CURSOR_Y + 3 } );
Tweener.addTween(cursor, { time:0.1, transition:"easeOutSine", alpha:1 } );
Tweener.addTween(cursor, { delay:0.15, time:0.1, transition:"easeOutSine", alpha:0 } );
Tweener.addTween(cursor, { delay:0.45, onComplete:tickCursor } );
}
}
}