forked from: Butterfly (+animation)
/**
* Copyright Liviu.Eu ( http://wonderfl.net/user/Liviu.Eu )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/87FJ
*/
// forked from tencho's Butterfly (+animation)
/**
* Click : Zoom In
* CTRL+Click : Zoom Out
* Drag : Move
* 1-5 : Somewhere
*/
package {
import com.bit101.components.*;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Point;
import frocessing.color.ColorHSV;
public class Study extends Sprite {
private var _bg:Sprite = new Sprite();
private var _bmp:Bitmap;
private var _bmd:BitmapData;
private var _buffer:BitmapData;
private var _md:Mandelbrot;
private var _animate:Boolean = true;
private var _fade:Boolean = true;
private var _deep:Boolean = false;
private var _ctrl:Boolean = false;
private var _isMouseDown:Boolean = false;
private var _isDrag:Boolean = false;
private var _staticScale:Number = 1;
private var _animationScale:Number = 0.5;
private var _centerRI:Point = new Point();
private var _downRI:Point = new Point();
private var _downXY:Point = new Point();
private var _alphaBlend:ColorTransform = new ColorTransform(1, 1, 1, 0.15, 0, 0, 0, 0);
private var _checks:Vector.<CheckBox> = new Vector.<CheckBox>();
private var _timer:ClockTimer = new ClockTimer();
private var _drawScale:Number;
private var _zoom:Number;
public function Study() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.frameRate = 60;
_bmp = new Bitmap(_bmd, "auto", true);
setCanvasScale(_animationScale);
addChild(_bg);
addChild(_bmp);
createButtons();
_bg.graphics.beginFill(0);
_bg.graphics.drawRect(0, 0, 465, 465);
_timer.start();
_timer.time = 2000;
_md = new Mandelbrot();
_md.colors.length = 0;
for (var c:int = 0; c < 256; c++)
_md.colors[c] = !c ? 0xFFFFFFFF : (c < 128) ? new ColorHSV(70 - 40 * c / 128, 1, 1).value32 : new ColorHSV(30, 1, 2 - c / 128).value32;
_bg.addEventListener(MouseEvent.MOUSE_DOWN, onDownStage);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onDragStage);
stage.addEventListener(MouseEvent.MOUSE_UP, onUpStage);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyInput);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyInput);
resetPosition();
updateSettings();
}
private function createButtons():void {
Style.PANEL = 0x222222;
new Panel(this, 465 - 90, 0).setSize(90, 105);
var vox:VBox = new VBox(this, 465 - 80, 6);
Style.LABEL_TEXT = 0xFFFFFF;
Style.BACKGROUND = 0x666666;
new FPSMeter(vox, 0, 0);
var labels:Array = ["ANIMATION", "BLUR", "DEEP"];
for (var i:int = 0; i < labels.length; i++)
_checks[i] = new CheckBox(vox, 0, 0, labels[i], updateSettings);
Style.LABEL_TEXT = 0;
new PushButton(vox, 0, 10, "RESET", resetPosition).setSize(70, 18);
_checks[0].selected = _animate;
_checks[1].selected = _fade;
_checks[2].selected = _deep;
}
private function onKeyInput(e:KeyboardEvent):void {
if (e.type == KeyboardEvent.KEY_UP) {
switch(e.keyCode) {
///case 32: System.setClipboard("jump(" + _centerRI.x.toFixed(String(int(_zoom)).length+2) + ", " + _centerRI.y.toFixed(String(int(_zoom)).length+2) + ", " + _zoom.toFixed(1) + ", " + _timer.time + ", "+_deep+");"); break;
case 49: case 97: jump( -0.32295, 0.000975, 0.8, 108841, false); break;
case 50: case 98: jump(-0.37453, 1.16594, 46, 165175, false); break;
case 51: case 99: jump(0.40441, -0.09875, 1995, 73081, true); break;
case 52: case 100: jump(-0.77836, 0.00102, 525, 38564, true); break;
case 53: case 101: jump(0.79734, 0.06116, 288, 34733, true); break;
}
}
_ctrl = e.ctrlKey;
}
private function jump(x:Number, y:Number, zoom:Number, time:int, deep:Boolean):void {
_timer.time = time;
_centerRI = new Point(x, y);
_zoom = zoom;
_checks[0].selected = false;
_checks[2].selected = deep;
updateSettings();
draw(true, _fade);
}
private function resetPosition(e:MouseEvent = null):void {
_centerRI = new Point( -0.1, 0);
_zoom = 0.7;
draw(true, _fade);
}
private function updateSettings(e:Event = null):void {
_animate = _checks[0].selected;
_fade = _checks[1].selected;
_deep = _checks[2].selected;
_timer.setPlaying(_animate);
_md.iteration = _deep? 120 : 30;
setCanvasScale(_animate? _animationScale : _staticScale);
draw(true, false);
}
private function onEnterFrame(e:Event):void {
draw(_animate, _fade);
}
private function setCanvasScale(scale:Number):void {
_drawScale = scale;
if(_bmd) _bmd.dispose();
if(_buffer) _buffer.dispose();
_bmd = new BitmapData(465 * scale, 465 * scale, false, 0);
_buffer = new BitmapData(465 * scale, 465 * scale, true, 0);
_bmp.bitmapData = _bmd;
_bmp.width = _bmp.height = 465;
}
private function onDownStage(e:MouseEvent):void {
_isMouseDown = true;
_isDrag = false;
_downRI = _centerRI.clone();
_downXY = new Point(mouseX, mouseY);
}
private function onUpStage(e:MouseEvent):void {
if (!_isMouseDown) return;
_isMouseDown = false;
if (!_isDrag) {
var m:int = _ctrl? -1 : 1;
var tx:Number = (mouseX - _bmp.width / 2) * _md.SX / _zoom * m;
var ty:Number = (mouseY - _bmp.height / 2) * _md.SY / _zoom * m;
_centerRI.offset(tx, ty);
_zoom *= Math.pow(1.5, m);
}
if (!_animate) setCanvasScale(_staticScale);
draw(true, false);
}
private function onDragStage(e:MouseEvent):void {
if (!_isMouseDown) return;
if (!_isDrag) {
if (Point.distance(new Point(_bmp.mouseX, _bmp.mouseY), _downXY) > 2) {
setCanvasScale(_animationScale);
draw(true, false);
_isDrag = true;
}
return;
}
_centerRI.x = _downRI.x - (mouseX - _downXY.x) * _md.SX / _zoom;
_centerRI.y = _downRI.y - (mouseY - _downXY.y) * _md.SY / _zoom;
if (!_animate) draw(true, _fade);
}
public function draw(calc:Boolean = true, fade:Boolean = true):void {
if (calc) {
var r:Number = _timer.time * 0.007;
_md.t = Math.sin(Math.PI / 180 * r*0.5) * 2;
_md.x0 = Math.cos(Math.PI / 180 * r) * 0.8;
_md.y0 = (Math.sin(Math.PI / 180 * r) + 2) * 0.2;
_buffer.setVector(_bmd.rect, _md.getPixelsByCenter(_centerRI.x, _centerRI.y, _zoom * _drawScale, _zoom * _drawScale, _buffer.width, _buffer.height));
if (fade) _buffer.colorTransform(_buffer.rect, _alphaBlend);
}
_bmd.copyPixels(_buffer, _buffer.rect, new Point(0, 0), null, null, true);
}
}
}
import flash.geom.Rectangle;
import flash.utils.getTimer;
import frocessing.color.ColorHSV;
class ClockTimer {
private var _time:int = 0;
private var _start:int = 0;
private var _isPlaying:Boolean = false;
public function get isPlaying():Boolean { return _isPlaying; }
public function get time():int { return (!_isPlaying)? _time : _time + getTimer() - _start; }
public function set time(value:int):void { setTime(value); }
public function ClockTimer() {
}
public function reset():void {
setTime(0);
}
private function setTime(value:int):void {
_time = value;
_start = getTimer();
}
public function setPlaying(play:Boolean):void {
play? start() : stop();
}
public function start():void {
if (_isPlaying) return;
_start = getTimer();
_isPlaying = true;
}
public function stop():void {
_time = time;
_isPlaying = false;
}
}
class Mandelbrot {
public var iteration:int = 100;
public var t:Number = 2;
public var x0:Number = 0;
public var y0:Number = 0;
public var colors:Vector.<uint> = new Vector.<uint>();
public const SX:Number = 2.6 / 500;
public const SY:Number = 2.6 / 500;
public function Mandelbrot() {
for (var i:int = 0; i < 360; i++)
colors[i] = !i? 0xFF000000 : new ColorHSV(i, 0.8, 1.4).value32;
}
public function getPixelsByCenter(x:Number, y:Number, scaleX:Number = 1, scaleY:Number = 1, width:int = 465, height:int = 465):Vector.<uint> {
var w:Number = SX / scaleX * width;
var h:Number = SY / scaleY * height;
return getPixels(new Rectangle(x - w / 2, y - h / 2, w, h), width, height);
}
public function getPixels(rect:Rectangle, width:int = 465, height:int = 465):Vector.<uint> {
var i:int = 0, w:int, h:int, n:int, m:Number, dx:Number, dy:Number, cx:Number, cy:Number, x1:Number, y1:Number, x2:Number, y2:Number;
var pixels:Vector.<uint> = new Vector.<uint>(width * height, true);
dx = rect.width / width, dy = rect.height / height;
cy = rect.y
for (h = height; h > 0; h--) {
cy += dy;
cx = rect.x;
for (w = width; w > 0; w--) {
cx += dx;
x1 = x0, y1 = y0;
for (n = iteration; n > 0 && (x1 * x1 + y1 * y1) <= 100; n--) {
m = y1? x1 / y1 : Number.MAX_VALUE;
x2 = x1 * x1 - y1 * y1 + cy * m;
y2 = t * x1 * y1 + cx;
x1 = x2, y1 = y2;
}
pixels[i++] = colors[n / iteration * colors.length | 0];
}
}
return pixels;
}
}