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

Elastic String

Elastic String 1
Elastic Pixels の発展
Elastic Pixels 1
あちこちのコードをパッチワーク
// Elastic String 1
// Elastic Pixels の発展
//
// forked from Aquioux's Elastic Pixels
// Elastic Pixels 1
// あちこちのコードをパッチワーク
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
	
	public class Main1 extends Sprite {
		private var aryParticle:Array;	// パーティクル格納配列
		
		private var isMouseDown:Boolean = false;	// マウスをダウンしているか否か
		private var distanceOfReaction:uint = 150;	// マウスに反応する距離
		private var spring:Number = 0.075;			// バネ係数
		private var friction:Number = 0.93;			// 摩擦係数

		private var canvas:BitmapData;
		private var tpx:TextPixelizer;
		
		// コンストラクタ
		public function Main1() {
			var w:uint = stage.stageWidth;
			var h:uint = stage.stageHeight;

			canvas = new BitmapData(w, h, false, 0x000000);
			addChild(new Bitmap(canvas));
			
			tpx = new TextPixelizer("_serif", 60, 0x000000);
			tpx.addEventListener(PixelizerEvent.COMPLETE, completeHandler);
			tpx.pixelize("wonderfl\nbuild flash\nonline");
		}
		
		private function completeHandler(e:PixelizerEvent):void {
			var offsetX:Number = (stage.stageWidth  - tpx.width)  / 2;
			var offsetY:Number = (stage.stageHeight - tpx.height) / 2;
			var data:Vector.<Pixel> = tpx.data;
			
			aryParticle = [];
			for each(var pixel:Pixel in data) {
				var alpha:uint = tpx.getAlpha(pixel.color);
				if (alpha > 0x7f) {
					var particle:Particle = new Particle(pixel.x + offsetX, pixel.y + offsetY);
					aryParticle.push(particle);
				}
			}
			tpx = null;
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		private function enterFrameHandler(e:Event):void {
			canvas.lock();
			canvas.fillRect(canvas.rect, 0x000000);
			var mousePoint:Point = new Point(mouseX, mouseY);
			for each (var particle:Particle in aryParticle) {
				particle.update(mousePoint, isMouseDown, distanceOfReaction, spring, friction);
				canvas.setPixel(particle.x, particle.y, 0xffffff);
			}
			canvas.unlock();
		}
		private function mouseDownHandler(e:MouseEvent):void {
			isMouseDown = true;
		}
		private function mouseUpHandler(e:MouseEvent):void {
			isMouseDown = false;
		}
	}
}

import flash.geom.Point;
class Particle {
	// 既定座標
	private var localX:Number;
	private var localY:Number;
	// ベロシティ
	private var vx:Number = 0;
	private var vy:Number = 0;
	// 現在座標
	private var _x:Number;
	private var _y:Number;
	
	private var offset:int;
	
	public function Particle(x:Number, y:Number) {
		_x = localX = x;
		_y = localY = y;
		offset = Math.floor(Math.random()) * 30 - 15;
	}
	
	public function update(mousePoint:Point, isMouseDown:Boolean, distanceOfReaction:uint, spring:Number, friction:Number):void {
		// 到達値
		var dx:Number;
		var dy:Number;

		var distance:Number = Point.distance(mousePoint, new Point(localX, localY));
		var direction:Number = isMouseDown ? 1 : -1;
		
		if (distance < distanceOfReaction) {
			var diff:Number = distance * direction * (distanceOfReaction - distance) / distanceOfReaction + offset;
			var radian:Number   = Math.atan2(mousePoint.y - localY, mousePoint.x - localX);
			var diffPoint:Point = Point.polar(diff, radian);
			dx = localX + diffPoint.x;
			dy = localY + diffPoint.y;
		} else{	// 位置を元に戻す
			dx = localX;
			dy = localY;
		}
		
		vx += (dx - _x) * spring;
		vy += (dy - _y) * spring;
		vx *= friction;
		vy *= friction;
		_x += vx;
		_y += vy;
	}

	public function get x():Number { return _x; }
	public function get y():Number { return _y; }
}

class Pixel {
	private var _x:Number;
	private var _y:Number;
	private var _color:uint;	// 32 bit color

	public function Pixel(x:Number, y:Number, color:uint) {
		_x = x;
		_y = y;
		_color = color;
	}

	public function get x():Number { return _x; }
	public function get y():Number { return _y; }
	public function get color():uint { return _color; }
	
	public function set x(value:Number):void { _x = value; }
	public function set y(value:Number):void { _y = value; }
	public function set color(value:uint):void { _color = value; }
}

import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
class Pixelizer extends EventDispatcher {
	// ピクセル格納ベクター
	private var _data:Vector.<Pixel>;
	// スキャンサイズ
	private var _width:uint  = 0;	// 幅
	private var _height:uint = 0;	// 高

	public function Pixelizer() {}

	// 走査
	public function scan(bmd:BitmapData):void {
		var w:uint = _width  = bmd.width;
		var h:uint = _height = bmd.height;
		var i:uint = 0;
		_data = new Vector.<Pixel>(w*h, true);
		for (var y:uint = 0; y < h; y++){
			for (var x:uint = 0; x < w; x++){
				_data[i++] = new Pixel(x, y, bmd.getPixel32(x, y));
			}
		}
		// BitmapData 消去
		bmd.dispose();
		// イベント発行
		dispatchEvent(new PixelizerEvent(PixelizerEvent.COMPLETE));
	}

	// 32 bit color のアルファ値を取得
	public function getAlpha(c:uint):uint {
		return (c >> 24) & 0xff;
	}

	// getter(pixelize 実行後に有効)
	public function get data():Vector.<Pixel> { return _data; }
	public function get width():uint  { return _width; }
	public function get height():uint { return _height; }
}

import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
class TextPixelizer extends EventDispatcher {
	// バックエンドクラス
	private var px:Pixelizer;
	
	// テキストフォーマット用変数
	private var _font:String = "_serif";// フォント名
	private var _size:uint = 16;		// フォントサイズ
	private var _color:uint = 0x000000;	// フォントカラー
	
	static public const TRANSPARENT:uint = 0x00000000;

	public function TextPixelizer(font:String = "_serif", size:uint = 16, color:uint = 0x000000) {
		_font = font;
		_size = size;
		_color = color;
	}

	// ピクセル情報作成
	public function pixelize(str:String):void {
		// バックエンドクラス設定
		px = new Pixelizer();
		px.addEventListener(PixelizerEvent.COMPLETE, completeHandler);
		
		// TextField 生成
		var fld:TextField = new TextField();
		fld.defaultTextFormat = new TextFormat(_font, _size, _color);
		fld.text = str;
		fld.autoSize = "left";
		
		// BitmapData 生成
		var w:Number = fld.width - 4;
		var h:Number = fld.height - 4;
		var bmd:BitmapData = new BitmapData(w, h, true, TRANSPARENT);
		bmd.draw(fld, new Matrix(1, 0, 0, 1, -2, -2));

		// 走査
		px.scan(bmd);
	}
	private function completeHandler(e:Event):void {
		dispatchEvent(new PixelizerEvent(PixelizerEvent.COMPLETE));
	}

	// 32 bit color のアルファ値を取得
	public function getAlpha(c:uint):uint {
		return px.getAlpha(c);
	}

	// getter(pixelize 実行後に有効)
	public function get data():Vector.<Pixel> { return px.data; }
	public function get width():uint { return px.width; }
	public function get height():uint { return px.height; }
	
	// setter(pixelize 実行前のみ有効)
	public function set font(value:String):void { _font = value; }
	public function set size(value:uint):void   { _size = value; }
	public function set color(value:uint):void  { _color = value; }
}

import flash.events.Event;
class PixelizerEvent extends Event {
	public static const COMPLETE:String = "complete";

	public function PixelizerEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
		super(type, bubbles, cancelable);
	}
	public override function clone():Event {
		return new PixelizerEvent(type, bubbles, cancelable);
	}
	public override function toString():String {
		return formatToString("PixelizerEvent", "type", "bubbles", "cancelable", "eventPhase");
	}
}