// forked from Event's Simple MediaRSS Viewer // 8月のJAMの課題 // 「MediaRSSをフィードとするフォトビューアをつくってください」に挑戦。 // 何か楽しげなものを作りたかった。 // クリック&ドラッグで画面外まで画像をふっ飛ばすと画像が拡大表示されます。 // search機能もあります。randomサーチするといろんな画像を見ることができます。 //urlが入力できるようになってますが //wonderfl用に許可されたrss以外は読み込めません。 //読み込めるRSS //http://api.flickr.com/services/feeds/photos_public.gne?format=rss_200 package { import flash.net.URLRequest; import flash.events.Event; import flash.net.URLLoader; import flash.display.*; import com.bit101.components.*; [SWF(backgroundColor = "#060606")] public class MediaRSSReader extends Sprite { private var feed:String = "http://api.flickr.com/services/feeds/photos_public.gne"; private var tags:Array = ["fun","baby","wonder","landscape","building","colorful","old","art","azuki","night","fire","monotone","pink"] private var tags2:Array = ["kamakura","cat","desert","smile","jump","kyoto","juggling","zebra","maze","tropical","antarctica","roma","sketch","temple"] private var tag:String = ""; private var tagmode:String = "ALL"; private var format:String = "rss_200" private var media:Namespace = new Namespace("http://search.yahoo.com/mrss/"); private var viewer:Viewer; private var isRandom:Boolean = true; private var pLabel:Label; private var sLabel:Label; private var input:InputText; private var ok:PushButton; private var random:PushButton; private var stepper:NumericStepper; private var orRadio:RadioButton; private var andRadio:RadioButton; private var tagInput:InputText; public function MediaRSSReader() { Wonderfl.capture_delay( 100 ); addEventListener(Event.ADDED_TO_STAGE,init); } private function init(e:Event):void{ removeEventListener(Event.ADDED_TO_STAGE,init); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; var w:int = stage.stageWidth; var h:int = stage.stageHeight; //コンポーネントの設定 pLabel = new Label(this,440,440,"/1"); sLabel = new Label(this,440,440,"tag:"); input = new InputText(this,10,440,feed); ok = new PushButton(this,312,440,"search",feedChange); random = new PushButton(this,312,440,"random",randomPush); stepper = new NumericStepper(this,360,440,pageChange); tagInput = new InputText(this,10,440,tag); orRadio = new RadioButton(this,10,440,"OR"); andRadio = new RadioButton(this,10,440,"AND",true); pLabel.setSize(20,16); input.setSize(w-130,16); ok.setSize(40,16); random.setSize(40,16); stepper.setSize(60,16); tagInput.setSize(w-350,16); pLabel.move(w-30, h-20); input.move(10, h-41); ok.move(w-160, h-20); random.move(w-205, h-20); stepper.move(w-90, h-20); tagInput.move(35, h-20); sLabel.move(10, h-20); orRadio.move(w-270, h-15); andRadio.move(w-310, h-15); stepper.minimum = 1; stepper.value = 1; randomPush(null); } private function readRSS():void{ var ldr:URLLoader = new URLLoader; tag = tag.replace( /[ ,]+/, ","); var url:String = feed + "?format=" + format + "&tags=" + tag + "&tagmode=" + tagmode ldr.load(new URLRequest(url) ); ldr.addEventListener(Event.COMPLETE, function _load(e:Event):void { ldr.removeEventListener(Event.COMPLETE, _load); var thumbs:Array = XML(ldr.data)..media::thumbnail.@url.toXMLString().split('\n'); if(thumbs.length>1){ onImageLoaded(thumbs,XML(ldr.data)..media::content.@url.toXMLString().split('\n')); }else if(isRandom){ randomPush(null); } }); } private function onImageLoaded($thumbs:Array , $contents:Array):void { if(viewer != null && contains(viewer)){ removeChild(viewer) viewer.remove(); viewer = null; } var w:int = stage.stageWidth; var h:int = stage.stageHeight; viewer = new Viewer(w-20,h-56); viewer.x = viewer.y = 10; addChild(viewer); var ldr:Loader; for (var i:int = 0; i < $thumbs.length; ++i) { ldr = new Loader; ldr.load(new URLRequest($thumbs[i])); viewer.addThumb(ldr,$contents[i]); stepper.maximum = viewer.lastPage; pLabel.text = "/ " + viewer.lastPage; } } private function feedChange(e:Event):void{ feed = input.text; tag = tagInput.text; if( orRadio.selected ){ tagmode = "any"; } else if( andRadio.selected ){ tagmode = "all"; } isRandom = false; readRSS(); } private function randomPush(e:Event):void{ tag = tags[Math.floor(tags.length*Math.random())] +" "+ tags2[Math.floor(tags2.length*Math.random())]; tagInput.text = tag; isRandom = true; readRSS(); } private function pageChange(e:Event):void{ viewer.page = e.currentTarget.value; } } } import flash.system.LoaderContext; import flash.net.URLRequest; import flash.text.*; import flash.filters.BlurFilter; import flash.geom.Rectangle; import flash.events.Event; import flash.events.MouseEvent; import flash.display.*; import caurina.transitions.*; class Viewer extends Sprite{ //サムネは正方形 static private const thumbH:int = 80; static private const thumbW:int = 80; static private const intervalV:int = 2; static private const intervalH:int = 2; private var startX:int = thumbW; private var startY:int = thumbH; private var numThumb:int = 0; private var nextX:int = startX; private var nextY:int = startY; private var nextPage:int = 1; private var w:int = 0; private var h:int = 0; public var lastPage:int = 1; private var _page:int = 1; public function set page(i:int):void{ if(_page != i){ i; if(i>lastPage){ i = lastPage; } if(0>i){ i = 0; } setPage(i); } } public function get page():int{ return _page; } public var down:Thumbnail = null; public var select:Thumbnail = null; public var dir:Array = [0,0]; public var thumbs:Vector.<Thumbnail> = new Vector.<Thumbnail>(); public var thumbSprite:Sprite = new Sprite(); public var blur:BlurFilter = new BlurFilter(16,16); static private const TF1:Array = [ ["autoSize",TextFieldAutoSize.LEFT],["x",0],["y",0],["selectable",false] ]; static private const FR1:Array = [ ["size",15],["color",0xFF],["underline",true],["target","_blank"] ]; static private const TF2:Array = [ ["autoSize",TextFieldAutoSize.LEFT],["text","now loading..."],["x",0],["y",15],["selectable",false],["blendMode","invert"],["alpha",0] ]; static private const FR2:Array = [ ["size",15],["color", 0x000000] ]; public var url:TextField; public var now:TextField; public var format:TextFormat; public var img:BoyoyonMap = new BoyoyonMap(1,1); private var loadIndex:int = 0; public function Viewer(width:int,height:int){ var maskBmp:Bitmap = new Bitmap(new BitmapData(1,1,false)); maskBmp.scaleX = w = width; maskBmp.scaleY = h = height; addChild( maskBmp ); mask = maskBmp; addEventListener( "mouseOut", mouseOut ); addEventListener( "mouseUp", mouseUp ); addEventListener( "mouseDown", mouseDown ); addEventListener( "mouseMove", mouseMove ); addChild( thumbSprite ); url = TFUtil.textField(TF1); url.defaultTextFormat = format = TFUtil.format(FR1); now = TFUtil.textField(TF2); now.defaultTextFormat = TFUtil.format(FR2); addChild( url ); addChild( now ); graphics.beginFill(0x222222,1.0); graphics.drawRect(0,0,width,height); Sound.se(6); } public function remove():void{ removeEventListener( "mouseOut", mouseOut ); removeEventListener( "mouseUp", mouseUp ); removeEventListener( "mouseDown", mouseDown ); removeEventListener( "mouseMove", mouseMove ); var num:int = thumbSprite.numChildren; for(var i:int=0; i<num; i++){ var ch:Thumbnail = thumbSprite.getChildAt(i) as Thumbnail; removeListener(ch); } } public function setPage(p:int):void{ if(p > page){ Sound.se(4); } if(p < page){ Sound.se(5); } if(p == page){ Sound.se(6); } Sound.se(0); _page = p; mouseUp(null); var num:int = thumbSprite.numChildren; for(var i:int=0; i<num; i++){ var ch:Thumbnail = thumbSprite.getChildAt(i) as Thumbnail; var r:Rectangle = ch.getRect(ch); var dir:Array = [[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,1],[-1,-1],[1,-1]] dir = dir[ Math.floor(Math.random() * dir.length) ]; var tx:int = w/2 - (w+r.width)*dir[0]/2*(1+Math.random()); var ty:int = h/2 - (h+r.height)*dir[1]/2*(1+Math.random()); removeListener(ch); Tweener.addTween(ch,{x:tx,y:ty,time:0.8,onStartParams:[ch],onStart:removeChild, transition:"easeOutExpo"} ); } for(var j:int=0;j<thumbs.length;j++){ if(thumbs[j].page == p){ setThumb(thumbs[j]); } } } public function addThumb(obj:DisplayObject,url:String):Thumbnail{ var thumb:Thumbnail = new Thumbnail(obj,thumbH,thumbW,url); thumbs.push(thumb); thumb.x = startX - Math.random()*intervalH; thumb.y = startY - Math.random()*intervalV; lastPage = nextPage; thumb.page = nextPage; thumb.cx = nextX; thumb.cy = nextY; if(_page == nextPage ){ setThumb(thumb); } nextX += thumbW + intervalH; if(nextX+thumbW + intervalH > w){ nextX = startX; nextY += thumbH + intervalV; if(nextY + thumbH + intervalV > h){ nextY = startY; nextPage++; } } numThumb++; return thumb; } private function setThumb(thumb:Thumbnail):void{ thumb.rotation = 0; thumb.scaleX = thumb.scaleY = 1; Tweener.addTween( thumb,{ x:thumb.cx , y:thumb.cy, delay:Math.random()*0.5, time:1, transition:"easeInOutCubic" } ); thumbSprite.addChild(thumb); setListener(thumb); } private function thumbOver(e:MouseEvent):void{ var t:Thumbnail = e.currentTarget as Thumbnail; if(down == null && select == null){ var rate:Number = 2; thumbSprite.setChildIndex( t, thumbSprite.numChildren-1); Tweener.addTween( t,{ scaleX:rate, scaleY:rate, time:1.5, transition:"easeOutElastic" } ); Sound.se(1); } } private function thumbOut(e:MouseEvent):void{ var t:Thumbnail = e.currentTarget as Thumbnail; if(down == null && select == null){ var rate:Number = 1; Tweener.addTween( t,{ scaleX:rate, scaleY:rate, time:1.5, rotation:360, transition:"easeOutElastic" } ); Sound.se(2,2); Sound.se(7,1); } } private function thumbDown(e:MouseEvent):void{ if(select == null){ down = e.currentTarget as Thumbnail; var rate:Number = 1.8; down.clipX = down.x; down.clipY = down.y; down.x = (mouseX + down.clipX)/2 down.y = (mouseY + down.clipY)/2 } } private function mouseDown(e:MouseEvent):void{ if(select != null){ var mw:int = w/img.cutW; var mh:int = h/img.cutH; for(var i:int=0;i<img.cutW+1;i++){ for(var j:int=0;j<img.cutH+1;j++){ var t:TweenPoint = img.points[i][j]; var dx:int = mouseX - img.dPoints[i][j].x; var dy:int = mouseY - img.dPoints[i][j].y; var d:int = dx*dx+dy*dy; Tweener.addTween(t,{ delay:0 ,time:t.time, x:(mouseX + 3*mw*i)/4, y:(mouseY + 3*mh*j)/4,transition:"easeOutElastic"}); } } } } private function mouseUp(e:MouseEvent):void{ if(down != null && select == null){ var rate:Number = 1.0; removeListener(down); Tweener.addTween( down,{ x:down.clipX-(down.x-down.clipX)*1, y:down.clipY-(down.y-down.clipY)*1, time:1.2, transition:"easeOutElastic", onUpdate:onMove, onUpdateParams:[down] } ); Tweener.addTween( down,{ scaleX:rate, scaleY:rate, delay:0.75, time:1, transition:"easeOutBounce", onStartParams:[down], onStart:setListener, onUpdate:onMove, onUpdateParams:[down] } ); down = null; Sound.se(3); Sound.se(0); }else if(select != null){ rate = 1.0; setListener(select); Tweener.removeTweens(blur); Tweener.addTween(blur,{blurX:0, blurY:0, skipUpdates:3, time:2, onUpdate:doBlur }); Tweener.addTween( select,{ scaleX:rate, scaleY:rate, rotation:0, x:Math.random()*w/2+w/4, y:Math.random()*h/2+h/4, time:1, onUpdate:onMove, onUpdateParams:[down] } ); Tweener.resumeAllTweens(); if( this.contains(img) ){ removeChild(img); } select.onLoaded = null; select = null; url.text = ""; Tweener.addTween(now, {alpha:0, time:0.5, transition:"easeOutExpo" } ); Sound.se(8); } } private function mouseOut(e:MouseEvent):void{ if( (e.relatedObject == null || contains(e.relatedObject)==false ) && select == null){mouseUp(e);} } private function mouseMove(e:MouseEvent):void{ if(down != null && select == null){ down.x = (mouseX + down.clipX)/2 down.y = (mouseY + down.clipY)/2 } } //外に出たかチェック private function onMove(t:Thumbnail):void{ if(mask.hitTestObject(t) == false){ dir = [0,0]; if(t.x < 0){ dir[0] = -1; } if(t.y < 0){ dir[1] = -1; } if(t.x > w){ dir[0] = 1; } if(t.y > h){ dir[1] = 1; } format.url=t.contentUrl; url.defaultTextFormat = format; blur.blurX=blur.blurY=0; select=t; Tweener.removeTweens(t); Tweener.pauseAllTweens(); Tweener.addTween(blur,{blurX:16, blurY:16, time:2, skipUpdates:3, onUpdate:doBlur }); url.text = t.contentUrl; if( t.load() ){ slide() } else{now.alpha=1;t.onLoaded=slide;} } } private function doBlur():void{thumbSprite.filters = [ blur ];} private function setListener(thumb:Thumbnail):void{ thumb.addEventListener( "mouseOver", thumbOver ); thumb.addEventListener( "mouseOut", thumbOut ); thumb.addEventListener( "mouseDown", thumbDown ); } private function removeListener(thumb:Thumbnail):void{ thumb.removeEventListener( "mouseOver", thumbOver ); thumb.removeEventListener( "mouseOut", thumbOut ); thumb.removeEventListener( "mouseDown", thumbDown ); } private function slide():void{ if(select != null){ img = new BoyoyonMap(w,h,select.image); addChildAt(img,2); var mw:int = w/img.cutW; var mh:int = h/img.cutH; var sx:int = w*dir[0]; var sy:int = h*dir[1]; for(var i:int=0;i<img.cutW+1;i++){ for(var j:int=0;j<img.cutH+1;j++){ var t:TweenPoint = img.points[i][j]; t.x = mw * i - sx; t.y = mh * j - sy; Tweener.addTween(t,{delay:t.delay, time:t.time, x:mw*i, y:mh*j,transition:"easeOutElastic"}); } } Sound.se(0,2); } Tweener.addTween(now, {alpha:0, time:0.5, transition:"easeOutExpo" } ); } private function imageLoad():void{ } } import flash.filters.BlurFilter; import flash.events.Event; import flash.geom.Rectangle; import flash.geom.Matrix; import flash.display.*; class BoyoyonMap extends Shape{ public var cutW:int = 20,cutH:int = 20; public var center:Point; public var dPoints:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(); public var points:Vector.<Vector.<TweenPoint>> = new Vector.<Vector.<TweenPoint>>(); public var imageMap:BitmapData; private var softData:BitmapData; function BoyoyonMap(w:int,h:int,spr:DisplayObject=null):void{ imageMap = new BitmapData(w,h,true,0x0); softData = new BitmapData(w,h); if(spr != null){ var r:Rectangle = spr.getRect(spr); var rate:Number = 1; var tw:int = r.width*rate; var th:int = r.height*rate; if(tw > w){ rate *= (w / tw); th = r.height * rate; tw = r.width * rate; } if(th> h){ rate *= (h / th); th = r.height * rate; tw = r.width * rate; } imageMap.draw(spr, new Matrix(rate,0,0,rate, (w-tw)/2+spr.x , (h-th)/2+spr.y )); softData.applyFilter(imageMap,imageMap.rect,new flash.geom.Point(),new BlurFilter(20,20,2)); } var mw:int = w/cutW; var mh:int = h/cutH; var center:Point = new Point(w/2,h/2); for(var i:int=0;i<cutW+1;i++){ points[i] = new Vector.<TweenPoint>; dPoints[i] = new Vector.<Point>; for(var j:int=0;j<cutH+1;j++){ dPoints[i][j] = new Point( i*mw, j*mh ); /* var dx:int = center.x-dPoints[i][j].x; var dy:int = center.y-dPoints[i][j].y; var d:int = dx*dx+dy*dy; points[i][j] = new TweenPoint( i*mw, j*mh, (1-d/(w*h))*2, 0 ); */ var sof:Number = softData.getPixel(i * mw, j * mh) / 0x4000000; points[i][j] = new TweenPoint( i*mw, j*mh, 3*sof, sof ); } } this.addEventListener( "enterFrame", onFrame ); } private function onFrame(e:Event=null):void{ graphics.clear(); for(var i:int=0;i<cutW;i++){ for(var j:int=0;j<cutH;j++){ GraphicUtil.drawTriangle(graphics,imageMap,points[i][j],points[i][j+1],points[i+1][j],dPoints[i][j],dPoints[i][j+1],dPoints[i+1][j] ) GraphicUtil.drawTriangle(graphics,imageMap,points[i+1][j+1],points[i][j+1],points[i+1][j],dPoints[i+1][j+1],dPoints[i][j+1],dPoints[i+1][j] ) } } } } class Point{ public var x:int = 1; public var y:int = 1; function Point(x:int,y:int){ this.x=x; this.y=y; } } class TweenPoint extends Point{ public var delay:Number = 1; public var time:Number = 1; function TweenPoint(x:int,y:int,time:Number=1,delay:Number=0){ super(x,y); this.delay = delay; this.time = time; } } class GraphicUtil { public static function drawTriangle( g:Graphics, bitmapData:BitmapData, a0:Point, a1:Point, a2:Point, p0:Point, p1:Point, p2:Point):void{ var matrix:Matrix = _buildTransformMatrix(p0, p1, p2, a0, a1, a2); g.beginBitmapFill(bitmapData, matrix, false, true); _drawTriangle(g, a0, a1, a2, matrix); g.endFill(); } private static function _buildTransformMatrix( a0:Point, a1:Point, a2:Point, b0:Point, b1:Point, b2:Point):Matrix { var matrixA:Matrix = new Matrix( a1.x - a0.x, a1.y - a0.y, a2.x - a0.x, a2.y - a0.y); matrixA.invert(); var matrixB:Matrix = new Matrix( b1.x - b0.x, b1.y - b0.y, b2.x - b0.x, b2.y - b0.y); var matrix:Matrix = new Matrix(); matrix.translate(-a0.x, -a0.y); // (原点)へ移動 matrix.concat(matrixA); // 単位行列に変換(aの座標系の逆行列) matrix.concat(matrixB); // bの座標系に変換 matrix.translate(b0.x, b0.y); // b0へ移動 return matrix; } private static function _drawTriangle(g:Graphics, p0:Point, p1:Point, p2:Point, matrix:Matrix):void { //g.lineStyle(1, 0x808080); // debug g.moveTo(p0.x, p0.y); g.lineTo(p1.x, p1.y); g.lineTo(p2.x, p2.y); g.lineTo(p0.x, p0.y); } } class Thumbnail extends Sprite{ public var w:int = 0; public var h:int = 0; public var clipX:int = 0; public var clipY:int = 0; public var page:int = 0; public var contentUrl:String = ""; public var loader:Loader = new Loader; public var image:Sprite = new Sprite; public var isLoaded:Boolean = false; public var onLoaded:Function; public var cx:int; public var cy:int; public function Thumbnail(obj:DisplayObject,width:int,height:int,url:String):void{ var maskBmp:Bitmap = new Bitmap(new BitmapData(1,1,false)); maskBmp.scaleX = w = width; maskBmp.scaleY = h = height; maskBmp.x = obj.x = -w/2; maskBmp.y = obj.y = -h/2; addChild(maskBmp); addChild(obj); mask = maskBmp; contentUrl = url; } public function load():Boolean{ if(isLoaded == false){ loader.load( new URLRequest( contentUrl ),new LoaderContext(true) ); loader.contentLoaderInfo.addEventListener("complete",loaded); } return isLoaded; } private function loaded(e:Event):void{ loader.contentLoaderInfo.removeEventListener("complete",loaded); isLoaded = true; image.addChild(loader); var rect:Rectangle = loader.getRect(image); if(onLoaded!=null){onLoaded()} } } import org.si.sion.*; class MyDriver extends SiONDriver { function MyDriver():void{ super(); volume = 1.5 setSamplerData(0, render("%2@4 v8 l24 c<c48")); setSamplerData(1, render("%3@8 l48 cg")); setSamplerData(2, render("%3@8 l48 ac")); setSamplerData(3, render("%3@8 l48 g<c")); setSamplerData(5, render("%3@8 l32 <a>ge>c")); setSamplerData(4, render("%3@8 l32 >c<eg<a")); setSamplerData(6, render("%3@8 l32 >c<<a")); setSamplerData(7, render("%2@4 v5 l48 <e>e<<e")); setSamplerData(8, render("%3@8 l32 <a>>c")); play(); } } class Sound{ static public var driver:MyDriver = new MyDriver(); static public function se(i:int,delay:int=0):void{ driver.playSound(i,0,delay); } } class TFUtil{ //行列に従ってパラメータを設定したTextFieldを返します。 static public function textField(arr:Array,format:Array=null):TextField{ var tf:TextField = new TextField(); if(format!=null){tf.defaultTextFormat = TFUtil.format(format);} for(var i:int=0;i<arr.length;i++){tf[arr[i][0]]=arr[i][1];} return tf; } //行列に従ってパラメータを設定したTextFormatを返します。 static public function format(arr:Array):TextFormat{ var f:TextFormat = new TextFormat(); for(var i:int=0;i<arr.length;i++){f[arr[i][0]]=arr[i][1];} return f; } //行列に従ってパラメータをobjに設定します。 static public function push(obj:Object,arr:Array):void{ for(var i:int=0;i<arr.length;i++){obj[arr[i][0]]=arr[i][1];} } } ぼよよんビューア