In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Port jsdo.it/hakim/magnetic-02

Ported from http://jsdo.it/hakim/magnetic-02
Get Adobe Flash player
by smirnov48 31 Aug 2010
/**
 * Copyright smirnov48 ( http://wonderfl.net/user/smirnov48 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/Aiv2
 */

/**
 * Ported from http://jsdo.it/hakim/magnetic-02
  */
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.utils.getTimer;
    
    public class Main extends Sprite 
    {        
        private var MAGNETS_AT_START:int = 4;
        private var PARTICLES_PER_MAGNET:int = 20;
        private var MAGNETIC_FORCE_THRESHOLD:int = 300;
        
        private var particles:Array = new Array();
        private var magnets:Array = new Array();
        
        private var mouseIsDown:Boolean = false;
        private var mouseDownTime:int = 0;
        
        private var particle:Particle; 
        private var magnet:Magnet;
        private var i:int;
        private var j:int;
        private var ilen:int;
        private var jlen:int;
        private var len:int;
        
        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);
            // entry point
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, documentMouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, documentMouseUpHandler);
            
            createMagnets();
            
            addEventListener(Event.ENTER_FRAME, loop);
        }
        
        private function createMagnets():void {
            var w:int = 300;
            var h:int = 300;

            for (var i:int = 0; i < MAGNETS_AT_START; i++) {
                var position:Object = {
                    x: (stage.stageWidth - w) * 0.5 + (Math.random() * w),
                    y: (stage.stageHeight - h) * 0.5 + (Math.random() * h)
                };
                
                createMagnet(position);
            }
        }

        private function createMagnet(position:Object):void {
            var m:Magnet = new Magnet();
            m.position.x = position.x;
            m.position.y = position.y;
            
            magnets.push(m);
            
            createParticles(m.position);
        }

        private function createParticles( position:Object ):void {
            for (i = 0; i < PARTICLES_PER_MAGNET; i++) {
                var p:Particle = new Particle();
                p.position.x = position.x;
                p.position.y = position.y;
                p.shift.x = position.x;
                p.shift.y = position.y;
                
                particles.push(p);
            }
        }
    
        private function documentMouseDownHandler(event:MouseEvent):void {
            event.preventDefault();
            mouseIsDown = true;
            
            if (getTimer() - mouseDownTime < 300) {
                // The mouse was pressed down twice with a < 300 ms interval: add a magnet
                createMagnet( {x:mouseX, y:mouseY} );
                mouseDownTime = 0;
            }

            mouseDownTime = getTimer();
            
            len = magnets.length
            for (i = 0; i < len; i++) {
                magnet = magnets[i];
                
                if (distanceBetween(magnet.position, { x: mouseX, y: mouseY }) < magnet.orbit * .5) {
                    magnet.dragging = true;
                    break;
                }
            }
        }

        private function documentMouseUpHandler(event:MouseEvent):void {
            mouseIsDown = false;
            
            len = magnets.length
            for (i = 0; i < len; i++) {
                magnet = magnets[i];
                magnet.dragging = false;
            }
        }
        
        private function loop(e:Event):void {
            graphics.clear();
            
            // Render the magnets
            for (j = 0, jlen = magnets.length; j < jlen; j++) {
                magnet = magnets[j];
                
                if (magnet.dragging) {
                    magnet.position.x += (mouseX - magnet.position.x) * 0.2;
                    magnet.position.y += (mouseY - magnet.position.y) * 0.2;
                }
                    
                // Increase the size of the magnet center point depending on # of connections
                magnet.size += ((magnet.connections/3) - magnet.size) * 0.05;
                magnet.size = Math.max(magnet.size, 2);
                
                graphics.lineStyle(0, 0xFF00FF, 0);
                graphics.beginFill(0xFF00FF, 0.4);
                graphics.drawCircle(magnet.position.x, magnet.position.y, magnet.size * 10);
                graphics.endFill();
                
                graphics.lineStyle(0, 0x0000FF, 0);
                graphics.beginFill(0x0000FF, 0.4);
                graphics.drawCircle(magnet.position.x, magnet.position.y, magnet.size);
                graphics.endFill();
                
                magnet.connections = 0;
            }

            // Render the particles
            for (i = 0, ilen = particles.length; i < ilen; i++) {
                particle = particles[i];

                var currentDistance:Number = -1;
                var closestDistance:Number = -1;
                var closestMagnet:Magnet = null;

                var force:Object = {x:0, y:0};

                    // For each particle, we check what the closes magnet is
                    for (j = 0, jlen = magnets.length; j < jlen; j++) {
                        magnet = magnets[j];
                        
                        currentDistance = distanceBetween(particle.position, magnet.position) - (magnet.orbit * 0.5);
                        
                        if (particle.magnet != magnet) {
                            var fx:Number = magnet.position.x - particle.position.x;
                            if (fx > -MAGNETIC_FORCE_THRESHOLD && fx < MAGNETIC_FORCE_THRESHOLD) {
                                force.x += fx / MAGNETIC_FORCE_THRESHOLD;
                            }
                            
                            var fy:Number = magnet.position.y - particle.position.y;
                            if (fy > -MAGNETIC_FORCE_THRESHOLD && fy < MAGNETIC_FORCE_THRESHOLD) {
                                force.y += fy / MAGNETIC_FORCE_THRESHOLD;
                            }
                            
                        }

                        if (closestMagnet == null || currentDistance < closestDistance) {
                            closestDistance = currentDistance;
                            closestMagnet = magnet;
                        }
                    }

                if (particle.magnet == null || particle.magnet != closestMagnet) {
                    particle.magnet = closestMagnet;
                }

                closestMagnet.connections += 1;

                // Rotation
                particle.angle += particle.speed;

                // Translate towards the magnet position
                particle.shift.x += ( (closestMagnet.position.x+(force.x*8)) - particle.shift.x) * particle.speed;
                particle.shift.y += ( (closestMagnet.position.y+(force.y*8)) - particle.shift.y) * particle.speed;

                // Appy the combined position including shift, angle and orbit
                particle.position.x = particle.shift.x + Math.cos(i+particle.angle) * (particle.orbit*particle.force);
                particle.position.y = particle.shift.y + Math.sin(i+particle.angle) * (particle.orbit*particle.force);

                // Limit to screen bounds
                particle.position.x = Math.max( Math.min( particle.position.x, stage.stageWidth-particle.size/2 ), particle.size/2 );
                particle.position.y = Math.max( Math.min( particle.position.y, stage.stageHeight-particle.size/2 ), particle.size/2 );

                // Slowly inherit the cloest magnets orbit
                particle.orbit += ( closestMagnet.orbit - particle.orbit ) * 0.1;

                graphics.lineStyle(0, 0xFF0000, 1);
                graphics.beginFill(0xFF0000, 0.4);
                graphics.drawCircle(particle.position.x, particle.position.y, particle.size);
                graphics.endFill();
            }
        }
        
        private function distanceBetween(p1:Object, p2:Object):Number {
            var dx:Number = p2.x - p1.x;
            var dy:Number = p2.y - p1.y;
            return Math.sqrt(dx * dx + dy * dy);
        }        
        
    }
    
}

internal class Particle {
  public var size:Number = 0.5 + Math.random() * 3.5;
  public var position:Object = { x: 0, y: 0 };
  public var shift:Object = { x: 0, y: 0 };
  public var angle:Number = 0;
  public var speed:Number = 0.01 + (size / 4) * 0.03;
  public var force:Number = 1 - (Math.random()*0.15);
  public var color:int = 0xffffff;
  public var orbit:Number = 1;
  public var magnet:Magnet = null;
}

internal class Magnet {
    public var orbit:Number = 100;
    public var position:Object = { x: 0, y: 0 };
    public var dragging:Boolean = false;
    public var connections:Number = 0;
    public var size:Number = 1;
}