WIP: MacOS Genie Effect
This a atempt to create the genie effect similar to MacOS, I try to create a fully parametrizable object that you can use.
/**
* Copyright cralph ( http://wonderfl.net/user/cralph )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2zQy
*/
package
{
import flash.system.LoaderContext;
import flash.events.ProgressEvent;
import flash.errors.IOError;
import caurina.transitions.Tweener;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
/**
* ...
* @author Caleb Chicohay
*/
import com.actionscriptbible.Example;
public class GenieEffect extends Example {
public const SLICESY:int = 15;
public const SLICESX:int = 10;
public var EFFECT_TIME:Number = .5;// TIME IN SECONDS
public var canvas:Sprite;
public var pivot:Sprite;
public var step:Number = 0;
public var overhead:Number = 0;
public var state:String = "normal";
public var imageToSample:BitmapData;
public var imageURL:String = "http://upload.wikimedia.org/wikipedia/en/7/7e/AquaControlsIB.png";
public function GenieEffect() {
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageComplete);
l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
l.load(new URLRequest(imageURL), new LoaderContext(true));
}
public function onImageComplete(e:Event):void {
try {
imageToSample = Bitmap(e.target.content).bitmapData;
init();
} catch(e:Error){
trace('There was an Error: '+e);
}
}
public function onProgress(e:ProgressEvent):void{
trace('Loading: '+Math.floor((e.bytesLoaded/e.bytesTotal)*100)+'%');
}
public function onIOError(e:IOErrorEvent):void{
trace(e);
}
public function init():void {
canvas = new Sprite();
this.addChild(canvas);
pivot = new Sprite();
pivot.graphics.beginFill(0);
pivot.graphics.drawRect(0, 0, 30, 10);
pivot.x = (stage.stageWidth -pivot.width) / 2;
pivot.y = stage.stageHeight - 10;
pivot.buttonMode = true;
pivot.addEventListener(MouseEvent.CLICK, toggleImage);
pivot.addEventListener(MouseEvent.MOUSE_DOWN, dragPivot);
this.addEventListener(MouseEvent.MOUSE_UP, function():void { stopDrag(); } );
this.addChild(pivot);
render();
}
public function dragPivot(e:MouseEvent):void {
pivot.startDrag(false, new Rectangle(0, pivot.y, stage.stageWidth -pivot.width, 0));
}
public function toggleImage(e:MouseEvent):void {
if(state=="normal"){
Tweener.addTween(this, { paso:1, time:EFFECT_TIME, transition:"easeinoutquart",
onComplete:function():void {
Tweener.addTween(this, { offset:1, time:EFFECT_TIME, transition:"easeinoutquart",
onComplete:function():void{
state="minimized"
}
});
}
});
} else {
Tweener.addTween(this, { offset:0, time:EFFECT_TIME, transition:"easeinoutquart",
onComplete:function():void {
Tweener.addTween(this, { paso:0, time:EFFECT_TIME, transition:"easeinoutquart",
onComplete:function():void{
state="normal"
}
});
}
});
}
}
public function onClick(e:MouseEvent):void {
step += .05;
render(step);
}
public function set paso(n:Number):void {
step = n;
render(step);
}
public function get paso():Number {
return step;
}
public function set offset(n:Number):void {
overhead = n;
render(step, overhead);
}
public function get offset():Number {
return overhead;
}
public function render(p:Number=0, s:Number = 0):void {
var imageWidth:Number = stage.stageWidth;
var imageHeight:Number = stage.stageHeight - 10;
canvas.graphics.clear();
for (var i:uint = 0; i < SLICESY; i++) {
var sliceX1_a:Number = easeInOut(
SLICESY * s + ((1 - s) * i)
, 0, pivot.x, SLICESY) * p;
var sliceX2_a:Number = imageWidth - (
easeInOut(
SLICESY * s + ((1 - s) * i)
, 0, imageWidth - pivot.x - pivot.width, SLICESY) * p );
var sliceWidth_a:Number = sliceX2_a - sliceX1_a;
var sliceY_a:Number = s * imageHeight + ((1 - s) * (imageHeight * (i / SLICESY)));
var sliceX1_b:Number = easeInOut(
SLICESY * s + ((1 - s) * (i + 1))
, 0, pivot.x, SLICESY) * p;
var sliceX2_b:Number = imageWidth - (
easeInOut(
SLICESY * s + ((1 - s) * (i + 1))
, 0, imageWidth - pivot.x - pivot.width, SLICESY) * p );
var sliceWidth_b:Number = sliceX2_b - sliceX1_b;
var sliceY_b:Number = s * imageHeight + ((1 - s) * (imageHeight * ((i + 1) / SLICESY)));
for (var j:uint = 0; j < SLICESX;j++){
var vertices:Vector.<Number> = new Vector.<Number>();
var indices:Vector.<int> = new Vector.<int>();
var uvtData:Vector.<Number> = new Vector.<Number>();
vertices.push(
sliceX1_a + ( j*sliceWidth_a / SLICESX ),
sliceY_a ,
sliceX1_a + ( (j+1) * sliceWidth_a / SLICESX),
sliceY_a ,
sliceX1_b + ( (j+1) * sliceWidth_b / SLICESX),
sliceY_b ,
sliceX1_b + ( j*sliceWidth_b / SLICESX),
sliceY_b
);
indices.push( 0, 1, 3 , 1, 2, 3);
uvtData.push(j/SLICESX, i/SLICESY , (j+1)/SLICESX,i/SLICESY , (j+1)/SLICESX,(i+1)/SLICESY, j/SLICESX, (i+1)/SLICESY);
canvas.graphics.beginBitmapFill(imageToSample, null,false);
canvas.graphics.drawTriangles(vertices, indices, uvtData);
canvas.graphics.endFill();
}
}
}
/*
EASE FUNCTIONS
*/
public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
return c*(t/=d)*t*t*t + b;
}
public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
}
public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
}
public static function SineEaseIn (t:Number, b:Number, c:Number, d:Number):Number {
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
};
}
}