MOMIJI
秋なので…
Webカメラでのトラキングで表示コンテナが回転します。
(カメラからちょっと離れて試した方がなんかうまくいくっぽいです。)
フルサイズ(1280 × 720)のバージョンはこちら → http://www.digifie.jp/labo/momiji/
/**
* Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/cjIA
*/
// forked from mousepancyo's SAKURA
package
{
import flash.display.*;
import flash.events.*;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.media.Camera;
import flash.media.Video;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.utils.Dictionary;
[SWF(width = "465", height = "465", backgroundColor = "0", frameRate = "60")]
public class Main extends Sprite
{
private const W:Number = 465;
private const H:Number = 465;
private const NUM_SAKURA:int = 250;
private const IMG_URL:String = "http://www.digifie.jp/assets/images/momiji.png";
private var _loader:Loader;
private var _canvas:BitmapData;
private var _ctf:ColorTransform;
private var _dict:Dictionary = new Dictionary(true);
public var container3D:Sprite;
private var _sakura:BitmapData;
private var _sakuraList:Vector.<Sprite> = Vector.<Sprite>([]);
private var _isDown:Boolean;
private var _oldP:Point = new Point();
private var _distP:Point = new Point();
private var _cam:Camera;
public var video:Video;
private var _px:Number = 0;
private var _py:Number = 0;
// Tracker
private var _tracker:Tracker;
public function Main()
{
root.transform.perspectiveProjection.fieldOfView = 60;
root.transform.perspectiveProjection.projectionCenter = new Point(W * .5, H * .5);
Security.loadPolicyFile("http://www.digifie.jp/crossdomain.xml");
loadImage(IMG_URL);
}
private function loadImage(url:String):void
{
var context:LoaderContext = new LoaderContext;
context.checkPolicyFile = true;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
_loader.load(new URLRequest(url), context);
}
private function onLoaded(e:Event):void
{
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
_sakura = new BitmapData(_loader.width, _loader.height, true, 0);
_sakura.draw(_loader);
setup();
}
private function setup():void
{
container3D = new Sprite();
container3D.x = W * .5;
container3D.y = H * .5;
container3D.z = 0;
addChild(container3D);
_canvas = new BitmapData(W, H, false, 0);
addChildAt(new Bitmap(_canvas), 0);
_ctf = new ColorTransform(.75, .75, .75);
addSakura();
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
// Camera & Video
_cam = Camera.getCamera();
_cam.setMode(240, 240, 30);
video = new Video(_cam.width, _cam.height);
video.attachCamera(_cam);
//container3D.addChild(video);
// Tracker
_tracker = new Tracker(W, H, video);
//addChild(_tracker);
}
private function addSakura():void
{
var n:int = NUM_SAKURA;
while(n--)
{
var sak:Sprite = new Sprite();
var bmd:BitmapData = _sakura.clone();
var bm:Bitmap = new Bitmap(bmd);
sak.addChild(bm);
bm.x = -bm.width * .5;
bm.y = -bm.height * .5;
sak.scaleX = sak.scaleY = Math.random() * 1.3 + .15;
sak.x = (Math.random() * 1000 - 200) - W * .5;
sak.y = (Math.random() * -200 - 50) - H * .5;
sak.z = Math.random() * 2000 - 1000;
sak.filters = [new BlurFilter(4, 4)];
sak.blendMode = "add";
_dict[sak] = {vx:3 - sak.scaleX, vy:Math.random() * sak.scaleY + 1, inix:sak.x, iniy:sak.y};
container3D.addChild(sak);
_sakuraList.push(sak);
}
}
private function fall(sak:Sprite):void
{
sak.rotationX += Math.random() * 10 - _distP.x * .01;
sak.rotationY += Math.random() * 10 - _distP.y * .01;
var vx:Number = _dict[sak].vx;
var vy:Number = _dict[sak].vy;
var dist:Number = Point.distance(new Point(sak.x, sak.y), _distP);
vx = vx + (180 - (sak.rotationY % 360)) * (.003 - _distP.x / dist);
vy = vy - (180 - (sak.rotationX % 180)) * (.008 - _distP.y / dist);
sak.x += vx;
sak.y += vy;
if(sak.x > W * .5 + 100 || sak.x < -W * .5 - 500) sak.x = _dict[sak].inix;
if(sak.y > H * .5 + 50 || sak.y < - H * .5 - 600) sak.y = _dict[sak].iniy;
}
private var _count:int = 0;
private function update(e:Event):void
{
if(_tracker.isMotion)
{
_px += (_tracker.trackPoint.x - _px) * .03;
_py += (_tracker.trackPoint.y - _py) * .03;
}
else
{
_px += ((W * .5) - _px) * .05;
_py += ((H * .5) - _py) * .05;
}
container3D.rotationY = -(_px - W * .5) * .8;
container3D.rotationX = -(_py - H * .5) * .2;
//
var n:int = NUM_SAKURA;
while(n--)
{
fall(_sakuraList[n]);
}
_canvas.lock();
_canvas.draw(this);
_canvas.applyFilter(_canvas, _canvas.rect, new Point(), new BlurFilter(16, 16));
_canvas.colorTransform(_canvas.rect, _ctf);
_canvas.unlock();
}
private function onDown(e:MouseEvent):void
{
_oldP = new Point(mouseX, mouseY);
_isDown = true;
}
private function onUp(e:MouseEvent):void
{
_isDown = false;
}
}
}
//package
//{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Video;
import flash.utils.Timer;
internal class Tracker extends Sprite
{
private var _w:Number;
private var _h:Number;
public var trackPoint:Point = new Point();
public var _previous:BitmapData;
public var _current:BitmapData;
private var _px:Number;
private var _py:Number;
private var _blur:BlurFilter = new BlurFilter(64,64);
private var _vid:Video;
private var _mirror:Matrix;
private var _point:Point = new Point();
private var _area:Rectangle;
public var isMotion:Boolean = false;
public function Tracker(w:Number, h:Number, vid:Video)
{
_w = w;
_h = h;
_vid = vid;
_mirror = new Matrix();
_mirror.scale(-1, 1);
_mirror.translate( _vid.width, 0);
/*var ofsetX:Number = _vid.width - (_vid.width - _w) * .5
var ofsetY:Number = _vid.height - (_vid.height - _h) * .5
_mirror.translate(ofsetX, ofsetY);*/
_current = new BitmapData(_w * .25, _h * .25, false, 0x000000);
_previous = _current.clone();
//addChild(new Bitmap(_previous));
//
var timer:Timer = new Timer(200);
timer.addEventListener(TimerEvent.TIMER, trackerUpdate);
timer.start();
}
private function trackerUpdate(e:TimerEvent):void
{
track();
trackPoint.x = _px * 4;
trackPoint.y = _py * 4;
trace(trackPoint.x, trackPoint.y)
}
private function track():void
{
_current.draw(_vid, _mirror);
_current.draw(_previous, null, null, BlendMode.DIFFERENCE);
_current.applyFilter(_current, _current.rect, _point, _blur);
_current.threshold(_current, _current.rect, _point, ">", 0xFF333333, 0xFFFFFFFF);
_previous.draw(_vid, _mirror);
_area = _current.getColorBoundsRect(0xFFFFFFFF,0xFFFFFFFF,true);
isMotion = ( _area.width > ( _current.width / 100) * 5 || _area.height > (_current.height / 100) * 5 );
if (isMotion)
{
_px = _area.x + _area.width * .5;
_py = _area.y + _area.height * .5;
}
graphics.clear();
graphics.lineStyle(1, 0xFF0000, .5);
graphics.drawRect(_area.x * 4, _area.y * 4, _area.width, _area.height);
}
}
//}