Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
ActionScript
/*fork from http://wonderfl.net/c/joNX/*/ package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.display.Stage; import flash.events.MouseEvent; import flash.events.TouchEvent; import flash.geom.Point; import flash.geom.Rectangle; /** * ... * @author ze */ [SWF(frameRate='60')] public class Main extends Sprite { //private var starling:Starling; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.BEST; var fd:FluidDrawer = new FluidDrawer(stage); addChild(fd); } } } import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.display.Stage; import flash.events.MouseEvent; import flash.events.TouchEvent; import flash.geom.Point; import flash.geom.Rectangle; class FluidDrawer extends Sprite { //public var h:Silks; //public var a:Object; //audio //public var b; //controls //public var c:Function; //public var e, f:int, g; //public static var silks:Silks; //public var c, e, f, j, g, k, C:*, m, n:Number, t, l:Number, p, r, E:Shape, u:Shape, zProperty, q, s, v, F; private var finalResult:Bitmap; private var bitmapData:BitmapData; private var targetSilk:Shape; //private var cntr:int = 0; private var stageRef:Stage; public function FluidDrawer(stageRef:Stage) { this.stageRef = stageRef; //addChild(this); bitmapData = new BitmapData(stageRef.stageWidth, stageRef.stageHeight, false, 0x0); finalResult = new Bitmap(bitmapData); addChild(finalResult); //this.stage = stageRef; var audio:Object, controls:Object, animateFunction:Function, /*e, f, g,*/ silks:Silks; var silkOne:Shape = new Shape(); var silkTwo:Shape = new Shape(); var sparks:Shape = new Shape(); //silkOne.cacheAsBitmap = true; //silkTwo.cacheAsBitmap = true; //sparks.cacheAsBitmap = true; targetSilk = silkOne; //this.addChild(silkOne); //this.addChild(silkTwo); this.addChild(sparks); silks = new Silks(stage, silkOne, silkTwo, sparks); //a = initAudio(); controls = initControls(silks, audio); //f = document.location.href.indexOf("?"); //- 1 < f ? (g = document.location.href.indexOf("&"), e = document.location.href.substring(f + 1), -1 < g && (e = e.substring(0, g - f - 1)), d("Loading silk", e), h.load(e)) : refreshCarbonAd(); var cntr:int = 0; animateFunction = function():int { var degree:Number = (cntr+=7) % 360; var angle:Number = degree / 180 * Math.PI; // var radius:Number = 300; //trace("angle: " + angle); var xPos:Number, yPos:Number; xPos = 500 + Math.sin(angle) * radius; yPos = 500 + Math.cos(angle) * radius; //simulateMouseMove(xPos, yPos); //silkOne.graphics.lineStyle(2, 0xFF0000, 1); //silkOne.graphics.drawRect(xPos, yPos, 3, 3); for (var i:int = 0; i < 2; i++) { controls.exist(); silks.exist(); } //a.modulateDrawSound(b.vmouse()); copyToBitmap(); return Global.requestAnimFrame(animateFunction); }; animateFunction(); //return ko.applyBindings(b.ui, $("#body")[0]) } private function copyToBitmap():void { var g:Graphics = targetSilk.graphics; var rect:Rectangle = new Rectangle(0, 0, targetSilk.width, targetSilk.height); //bitmapData.copyPixels(targetSilk.graphics, rect, new Point(0,0)); bitmapData.draw(targetSilk, null, null, BlendMode.ADD); //if (cntr % 20 == 0) //{ targetSilk.graphics.clear(); //} //cntr++; } private function simulateMouseMove(xPos:Number, yPos:Number):void { var b:Number, e:Number; //b = c.offset(); //e = c.x; //b.left; //b = c.y; //b.top; //trace("xPos: " + xPos + " yPos: " +yPos); n = xPos; t = yPos; } private var n:*, t:*; public function initControls(a:Silks, b:Object):Object { var c:Shape, e:*, f:*, j:*, g:*, k:*, h:*, C:*, isMouseDown:Boolean, l:*, p:*, r:*, startDraw:Function, w:Function, stopDraw:Function, E:*, u:*, z:*, q:*, s:*, v:String, F:Array; C = a.silkOne; E = a.silkTwo; u = a.sparksCanvas; initResizeHandler(C, E, u); l = n = u.width / 2; p = t = u.height / 2; z = q = s = 0; isMouseDown = false; r = null; C = !1; /*try { (h = new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) && (C = !0) } catch (K) { null != navigator.mimeTypes["application/x-shockwave-flash"] && (C = !0) }*/ c = u; startDraw = function():Boolean { //b.start(); isMouseDown = true; r = a.add(); //b.playDrawSound(); //k.ui.replayUrl(""); return false; } w = function(mevent:MouseEvent):void { var b:Number, e:Number; //b = c.offset(); e = c.x; //b.left; b = c.y; //b.top; n = mevent.localX - e; t = mevent.localY - b; } stopDraw = function():void { isMouseDown = false; a.complete(r); //return b.stopDrawSound() } var onTouchEnd:Function = function(e:TouchEvent):void { stopDraw(); } var onTouchMove:Function = function(e:TouchEvent):void { //'a' is the name of the original param: ...mousemove(function (a) {... ////w(a.originalEvent.touches[0] || a.originalEvent.changedTouches[0]); } var onTouchStart:Function = function(e:TouchEvent):void { //'a' is the name of the original param: ...mousemove(function (a) {... /*w(a.originalEvent.touches[0] || a.originalEvent.changedTouches[0]); l = n; p = t; D();*/ } var onMouseMove:Function = function(event:MouseEvent):void { //'a' is the name of the original param: ...mousemove(function (a) {... /*return*/ w(event); } var onMouseDown:Function = function(e:MouseEvent):void { /*if (1 === a.which) return*/ //k.ui.showAbout.value = false; startDraw(); } var onMouseUp:Function = function(e:MouseEvent):void { /*if (1 ===a.which) return*/ stopDraw(); } stageRef.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); stageRef.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); stageRef.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); stageRef.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchStart); stageRef.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stageRef.addEventListener(TouchEvent.TOUCH_END, onTouchEnd); k = { exist: function():void{ var b:Number; if (isMouseDown) { a.addPoint(r, n, t, n - l, t - p); q = l - n; s = p - t; b = q * q + s * s; z = 0 < b ? Global.sqrt(b) : 0 } else { q = s = z = 0; } l = n; p = t }, vmouse: function():Number { //mouse speed return z }, ui: {pristine: a.pristine, dirty: a.dirty, canUndo: a.canUndo, replayUrl: a.replayUrl, saving: a.saving, canClip: C, symmetry: new Observable(""), color: new Observable(""), setColor: function(a:*):* { k.ui.color(a); return b.blip() }, setSymmetry: function(a:*):* { return k.ui.symmetry(a) }, randomize: function():* { return a.setRandomParams() }, unrandomize: function():* { return a.unsetRandomParams() }, bloop: function():* { return b.bloop() }}}; g = {blue: "#3d95cc", green: "#53BD39", yellow: "#E3BF30", orange: "#EB5126", pink: "#dd4876", grey: "#555555"}; j = function():String { return g[k.ui.color.value()]; }; var outerSilks:Silks = a; (k.ui.color as Observable).addEventListener(Observable.VALUE_CHANGE, function(e:*):* { var currSilks:Silks = outerSilks; var colorName:String = k.ui.color.value; var colorValue:String = g[colorName]; currSilks.setRGB(colorValue); } ); /*for (f in g) h = g[f], $("#colors ." + f).css("background", h);*/ /*k.ui.symmetry.subscribe(function(b) { //sessionStorage.symmetryKind = b; switch (b) { case "none": return a.setSymmetryTypes(); case "vertical": return a.setSymmetryTypes("vertical"); case "both": return a.setSymmetryTypes("horizontal", "vertical", "diagonal") } });*/ (k.ui.symmetry as Observable).addEventListener(Observable.VALUE_CHANGE, function(e:*):* { switch (b) { case "none": return a.setSymmetryTypes(); case "vertical": return a.setSymmetryTypes("vertical"); case "both": return a.setSymmetryTypes("horizontal", "vertical", "diagonal") } } ); //k.ui.color(null != (v = sessionStorage.colorName) ? v : "blue"); k.ui.color.value = "blue"; //k.ui.symmetry(null != (F = sessionStorage.symmetryKind) ? F : "vertical"); k.ui.symmetry.value = "vertical"; /*key("x, space", function() { return k.ui.clear() }); key("u", function() { return k.ui.undo() });*/ return k; } public function initResizeHandler(... params):void { /*var a:Array, b:Function; a = (1 <= arguments.length ? y.call(arguments, 0) : []); b = function() { var b:Stage, e, f, j, g, k, h; h = []; g = 0; for (k = a.length; g < k; g++) { e = a[g]; b = e.getContext("2d"); j = e.width; f = e.height; f = b.getImageData(0, 0, j - 1, f - 1); b = stage; e.width = b.stageWidth; e.height = b.stageHeight; b = e.getContext("2d"); h.push(b.putImageData(f, 0, 0)); } return h }; b(); //return $(window).resize(b) */ } } //SILKS import flash.display.BlendMode; import flash.display.Shape; import flash.display.Sprite; import flash.display.Stage; import flash.events.IEventDispatcher; /** * ... * @author ze */ class Silks { public var silkOne:Shape; public var silkTwo:Shape; public var sparksCanvas:Shape; public var bufferCanvas:Shape; public var silkCanvas:Shape; public var silks:Object; public var time:Number; public var pristine:Observable; public var dirty:Observable; public var undoState:Observable; //this.tape = new Tape(this); //this.replay = new Tape(this); public var sparks:Sparks; public var replayUrl:Observable; public var saving:Observable; public var drawScale:Number; public var rgb:Array; public var symmetryTypes:*; private var stage:Stage; public function Silks(stage:Stage,silkOne:Shape, silkTwo:Shape, sparksCanvas:Shape) { this.stage = stage; //this.getPictureURL = G(this.getPictureURL, this); //this.toBlob = G(this.toBlob, this); //var e = this; this.silkOne = silkOne; this.silkTwo = silkTwo; this.silkCanvas = this.silkOne; this.bufferCanvas = this.silkTwo; this.sparksCanvas = sparksCanvas; this.silkTwo.visible = false; this.silks = {}; this.time = 0; this.pristine = new Observable(true); // ko.observable(!0); this.dirty = new Observable(false); //ko.observable(!1); this.undoState = new Observable(null); //ko.observable(null); /*this.canUndo = ko.computed(function() { return null != e.undoState() && !e.dirty() });*/ //this.tape = new Tape(this); //this.replay = new Tape(this); this.sparks = new Sparks(); this.replayUrl = new Observable("");//ko.observable(""); this.saving = new Observable(false);//ko.observable(!1); this.setRGB("dd4876"); //this.setSymmetryTypes("vertical"); this.setSymmetryTypes(); this.drawScale = 1; } public function canUndo():Boolean { return null != undoState && !dirty.value; } public function load(a:String):* { /*var b = this; $.ajax({type: "GET", url: "/v1/load", data: {id: a}, success: function(a) { a = JSON.parse(a); b.replay = new Tape(b); return b.replay.load(a) }}); return this.replayUrl("/?" + a)*/ return null; } public function save():* { /* var a, b = this; a = JSON.stringify(this.tape.get()); $.ajax({type: "POST", url: "/v1/save", data: {contents: a}, success: function(a) { b.replayUrl("/?" + a); return b.saving(!1) }}); return this.saving(!0)*/ return null; } public function toBlob():* { /*return this.silkCanvas.toBlob(function(a) { return saveAs(a, "silk.png") })*/ return null; } public function getPictureURL():String { /*var a, b, c, e, f, j; a = this.silkCanvas; c = a.getContext("2d"); j = a.width; f = a.height; e = c.getImageData(0, 0, j, f); b = c.globalCompositeOperation; c.globalCompositeOperation = "destination-over"; c.fillStyle = "#000"; c.fillRect(0, 0, j, f); a = a.toDataURL("image/png"); c.clearRect(0, 0, j, f); c.putImageData(e, 0, 0); c.globalCompositeOperation = b; return a*/ return ""; } public function swapSilkCanvii():void { trace("3: swap"); this.silkCanvas === this.silkOne ? (this.bufferCanvas = this.silkOne, this.silkCanvas = this.silkTwo) : (this.silkCanvas = this.silkOne, this.bufferCanvas = this.silkTwo); var bufferCanvasChildIdx:int = silkCanvas.parent.getChildIndex(bufferCanvas); silkCanvas.parent.setChildIndex(silkCanvas, bufferCanvasChildIdx); //$(this.silkCanvas).insertBefore($(this.bufferCanvas)); //$(this.silkCanvas).addClass("active"); //return $(this.bufferCanvas).removeClass("active") } public function add(a:*=null, b:*=null, c:*=null, e:*=null, f:*=null, j:*=null):Number { var g:Silk; (null == a && (a = (new Date).getTime())); (null == b && (b = this.rgb)); (null == c && (c = this.symmetryTypes)); (null == e && (e = this.silkCanvas.width)); (null == f && (f = this.silkCanvas.height)); (null == j && (j = Global.randrange(0, 1E6) | 0)); //this.tape.recStart(); //this.tape.rec("add", a, b, c, e, f, j); this.silks[a] = new Silk(stage, this.silkCanvas, e, f, j); g = this.silks[a] as Silk; g.drawScale = this.drawScale; g.setRGB.apply(g, b); g.setSymmetryTypes(c); this.dirty.value=true; this.pristine.value = false; return a; } public function addPoint(a:Number, b:Number, c:Number, e:Number, f:Number):void { //this.tape.rec("addPoint", a, b, c, e, f); var j:Silk = this.silks[a] as Silk; if (j != null) { j.add2(b, c, e, f); } } public function complete(a:Number):void { var b:Boolean, c:Silk, e:Object; if (null != this.silks[a] && !this.silks[a].completed) { /*this.tape.rec("complete", a);*/ this.silks[a].complete(); b = true; e = this.silks; for (var key:String in e) if (c = e[key], !c.completed) { b = !1; break } /*if (b && (this.tape.recStop(), 10 < this.tape.time - this.tape.startedTime)) return this.tape.advance(15) */ } } public function clear():void { var a:*, b:Object; if (this.dirty.value) { /*b = this.tape.eject(); this.replay.eject();*/ this.undoState.value={time: this.time, tapeContents: b, replayUrl: this.replayUrl.value}; this.replayUrl.value = ""; b = this.silks; for (a in b) this.complete(a); this.silks = {}; this.dirty.value = false; this.time = 0; //a = this.bufferCanvas.getContext("2d"); //a.clearRect(0, 0, this.bufferCanvas.width, this.bufferCanvas.height); this.bufferCanvas.graphics.clear(); //$(this.silkCanvas).addClass("hidden"); //$(this.bufferCanvas).removeClass("hidden"); this.silkCanvas.visible = false; this.bufferCanvas.visible = true; this.swapSilkCanvii(); } this.sparks.addClear(this.sparksCanvas, 100); } public function undoClear():void { var a:*; if (this.canUndo()) { a = this.undoState.value; this.time = a.time; //this.tape.load(a.tapeContents); this.replayUrl.value = a.replayUrl; this.undoState.value = null; this.dirty.value = true; //$(this.bufferCanvas).removeClass("hidden"); this.bufferCanvas.visible = true; this.swapSilkCanvii(); this.sparks.addClear(this.sparksCanvas, 100, -1); } } public function exist():int { var a:String, b:Silk, c:Shape, e:Shape, f:int, j:Object; c = this.silkCanvas//.getContext("2d"); e = this.sparksCanvas//.getContext("2d"); //c.globalCompositeOperation = "lighter"; //c.blendMode = BlendMode.DARKEN; j = this.silks; for (a in j) { if (b = j[a], b.alive) { //trace("silk alive: " + b.alive + " " + b); this.sparks.addFromSilk(b); for (f = 1; 6 >= f; ++f) { b.exist(c); } b.tick(); } else { trace("delete silk"); delete this.silks[a]; } } //e.clearRect(0, 0, this.sparksCanvas.width, this.sparksCanvas.height); e.graphics.clear(); this.sparks.exist(e); //this.replay.play(); //this.tape.recording && this.tape.tick(); //this.replay.tick(); return this.tick() } public function tick():int { return this.time += 1 } public function setRandomParams(a:Object=null):void { (null == a && (a = Silk.randomParams())); Silk.setDefaultParams(a) } public function unsetRandomParams():void { return Silk.resetDefaultParams(); } public function setSymmetryTypes(...params):* { var arr:Array = params as Array; if (params.length >= 1) { this.symmetryTypes = params.slice(0); } else { this.symmetryTypes = []; } return this.symmetryTypes; //return null; } public function setRGB(a:String):Array { return this.rgb = Global.hexToRGB(a) } } //GLOBAL import flash.utils.clearTimeout; import flash.utils.setTimeout; /** * ... * @author ze * AS3 version of http://new.weavesilk.com/ */ class Global { //this.SilkDomain = "http://new.weavesilk.com"; //extend function /** public static function h(a:*, b:Array):* { function c() { this.constructor = a } for (var e in b) J.call(b, e) && (a[e] = b[e]); c.prototype = b.prototype; a.prototype = new c; a.__super__ = b.prototype; return a }**/ //~bind function public static function G(a:*, b:Array):* { return function():* { return a.apply(b, arguments); } } public static var J:Function = Object.prototype.hasOwnProperty; public static var y:Function = Array.prototype.slice; public static var min:Function = Math.min; public static var max:Function = Math.max; public static var rand:Function = Math.random; public static var abs:Function = Math.abs; public static var round:Function = Math.round; public static var floor:Function = Math.floor; public static var ceil:Function = Math.ceil; public static var log:Function = Math.log; public static var pow:Function = Math.pow; public static var sin:Function = Math.sin; public static var cos:Function = Math.cos; public static var sqrt:Function = Math.sqrt; public static var atan2:Function = Math.atan2; public static var Pi:Number = Math.PI; public static var TwoPi:Number = 2 * Pi; public static var HalfPi:Number = Pi / 2; public static var QuarterPi:Number = Pi / 4; public static var EighthPi:Number = Pi / 8; public static var E:Number = Math.E; public static var Epsilon:Number = 1E-4; public static var Paused:Boolean = false; public static function hexToRGB(input:String):Array { var a:int; var c:int; var b:Array = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.exec(input).slice(1); var e:Array = []; for (a = c = 0; 2 >= c; a = ++c) e.push(parseInt(b[a], 16)); return e; } public static function brightenRGB(a:int, b:int, c:int, e:Number):Array { return [floor(min(255, a + 255 * e)), floor(min(255, b + 255 * e)), floor(min(255, c + 255 * e))] } public static function contrain(a:Number, b:Number, c:Number):Number { //returns x where b<=x(=a)<=c return a > c ? c : a < b ? b : a } public static function randrange(a:Number, b:Number):Number { //returns random number(=x) between a and b (a.....x...b) return a + rand() * (b - a); } public static var H:int = 0; //some kind of counter... public static function autoinc():void { H++; } public static function d(params:*):void { //debug function trace(params); /*this.d = function () { return "undefined" !== typeof console && null !== console ? console.log.apply(console, Array.prototype.slice.call(arguments)) : void 0 };*/ } /*this.requestAnimationFrame || this.webkitRequestAnimationFrame || this.mozRequestAnimationFrame || this.oRequestAnimationFrame || this.msRequestAnimationFrame ||*/ public static function requestAnimFrame(a:Function):int { var delayMsec:int = 1E3 / 60; return setTimeout(a, delayMsec); }; /* this.cancelAnimationFrame || this.webkitCancelAnimationFrame || this.mozCancelAnimationFrame || this.oCancelAnimationFrame || this.msCancelAnimationFrame ||*/ public var cancelAnimFrame:Function = clearTimeout; } //OBSEVABLE import flash.events.Event; import flash.events.EventDispatcher; /** * ... * @author ze */ class Observable extends EventDispatcher { public static var VALUE_CHANGE:String = "onChanged"; private var currentValue:*; public function Observable(initValue:*) { currentValue = initValue; } public function get value():* { return currentValue; } public function set value(newValue:*):void { currentValue = newValue; dispatchEvent(new Event(VALUE_CHANGE)); } } //PARTICLES import flash.display.Shape; /** * ... * @author ze */ class Particles { public var maxParticles:int; public var start:int = 0; public var end:int = 0; public var all:Array; public function Particles(maxParticles:Number) { this.maxParticles = (!isNaN(maxParticles) ? maxParticles : 500); this.start = this.end = 0; this.all = new Array(this.maxParticles); this.all.length = this.maxParticles; //should have the same effect.. } public function newParticle():Object { return {age: 0, alive: true}; } public function shouldNotExist():Boolean { return this.start === this.end } public function exist(a:Shape):* { for (; !(this.start === this.end || this.all[this.start].alive); ) { this.all[this.start] = null, this.start = this.inc(this.start); } if (!this.shouldNotExist()) { return this.foreach(function(a:Object):Boolean { a.px = a.x; a.py = a.y; a.age += 1; return this.update(a) }), this.drawAll(a); //the drawAll() result will be returned! } return []; } protected var drawStart:Function; protected var drawEnd:Function; protected var symmetries:Array = null; public function drawAll(a:Shape):Array { //NO OP //return []; var b:*, c:int, e:int, f:Array, j:Array; if (!this.shouldNotExist() && (drawStart!=null && drawStart(a), this.foreach(function (b:*):* { if (b.alive) return this.draw(b, a) }), drawEnd!=null && drawEnd(a), this.symmetries)) { f = this.symmetries; j = []; c = 0; for (e = f.length; c < e; c++) { b = f[c]; this.foreach(b.trans); drawStart != null && drawStart(a), this.foreach(function (b:*):* { if (b.alive) return this.draw(b, a) }), drawEnd != null && drawEnd(a), j.push(this.foreach(b.inv)); } return j } return []; } public function foreach(funct:Function):void { var b:int; for (b = this.start; b !== this.end; ) funct.call(this, this.all[b]), b = this.inc(b) } public function add(xPos:Number, yPos:Number):Object { var c:int; var e:Object; c = this.inc(this.end); this.start === c && (this.start = this.inc(this.start)); e = newParticle(); e.x = xPos; e.y = yPos; this.all[this.end] = e; this.end = c; return e; } public function inc(a:int):int { return (a + 1) % this.maxParticles } public function dec(a:int):int { return (a - 1) % this.maxParticles; } } //SPARKS import flash.display.ShaderParameter; import flash.display.Shape; /** * ... * @author ze */ class Sparks extends Particles { public function Sparks(maxParticles:Number=Number.NaN) { super(maxParticles); } override public function newParticle():Object { var obj:Object = super.newParticle(); obj.r = 255; obj.g = 255; obj.b = 255; obj.maxA = 1; obj.radius = 0.75; obj.vx = Global.randrange( -1, 1); obj.vy = Global.randrange( -1, 0); obj.dieAt = 25; obj.fadeIn = false; return obj; } public function update(a:Object):Boolean { var b:Number; a.x += a.vx; a.y += a.vy; b = 1 - a.age / a.dieAt; a.a = a.fadeIn ? a.maxA * Global.sin(Global.Pi * b) : b; ///a.color = "rgba(" + a.r + ", " + a.g + ", " + a.b + ", " + a.a + ")"; //TODO: fix this! a.color = { r:a.r, g:a.g, b:a.b, a:a.a }; return a.alive && (a.alive = a.age < a.dieAt) } public function draw(a:Object, b:Shape):void { if (a.alive) { //b.beginPath(); //b.fillStyle = a.color; var tmpColor:int = ((a.color.r & 0xff) << 16) + ((a.color.g & 0xff) << 8) + (a.color.b & 0xff); b.graphics.beginFill(tmpColor, a.color.a); b.graphics.drawCircle(a.x, a.y, a.radius);// = b.arc(a.x, a.y, a.radius, 0, Global.TwoPi, !1); b.graphics.endFill(); //b.fill(); //b.closePath(); } } public function addFromSilk(a:Silk):void { var b:Sparks = this; a.foreach(function(c:Object):void { var e:Array; if (0.03 > Global.rand()) { c = b.add(c.x, c.y); e = a.sparkRGB; c.r = e[0]; c.g = e[1]; c.b = e[2]; e } }) } public function addClear (a:Shape, b:*, c:*=null):void { var e:Number, f:Number, j:Number, B:Number, k:*, g:int; (null == b && (b = 100)); (null == c && (c = 1)); f = a.width / 2; j = a.height / 2; for (g = 1; 1 <= b ? g <= b : g >= b; 1 <= b ? ++g : --g) { B = Global.randrange(0, a.width); k = Global.randrange(0, a.height); e = Global.atan2(k - j, B - f); e += Global.randrange( -Global.QuarterPi, Global.QuarterPi); k = this.add(B, k); B = 0.25 * c; k.vx = B * Global.cos(e); k.vy = B * Global.sin(e); k.dieAt = Global.randrange(25, 85); } } } //SILK import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Shape; import flash.display.Stage; /** * ... * @author ze */ class Silk extends Particles { public var canvas:Shape; public var width:int; public var height:int; public var seed:Number; public var offx:Number; public var offy:Number; public var perlin:PerlinNoise; private var stage:Stage; public var age:int; public var completed:Boolean; public var alive:Boolean; public var color:Object; public var sparkRGB:Array; public var num:int; //public var symmetries:Array; //props public var noiseOctaves:int; public var noiseFallout: Number; public var noiseScale: Number; public var wind:Boolean; public var windAngle:Number; public var windForce:Number; public var friction:Number; public var springLength:Number; public var rigidity:Number; public var reverseMouseVelocity:Boolean; public var mouseDamp:Number; public var drawScale:int = 1; private var prevParticle:Object; public function Silk(stage:Stage, a:Shape, width:int, height:int, seed:Number) { this.canvas = a; this.width = width; this.height = height; this.seed = seed; super(Number.NaN); //g.__super__.constructor.call(this); this.offx = 0;//(this.width - stage.stageWidth) / 2; this.offy = 0;//(this.height - stage.stageHeight) / 2; this.age = 0; this.alive = true; this.completed = false; this.setParams(defaultParams); this.perlin = new PerlinNoise(0); this.color = {r: 255, g: 255, b: 255, a: 0.07}; this.sparkRGB = [255, 255, 255]; this.num = 0; this.drawStart = drawStartX; this.drawEnd = drawEndX; } public function setSymmetryTypes(a:Array):void { var c:int; var e:*; var b:*; var j:Silk = this; var f:Array = []; c = 0; for (e = a.length; c < e; c++) switch (b = a[c], b) { case "vertical": f.push({trans: function(a:*):Number { return a.x = j.canvas.width - a.x }}); break; case "horizontal": f.push({trans: function(a:*):Number { return a.y = j.canvas.height - a.y }}); break; case "diagonal": f.push({trans: function(a:*):Number { a.x = j.canvas.width - a.x; return a.y = j.canvas.height - a.y }}); break; default: f.push(void 0) } e = this.symmetries = f; b = 0; for (c = e.length; b < c; b++) { var obj:* = e[b]; if (obj.inv == null) { obj.inv = obj.trans; } } } override public function newParticle():Object { /*return $.extend(g.__super__["new"].call(this), { accx: 0, accy: 0, friction: this.friction, mass: 1, springLength: this.springLength, rigidity: this.rigidity, death: 250 })*/ var obj:Object = super.newParticle(); obj.accx = 0; obj.accy = 0, obj.friction = this.friction; obj.mass = 1; obj.springLength = this.springLength; obj.rigidity = this.rigidity; obj.death = 250; return obj; } public function add2(aa:Number, bb:Number, c:Number, e:Number):Object { //TODO: test this! var f:*; f = (this.start === this.end); var a:Object = super.add(aa - this.offx, bb - this.offy); f || (this.prevParticle.next = a); f = this.mouseDamp; this.reverseMouseVelocity && (f *= -1);//ha reverse, akkor -1xf a.vmx = c * f; a.vmy = e * f; a.num = this.num++; return (this.prevParticle = a); } override public function shouldNotExist():Boolean { return super.shouldNotExist() || !this.alive } override public function exist(a:Shape):* { var start:Number = new Date().getTime(); super.exist(a); if (this.completed && (this.color.a -= 5E-4, this.color.a < Global.Epsilon)) { return this.die(); } //return; //TODO: wrong return value? var end:Number = new Date().getTime(); //trace("2: silks exist duration: " + (end - start)); } //private var updateccntr:Number=0; public function update(a:Object):Boolean { //updateccntr++; //if (updateccntr % 100 == 0) trace("3: updateccntr: " + updateccntr); var b:Number, c:Number; Noise.noiseDetail(this.noiseOctaves, this.noiseFallout); c = 2 * Global.TwoPi * Noise.noise((a.x + this.offx) * this.noiseScale, (a.y + this.offy) * this.noiseScale, this.seed + 0.008 * this.age, this.perlin); c *= 2; b = Global.Pi / 2; (0 !== a.vmx || 0 !== a.vmy) && Global.atan2(a.vmx, a.vmy); this.addAngleForce(a, c + b, 1); this.addForce(a, a.vmx, a.vmy); a.vmx *= 0.99; a.vmy *= 0.99; a.rigidity *= 0.999; this.wind && this.addAngleForce(a, this.windAngle, this.windForce); null != a.next && (this.move(a), this.constrain(a)); return a.alive && (a.alive = a.age < a.death) } public function move(a:Object):Number { a.x += (a.x - a.px) * a.friction + a.accx; a.y += (a.y - a.py) * a.friction + a.accy; return a.accx = a.accy = 0 } public function addForce(a:Object, b:Number, c:Number):Number { a.accx += b / a.mass; return a.accy += c / a.mass } public function addAngleForce(a:Object, b:Number, c:Number):Number { c /= a.mass; a.accx += c * Global.cos(b); return a.accy += c * Global.sin(b) } public function addPosition(a:Object, b:Number, c:Number):Number { a.x += b; return a.y += c; } public function constrain(a:Object):Number { var b:Number, c:Number, e:Number; c = a.next.x - a.x; e = a.next.y - a.y; b = Math.sqrt(c * c + e * e); if (0 !== b && (b = 1 - a.springLength / b, c = a.rigidity * c * b, e = a.rigidity * e * b, this.addPosition(a, c, e), null != a.next.next)) return this.addPosition(a.next, -c, -e) return 0; //added by me } public function drawStartX(a:Shape):void { var b:Object; //a.beginPath(); //not needed //added by ze var tmpColor:int = ((this.color.r & 0xff) << 16) + ((this.color.g & 0xff) << 8) + (this.color.b & 0xff); a.graphics.lineStyle(this.drawScale*1, tmpColor, this.color.a,true); //end b = this.all[this.start]; if (this.drawScale === 1) { a.graphics.moveTo(b.x * this.drawScale, b.y * this.drawScale); } else { a.graphics.moveTo((b.x - stage.stageWidth / 2) * this.drawScale + stage.stageWidth / 2, (b.y - stage.stageHeight / 2) * this.drawScale + stage.stageHeight / 2); } } public function draw(a:Object, b:Shape):void { var c:Number, e:Number, f:*, j:Number; f = a.next; if (null != (null != f ? f.next : void 0)) { if (1 === this.drawScale) { b.graphics.curveTo(a.x * this.drawScale, a.y * this.drawScale, (a.x * this.drawScale + f.x * this.drawScale) / 2, (a.y * this.drawScale + f.y * this.drawScale) / 2); return; } c = (a.x - stage.stageWidth / 2) * this.drawScale + stage.stageWidth / 2; e = (a.y - stage.stageHeight / 2) * this.drawScale + stage.stageHeight / 2; j = (f.x - stage.stageWidth / 2) * this.drawScale + stage.stageWidth / 2; f = (f.y - stage.stageHeight / 2) * this.drawScale + stage.stageHeight / 2; b.graphics.curveTo(c, e, (c + j) / 2, (e + f) / 2) return; } } public function drawEndX(a:Shape):void { //var tmpColor:int = ((this.color.r & 0xff) << 16) + ((this.color.g & 0xff) << 8) + (this.color.b & 0xff); //a.graphics.lineStyle(this.drawScale,tmpColor,this.color.a,true); //a.lineWidth = this.drawScale; //a.strokeStyle = "rgba(" + this.color.r + ", " + this.color.g + ", " + this.color.b + ", " + this.color.a + ")"; //a.stroke(); //return a.closePath() //NO OP } /* override public function drawAll(a:Shape):Array { var b:*, c:int, e:int, f:Array, j:Array; if (!this.shouldNotExist() && (this.drawStart(a), this.foreach(function (b:Object):void { if (b.alive) this.draw(b, a) }), this.drawEnd(a), this.symmetries)) { f = this.symmetries; j = []; c = 0; for (e = f.length; c < e; c++) b = f[c], this.foreach(b.trans), this.drawStart(a), this.foreach(function (b:Object):void { if (b.alive) this.draw(b, a) }), this.drawEnd(a), j.push(this.foreach(b.inv)); return j } return []; }*/ public function setParams(a:Object):void { for (var key:String in a) { this[key] = a[key]; } //return $.extend(this, a) } public function setRGB(a:int, b:int, c:int):Array { this.color.r = a; this.color.g = b; this.color.b = c; return this.sparkRGB = Global.brightenRGB(a, b, c, 0.3) } public function tick():int { return this.age += 1; } public function complete():Boolean { return this.completed = true; } public function die():Boolean { return this.alive = false; } private static var originalParams:Object = {noiseOctaves: 8, noiseFallout: 0.65, noiseScale: 0.01, wind: !1, windAngle: -Global.Pi, windForce: 0.75, friction: 0.975, springLength: 0, rigidity: 0.3, reverseMouseVelocity: false, mouseDamp: 0.2}; public static function randomParams():Object { return {noiseOctaves: Global.randrange(2, 9), noiseFallout: Global.randrange(0.25, 1), noiseScale: Global.randrange(0.001, 0.1), wind: 0.5 > Global.rand(), windAngle: Global.randrange(0, Global.TwoPi), windForce: Global.randrange(0.5, 1), friction: Global.randrange(0, 1), springLength: Global.randrange(0, 20), rigidity: Global.randrange(0, 1), reverseMouseVelocity: 0.5 > Global.rand(), mouseDamp: Global.randrange(0, 1)} } private static var defaultParams:Object = originalParams; public static function setDefaultParams(a:Object):void { defaultParams = a; } public static function resetDefaultParams():void { setDefaultParams(originalParams); } } //PERLINNOISE import flash.utils.ByteArray; /** * ... * @author ze */ class PerlinNoise { private var perm:ByteArray; function PerlinNoise(seed:Number) { var rnd:Marsaglia = (!isNaN(seed) ? new Marsaglia(seed,0) : Marsaglia.createRandomized()); var i:int var j:int; // http://www.noisemachine.com/talk1/17b.html // http://mrl.nyu.edu/~perlin/noise/ // generate permutation perm = new ByteArray(); //new Uint8Array(512); perm.length = 512; for (i = 0; i < 256; ++i) { perm[i] = i; } for (i = 0; i < 256; ++i) { var t:int = perm[j = rnd.nextInt() & 0xFF]; perm[j] = perm[i]; perm[i] = t; } // copy to avoid taking mod in perm[0]; for (i = 0; i < 256; ++i) { perm[i + 256] = perm[i]; } } public function noise3d(x:Number, y:Number, z:Number):Number { //var X = Math.floor(x)&255, Y = Math.floor(y)&255, Z = Math.floor(z)&255; //x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z); var X:int = (x | 0) & 255, Y:int = (y | 0) & 255, Z:int = (z | 0) & 255; x -= (x | 0); y -= (y | 0); z -= (z | 0); var fx:Number = (3 - 2 * x) * x * x, fy:Number = (3 - 2 * y) * y * y, fz:Number = (3 - 2 * z) * z * z; var p0:int = perm[X] + Y, p00:int = perm[p0] + Z, p01:int = perm[p0 + 1] + Z, p1:int = perm[X + 1] + Y, p10:int = perm[p1] + Z, p11:int = perm[p1 + 1] + Z; return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))); } public function noise2d(x:Number, y:Number):Number { var X:int = Math.floor(x) & 255, Y:int = Math.floor(y) & 255; x -= Math.floor(x); y -= Math.floor(y); var fx:Number = (3 - 2 * x) * x * x, fy:Number = (3 - 2 * y) * y * y; var p0:Number = perm[X] + Y, p1:Number = perm[X + 1] + Y; return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))); } public function noise1d(x:Number):Number { var X:int = Math.floor(x) & 255; x -= Math.floor(x); var fx:Number = (3 - 2 * x) * x * x; return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)); } // TODO: Benchmark public function grad3d(i:int, x:Number, y:Number, z:Number):Number { var h:int = i & 15; // convert into 1 2 gradient directions // var u = h<8 ? x : y, // v = h<4 ? y : h===12||h===14 ? x : z; // return ((h&1) === 0 ? u : -u) + ((h&2) === 0 ? v : -v); // Optimization from // http://riven8192.blogspot.com/2010/08/calculate-perlinnoise-twice-as-fast.html // // inline float grad(int hash, float x, float y, float z) // { //float u = (h < 8) ? x : y; //float v = (h < 4) ? y : ((h == 12 || h == 14) ? x : z); //return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); switch (h & 0xF) { case 0x0: return x + y; case 0x1: return -x + y; case 0x2: return x - y; case 0x3: return -x - y; case 0x4: return x + z; case 0x5: return -x + z; case 0x6: return x - z; case 0x7: return -x - z; case 0x8: return y + z; case 0x9: return -y + z; case 0xA: return y - z; case 0xB: return -y - z; case 0xC: return y + x; case 0xD: return -y + z; case 0xE: return y - x; case 0xF: return -y - z; default: return 0; // never happens } } public function grad2d(i:int, x:Number, y:Number):Number { var v:Number = (i & 1) === 0 ? x : y; return (i & 2) === 0 ? -v : v; } public function grad1d(i:int, x:Number):Number { return (i & 1) === 0 ? -x : x; } public function lerp(t:Number, a:Number, b:Number):Number { return a + t * (b - a); } } //MARSAGLIA class Marsaglia { // Pseudo-random generator private var z:int; private var w:int; public function Marsaglia(i1:Number, i2:Number) { // from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c z = i1 || 362436069 w = i2 || 521288629; } public function nextInt():int { z = (36969 * (z & 65535) + (z >>> 16)) & 0xFFFFFFFF; w = (18000 * (w & 65535) + (w >>> 16)) & 0xFFFFFFFF; return (((z & 0xFFFF) << 16) | (w & 0xFFFF)) & 0xFFFFFFFF; } public function nextDouble():Number { var i:Number = nextInt() / 4294967296.0; return i < 0 ? 1 + i : i; } public static function createRandomized():Marsaglia { var now:int = new Date().getTime(); return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF); } } //NOISE class Noise { //private static var undef:Object=new Object(); // Noise functions and helpers // processing defaults public static var noiseProfile:Object = {generator: null, octaves: 4, fallout: 0.5, seed: null}; /** * Returns the Perlin noise value at specified coordinates. Perlin noise is a random sequence * generator producing a more natural ordered, harmonic succession of numbers compared to the * standard random() function. It was invented by Ken Perlin in the 1980s and been used since * in graphical applications to produce procedural textures, natural motion, shapes, terrains etc. * The main difference to the random() function is that Perlin noise is defined in an infinite * n-dimensional space where each pair of coordinates corresponds to a fixed semi-random value * (fixed only for the lifespan of the program). The resulting value will always be between 0.0 * and 1.0. Processing can compute 1D, 2D and 3D noise, depending on the number of coordinates * given. The noise value can be animated by moving through the noise space as demonstrated in * the example above. The 2nd and 3rd dimension can also be interpreted as time. * The actual noise is structured similar to an audio signal, in respect to the function's use * of frequencies. Similar to the concept of harmonics in physics, perlin noise is computed over * several octaves which are added together for the final result. * Another way to adjust the character of the resulting sequence is the scale of the input * coordinates. As the function works within an infinite space the value of the coordinates * doesn't matter as such, only the distance between successive coordinates does (eg. when using * noise() within a loop). As a general rule the smaller the difference between coordinates, the * smoother the resulting noise sequence will be. Steps of 0.005-0.03 work best for most applications, * but this will differ depending on use. * * @param {float} x x coordinate in noise space * @param {float} y y coordinate in noise space * @param {float} z z coordinate in noise space * * @returns {float} * * @see random * @see noiseDetail */ public static function noise(x:Number, y:Number, z:Number, generator:PerlinNoise):Number { // if(noiseProfile.generator === undef) { // // caching // noiseProfile.generator = new PerlinNoise(noiseProfile.seed); // } // var generator = noiseProfile.generator; var effect:Number = 1, k:Number = 1, sum:Number = 0; for (var i:int = 0; i < noiseProfile.octaves; ++i) { effect *= noiseProfile.fallout; // Yuriedit // switch (arguments.length) { // case 2: // sum += effect * (1 + generator.noise1d(k*x))/2; break; // case 3: // sum += effect * (1 + generator.noise2d(k*x, k*y))/2; break; // case 4: sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; // break; // } k *= 2; } return sum; } /** * Adjusts the character and level of detail produced by the Perlin noise function. * Similar to harmonics in physics, noise is computed over several octaves. Lower octaves * contribute more to the output signal and as such define the overal intensity of the noise, * whereas higher octaves create finer grained details in the noise sequence. By default, * noise is computed over 4 octaves with each octave contributing exactly half than its * predecessor, starting at 50% strength for the 1st octave. This falloff amount can be * changed by adding an additional function parameter. Eg. a falloff factor of 0.75 means * each octave will now have 75% impact (25% less) of the previous lower octave. Any value * between 0.0 and 1.0 is valid, however note that values greater than 0.5 might result in * greater than 1.0 values returned by noise(). By changing these parameters, the signal * created by the noise() function can be adapted to fit very specific needs and characteristics. * * @param {int} octaves number of octaves to be used by the noise() function * @param {float} falloff falloff factor for each octave * * @see noise */ public static function noiseDetail(octaves:int, fallout:Number):void { noiseProfile.octaves = octaves; if (!isNaN(fallout)) { noiseProfile.fallout = fallout; } } /** * Sets the seed value for noise(). By default, noise() produces different results each * time the program is run. Set the value parameter to a constant to return the same * pseudo-random numbers each time the software is run. * * @param {int} seed int * * @returns {float} * * @see random * @see radomSeed * @see noise * @see noiseDetail */ public static function noiseSeed(seed:Number):void { noiseProfile.seed = seed; noiseProfile.generator = null; } }
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email