SandEffect
SandEffect
/**
* Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kTul
*/
////////////////////////////////////////////////////////////////////////////////
// SandEffect
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.system.LoaderContext;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.events.TweenEvent;
import org.libspark.betweenas3.easing.*;
[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private var loader:Loader;
private static var basePath:String = "http://assets.wonderfl.net/images/related_images/";
private static var filePath:String = "e/ef/ef33/ef332d0347b2d07b664eef52f6b4302890550a8f";
private var logo:Bitmap;
private var sand:SandEffect;
public function Main() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//Wonderfl.capture_delay(1);
init();
}
private function init():void {
var rect:Rectangle = new Rectangle(0, 0, 400, 200);
var area:Rectangle = new Rectangle(0, 50, 400, 100);
sand = new SandEffect(rect, area, 200);
addChild(sand);
sand.x = 32;
sand.y = 132;
//
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, initialize, false, 0, true);
loader.load(new URLRequest(basePath + filePath), new LoaderContext(true));
}
private function initialize(evt:Event):void {
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, initialize);
logo = Bitmap(loader.content);
addChild(logo);
logo.x = 32;
logo.y = 182;
logo.alpha = 0;
logo.visible = false;
//
sand.search(logo);
sand.addEventListener(Event.COMPLETE, complete, false, 0, true);
sand.start();
}
private function complete(evt:Event):void {
sand.removeEventListener(Event.COMPLETE, complete);
var itween:ITween = BetweenAS3.parallel(
BetweenAS3.to(logo, {alpha: 1, visible: 1}, 0.4, Linear.easeNone),
BetweenAS3.delay(BetweenAS3.to(sand, {alpha: 0, visible: 0}, 0.4, Linear.easeNone), 0.2)
);
itween.play();
}
}
}
//////////////////////////////////////////////////
// SandEffectクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.DisplayObject;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.events.TweenEvent;
import org.libspark.betweenas3.easing.*;
class SandEffect extends Sprite {
private var rect:Rectangle;
private var area:Rectangle;
private var offset:uint;
private var bitmapData:BitmapData;
private var bitmap:Bitmap;
private var detection:DetectPixels;
private var target:DisplayObject;
private var threshold:uint = 0x80000000;
private var maps:Array;
private var dots:Array;
private var itween:ITween;
private var tweens:Array;
private static var unit:uint = 10;
public function SandEffect(r:Rectangle, a:Rectangle, o:uint = 0) {
rect = r;
area = a;
offset = o;
init();
}
private function init():void {
bitmapData = new BitmapData(rect.width + offset, rect.height, true, 0x00000000);
bitmap = new Bitmap(bitmapData);
addChild(bitmap);
}
public function search(t:DisplayObject):void {
target = t;
detection = new DetectPixels(1);
detection.search(target, rect, threshold);
maps = detection.pixels();
plot(maps);
}
private function plot(maps:Array):void {
dots = new Array();
tweens = new Array();
for (var n:uint = 0; n < maps.length; n++) {
var point:Object = maps[n];
var dot:SandDot = new SandDot(point.color);
dot.alpha = 0;
dot.x = dot.px = area.x + point.x + offset - Math.random()*50;
dot.y = dot.py = area.y + point.y + (Math.random() - 0.5)*100;
dot.tx = area.x + point.x;
dot.ty = area.y + point.y;
dot.cx = (dot.px + dot.tx)/2 + (Math.random() - 0.5)*100;
dot.cy = dot.y + (Math.random() - 0.5)*80;
dots.push(dot);
var tween:ITween = BetweenAS3.delay(BetweenAS3.parallel(
BetweenAS3.to(dot, {alpha: 1}, 0.4 + 0.008*uint(n/unit), Linear.easeNone),
BetweenAS3.serial(
BetweenAS3.tween(dot, {x: dot.cx, y: dot.cy}, {x: dot.px, y: dot.py}, 0.8, Quad.easeIn),
BetweenAS3.tween(dot, {x: dot.tx, y: dot.ty}, {x: dot.cx, y: dot.cy}, 0.6, Sine.easeOut)
)
), 0.01*uint(n/unit));
tweens.push(tween);
}
}
public function start():void {
itween = BetweenAS3.parallelTweens(tweens);
itween.addEventListener(TweenEvent.COMPLETE, complete, false, 0, true);
itween.play();
update();
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
}
public function stop():void {
if (itween) {
itween.stop();
itween = null;
}
removeEventListener(Event.ENTER_FRAME, update);
}
private function update(evt:Event = null):void {
bitmapData.lock();
bitmapData.fillRect(bitmapData.rect, 0x00000000);
for (var n:uint = 0; n < dots.length; n++) {
var dot:SandDot = dots[n];
var rgb:uint = 0xFFFFFF & dot.color;
var color:uint = rgb | ((dot.alpha*0xFF) << 24);
bitmapData.setPixel32(dot.x, dot.y, color);
}
bitmapData.unlock();
}
private function complete(evt:TweenEvent):void {
itween.removeEventListener(TweenEvent.COMPLETE, complete);
update();
removeEventListener(Event.ENTER_FRAME, update);
dispatchEvent(new Event(Event.COMPLETE));
}
}
//////////////////////////////////////////////////
// SandDotクラス
//////////////////////////////////////////////////
class SandDot {
public var x:Number = 0;
public var y:Number = 0;
public var alpha:Number = 0;
public var px:Number = 0;
public var py:Number = 0;
public var tx:Number = 0;
public var ty:Number = 0;
public var cx:Number = 0;
public var cy:Number = 0;
public var color:Number = 0;
public function SandDot(c:uint) {
color = c;
}
}
//////////////////////////////////////////////////
// DetectPixelsクラス
//////////////////////////////////////////////////
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.display.IBitmapDrawable;
class DetectPixels {
private var bd:IBitmapDrawable;
private var rect:Rectangle;
private var map:BitmapData;
private var maps:Array;
private var accuracy:uint;
private var threshold:uint = 0x80FFFFFF;
private var offset:Object = {x: 0, y: 0};
public function DetectPixels(a:uint = 1) {
accuracy = a;
}
public function search(t:IBitmapDrawable, r:Rectangle, th:uint = 0x80FFFFFF, o:Object = null):void {
bd = t;
rect = r;
threshold = th;
if (o) offset = o;
var w:uint = rect.width/accuracy;
var h:uint = rect.height/accuracy;
detect(w, h);
}
private function detect(w:uint, h:uint):void {
map = new BitmapData(w, h, true, 0x00000000);
var matrix:Matrix = new Matrix();
matrix.translate(-rect.x, -rect.y);
matrix.scale(1/accuracy, 1/accuracy);
map.lock();
map.draw(bd, matrix);
map.unlock();
maps = new Array();
for (var x:uint = 0; x < w; x++) {
for (var y:uint = 0; y < h; y++) {
var color:uint = map.getPixel32(x, y);
if (color >= threshold) {
var px:int = x*accuracy + rect.x + offset.x;
var py:int = y*accuracy + rect.y + offset.y;
maps.push({x: px, y: py, color: color});
}
}
}
}
public function pixels():Array {
return maps;
}
}