サンドパーティクル

by thinktaro
SandButtonを参考に作った。ステージフォーカスout,overでイベント。
たまに見えづらいことがあるかも?

...
@author thinktaro
♥0 | Line 140 | Modified 2009-07-13 17:13:49 | MIT License
play

ActionScript3 source code

/**
 * Copyright thinktaro ( http://wonderfl.net/user/thinktaro )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bO4S
 */

package
{
	//SandButtonを参考に作った。ステージフォーカスout,overでイベント。
          //たまに見えづらいことがあるかも?
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.display.StageQuality;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	/**
	 * ...
	 * @author thinktaro
	 */
	public class SandButton extends Sprite 
	{
		private var container:Sprite;//これに特には意味はない。
		private var canvas:BitmapData;
		private var textCanvas:BitmapData;
		private var particles:Vector.<Particle>;
		private var rect:Rectangle;
		private var windX:Number = 0;
		private var windY:Number = 0;
		private var streamIndex:int = 0;
		private var returnIndex:int = 0;
		private var cTra:ColorTransform;
		public function SandButton() 
		{
			if(stage){
				initializeHandler();
			}
			else{
				addEventListener(Event.ADDED_TO_STAGE,initializeHandler);
			}
		}
		private function initializeHandler(evt:Event=null):void{
			removeEventListener(Event.ADDED_TO_STAGE,initializeHandler);
			configure();
			container = new Sprite();
			particles = new Vector.<Particle>();
			rect = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
			canvas = new BitmapData(stage.stageWidth, stage.stageHeight,false,0x0);
			container.addChild(new Bitmap(canvas));
			addChild(container);
			var tf:TextField = new TextField();
			tf.defaultTextFormat = new TextFormat("_sans", 80, 0xffffff);
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.text = "Hello! World";
			cTra = new ColorTransform(1, 1, 1, 1, -20, -30, -25);
			textCanvas = new BitmapData(tf.width, tf.height,false,0x0);
			textCanvas.draw(tf);
			createObject();
			stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			addEventListener(Event.ENTER_FRAME,loopHandler);
		}
		private function mouseOverHandler(evt:MouseEvent):void {
			removeEventListener(Event.ENTER_FRAME, returnParticleHandler);
			addEventListener(Event.ENTER_FRAME, streamParticleHandler);
			windX =  5 * Math.random() - 2.5;
			windY = (5 * Math.random() - 2.5) / 2;
			returnIndex = streamIndex;
			cTra.redOffset = 50 * Math.random() - 25;
			cTra.greenOffset = 50 * Math.random() - 25;
			cTra.blueOffset = 50 * Math.random() - 25;
		}
		private function mouseOutHandler(evt:MouseEvent):void {
			addEventListener(Event.ENTER_FRAME, returnParticleHandler);
			removeEventListener(Event.ENTER_FRAME, streamParticleHandler);
			streamIndex = returnIndex;
			cTra.redOffset = 50 * Math.random() - 25;
			cTra.greenOffset = 50 * Math.random() - 25;
			cTra.blueOffset = 50 * Math.random() - 25;
		}
		private function createObject():void {
			var offset:Point = new Point((stage.stageWidth - textCanvas.width) / 2, (stage.stageHeight - textCanvas.height) / 2);
			var k:int = 0;
			for (var i:int = 0; i < textCanvas.width; i++) {
				for (var j:int = 0; j < textCanvas.height; j++) {
					var color:int = textCanvas.getPixel(i, j);
					if (color != 0) {
						var p:Particle = new Particle(offset.x + i, offset.y + j);
						particles[k++] = p;
					}
					else {
						continue;
					}
				}
			}
		}
		private function loopHandler(evt:Event):void {
			canvas.lock();
			canvas.colorTransform(rect,cTra);
			for (var i:int = 0; i < particles.length; i++) {
				var p:Particle = particles[i];
				canvas.setPixel(int(p.x), int(p.y), 0xffffff);
			}
			canvas.unlock();
		}
		private function configure():void{
			stage.quality = StageQuality.MEDIUM;
		}
		private function streamParticleHandler(evt:Event):void {
			for (var i:int = 0; i < streamIndex; i++) {
				var p:Particle = particles[i];
				p.vy += windY * Math.random();
				p.vx += windX * Math.random();
				p.vy *= 0.8;
				p.vx *= 0.8;
				p.y += p.vy;
				p.x += p.vx;
			}
			(streamIndex <= particles.length - 10) ? streamIndex += 10:0;
		}
		private function returnParticleHandler(evt:Event):void {
			for (var i:int = returnIndex; i>=0; i--) {
				var p:Particle = particles[i];
				p.vx += (p.tempX - p.x) * Math.random() * 0.1;
				p.vy += (p.tempY - p.y) * Math.random() * 0.1;
				p.vx *= 0.4;
				p.vy *= 0.4;
				p.x += p.vx;
				p.y += p.vy;
			}
			(returnIndex <= particles.length - 10) ? returnIndex += 10:0;
		}
	}
}
internal class Particle {
	public var vx:Number = 0;
	public var vy:Number = 0;
	public var tempX:Number;
	public var tempY:Number;
	public var x:Number;
	public var y:Number;
	public function Particle(x:Number, y:Number) {
		this.x = tempX = x;
		this.y = tempY = y;
	}
}