Flush
@author Will Costa
@author http://www.williancosta.com/blog
/**
* Copyright will_costa ( http://wonderfl.net/user/will_costa )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6Axg
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
/**
* @author Will Costa
* @author http://www.williancosta.com/blog
*/
[SWF(backgroundColor="#000000", frameRate="31", width="465", height="465")]
public class Flush extends Sprite {
private var _loader:FileLoader;
private var _trianglesSprite:TrianglesSprite;
private var _textField:TextField;
public function Flush() {
Wonderfl.capture_delay(20);
_textField = new TextField();
_textField.textColor = 0xFFFFFF;
_textField.autoSize = "left";
_textField.text = "Click to upload image";
addChild(_textField);
_loader = new FileLoader();
_loader.addEventListener(Event.INIT, _loader_onCompleteHandler);
_loader.addEventListener(Event.CANCEL, _loader_onCancelHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, initFileLoader);
}
// ----------------------------------
// Private Functions
// ----------------------------------
private function initFileLoader(event : MouseEvent) : void {
_loader.load();
_textField.text = "loading...";
stage.removeEventListener(MouseEvent.MOUSE_DOWN, initFileLoader);
}
// ----------------------------------
// Event Handlers
// ----------------------------------
private function _loader_onCompleteHandler(event : Event) : void {
_textField.text = "click to flush";
_trianglesSprite = new TrianglesSprite();
addChild(_trianglesSprite);
var image:Bitmap = new Bitmap(_loader.bitmapData);
if(image.width > 460){
image.width = 460;
image.scaleY = image.scaleX;
}
if(image.height > 460){
image.height = 460;
image.scaleX = image.scaleY;
}
_trianglesSprite.x = (465-image.width)/2;
_trianglesSprite.y = (465-image.height)/2;
var newBD : BitmapData = new BitmapData(image.width, image.height);
newBD.draw(image);
_trianglesSprite.draw(newBD, 50, 50);
}
private function _loader_onCancelHandler(event : Event) : void {
_textField.text = "Click to upload image";
stage.addEventListener(MouseEvent.MOUSE_DOWN, initFileLoader);
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
internal class TrianglesSprite extends Sprite {
private var _vertices : Vector.<Number>;
private var _indices : Vector.<int>;
private var _uvtData : Vector.<Number>;
private var _texture : BitmapData;
private var _points : Vector.<Vertex>;
private var _mouseIsDown : Boolean;
private var _maxRadius : Number = 0;
public function TrianglesSprite() {
}
// ----------------------------------
// Public Functions
// ----------------------------------
/**
* Draw the texture in the object using drawTriangles;
* @param texture the BitmapData that will be used as texture
* @param segmentsW num of horizontal segments
* @param segmentsH num of vertical segments
*/
public function draw(texture : BitmapData, segmentsW : int = 3, segmentsH : int = 3):void {
_texture = texture;
var w : Number = _texture.width;
var h : Number = _texture.height;
_vertices = new Vector.<Number>();
_indices = new Vector.<int>();
_uvtData = new Vector.<Number>();
_points = new Vector.<Vertex>();
var _x : Number;
var _y : Number;
for (var j : int = 0; j <= segmentsH; j++) {
for (var i : int = 0; i <= segmentsW; i++) {
_x = w / segmentsW * i;
_y = h / segmentsH * j;
_vertices.push(_x, _y);
_points.push(new Vertex(_x,_y));
_uvtData.push(i / (segmentsW), j / (segmentsH));
var tl : int = i + j * (segmentsW + 1);
var tr : int = tl + 1;
var bl : int = tl + (segmentsW + 1);
var br : int = bl + 1;
if(i < segmentsW && j < segmentsH) _indices.push(tl, tr, br, tl, br, bl);
}
}
graphics.beginBitmapFill(_texture);
graphics.drawTriangles(_vertices, _indices, _uvtData);
graphics.endFill();
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
}
private function onMouseUpHandler(event : MouseEvent) : void {
_mouseIsDown = false;
}
private function onMouseDownHandler(event : MouseEvent) : void {
var n : int = _points.length;
var p : Vertex;
graphics.clear();
_maxRadius = 0;
for (var i : int = 0; i < n; i++) {
p = _points[i];
p.angle = Math2.angleBetweenTwoPoints({x:mouseX, y:mouseY}, p);
p.radius = Math2.distanceBetweenTwoPoints(p, {x:mouseX, y:mouseY});
if(p.radius > _maxRadius) _maxRadius = p.radius;
}
_mouseIsDown = true;
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
// ----------------------------------
// Event Handlers
// ----------------------------------
private function onEnterFrameHandler(event : Event) : void {
var n : int = _points.length;
var p : Vertex;
graphics.clear();
for (var i : int = 0; i < n; i++) {
p = _points[i];
if(_mouseIsDown) {
var _x : Number = mouseX + (Math.cos(p.angle) * p.radius);
var _y : Number = mouseY + (Math.sin(p.angle) * p.radius);
p.x -= (p.x - _x) / 10;
p.y -= (p.y - _y) / 10;
p.angle += (1 - (p.radius / _maxRadius)) / 5;
p.radius -= p.radius / 50;
} else {
p.x -= (p.x - p.inix) / 5;
p.y -= (p.y - p.iniy) / 5;
}
_vertices[(i * 2)] = p.x;
_vertices[(i * 2) + 1] = p.y;
graphics.drawCircle(p.x, p.y, 1);
}
graphics.beginBitmapFill(_texture);
graphics.drawTriangles(_vertices, _indices, _uvtData);
graphics.endFill();
}
}
internal class Vertex {
public var x : Number;
public var y : Number;
public var inix : Number;
public var iniy : Number;
public var angle : Number = 0;
public var radius : Number = 0;
public function Vertex(x : Number, y : Number) {
this.x = x;
this.y = y;
inix = x;
iniy = y;
}
}
internal class Math2 {
public static function angleBetweenTwoPoints(a : Object, b : Object) : Number {
return Math.atan2(b.y - a.y, b.x - a.x);
}
public static function distanceBetweenTwoPoints(a : Object, b : Object) : Number {
var dx : Number = b.x - a.x;
var dy : Number = b.y - a.y;
var dist : Number = Math.sqrt(dx * dx + dy * dy);
return dist;
}
}
internal class FileLoader extends EventDispatcher {
private var file:FileReference;
private static var typeFilter:Array;
public var data:*;
private var loader:Loader;
public var bitmapData:BitmapData;
public function FileLoader() {
init();
}
private function init():void {
file = new FileReference();
file.addEventListener(Event.SELECT, select, false, 0, true);
file.addEventListener(Event.CANCEL, cancel, false, 0, true);
file.addEventListener(Event.COMPLETE, complete, false, 0, true);
var fileFilter:FileFilter = new FileFilter("Images", "*.jpg;*.gif;*.png");
typeFilter = [fileFilter];
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, initialize, false, 0, true);
}
public function load():void {
file.browse(typeFilter);
}
private function select(evt:Event):void {
file.load();
dispatchEvent(evt);
}
private function cancel(evt:Event):void {
dispatchEvent(evt);
}
private function complete(evt:Event):void {
data = evt.target.data;
loader.loadBytes(data);
dispatchEvent(evt);
}
private function initialize(evt:Event):void {
bitmapData = null;
var bitmap:Bitmap = Bitmap(evt.target.content);
bitmapData = bitmap.bitmapData;
dispatchEvent(evt);
}
}