notice: Flash editor updated! Join the development! Thanks to MiniBuilder


embed

TALK
How can I test this script in Flash CS4. Can someone briefly describe?? Thanx
at 2009/07/28 20:57:11 by
FAVORITE BY
:
particles,image,slide,effectimage particle slide
:
:
:
:
fractalfirst code
:
:
:
particle格好いい
:
:
:
BeautiflNo1芸術いつ見ても飽きない。
:
:
:
:
:
muy bueno
:
:
:
particlephotoBeautiful!
:
:
:
背景に使ったらかっこいいかもー
:
:
:
オーラ粒子写真
:
:
FlickrBitmapThreadParticles気持ちいい。
:
:
:
:
particlethreadかっこいー
:
:
:
:
125 get
:
pixelsGreat pixel creator of photos
:
wonderfl
:
:
:
:
:
:
Bitmap
:
WOW! That's awesome!
:
:
It's the most beautiful one ever!!
:
:
:
:
素敵すぎます
:
:
そうめん
:
particlethreadパーティクルが写真に
:
ThreadBitmapDataパーティクル Thread
:
thread & particle
:
particle
:
:
:
:
:
そうめんちゃんとソース読みたい
:
:
:
:
particlesparticles fotos
:
:
:
やりよるなぁ
:
うっわー
:
:
:
:
イイ!
:
:
cool
:
:
そうめんすごいです
:
amazing bitmap flash
:
Bitmapこれはすごい!
:
:
:
とてもキレイ
:
:)
:
nice particle stuff
:
:
Oh! そうめん!
:
カッコイイ
:
threadParticleかっちぇ
:
パーティクル フリッカー
:
:
:
Awesome!
:
:
particle ヤバス
:
bitmapdataparticleやばいね
:
particle
:
整列しきる0.5秒前ぐらいの絵が好き
:
おおー.かっこよい
:
かっこいー
:
particleかちょいい
:
particlecool!!
:
すごい!!!
:
particleこれはすごい
:
パーティクルが集まったときのゾクゾク感
:
パーティ!
:
sehr gut
:
:
threadうひょー!
:
particleパーティクル
FORKED
  1. // forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
  2. /**
  3.  *  ActionScript3 Thread library のサンプルになれば幸いです :-)
  4.  *
  5.  *  @see    http://www.flickr.com/photos/auroracrowley/
  6.  *  @see    http://www.libspark.org/htdocs/as3/thread-files/document/
  7.  */
  8.  
  9.  
  10.  
  11.  
  12.  
  13. /* 
  14. では お言葉に甘えて、ここでAS3 Thread Library の使い方をおぼえてみます。
  15. 特にフォーク元とちがう動きはしません。
  16. */
  17. package
  18. {
  19.     import flash.display.Sprite;
  20.     import flash.display.StageAlign;
  21.     import flash.display.StageQuality;
  22.     import flash.display.StageScaleMode;
  23.     import flash.events.Event;
  24.     import org.libspark.thread.EnterFrameThreadExecutor;
  25.     import org.libspark.thread.Thread;
  26.     [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]
  27.     public class Tmp extends Sprite
  28.     {
  29.         public function Tmp()
  30.         {
  31.             addEventListener(Event.ADDED_TO_STAGE, initialize);
  32.         }
  33.         private function initialize(evt:Event):void
  34.         {
  35.             removeEventListener(Event.ADDED_TO_STAGE, initialize);
  36.             stage.align = StageAlign.TOP_LEFT;
  37.             stage.quality = StageQuality.HIGH;
  38.             stage.scaleMode = StageScaleMode.NO_SCALE;
  39.             if (!Thread.isReady)
  40.             {
  41.                 Thread.initialize(new EnterFrameThreadExecutor());
  42.             }
  43.             new MainThread(this).start();
  44.         }
  45.     }
  46. }
  47. import flash.display.Bitmap;
  48. import flash.display.BitmapData;
  49. import flash.display.BlendMode;
  50. import flash.display.DisplayObject;
  51. import flash.display.DisplayObjectContainer;
  52. import flash.display.Stage;
  53. import flash.events.MouseEvent;
  54. import flash.filters.BitmapFilter;
  55. import flash.filters.BitmapFilterQuality;
  56. import flash.filters.BlurFilter;
  57. import flash.geom.ColorTransform;
  58. import flash.geom.Point;
  59. import flash.net.URLRequest;
  60. import flash.net.URLVariables;
  61. import flash.system.LoaderContext;
  62. import flash.text.TextField;
  63. import flash.text.TextFieldAutoSize;
  64. import flash.text.TextFormat;
  65. import flash.ui.Mouse;
  66. import com.adobe.serialization.json.JSON;
  67. import org.libspark.thread.Thread;
  68. import org.libspark.thread.threads.display.LoaderThread;
  69. import org.libspark.thread.threads.net.URLLoaderThread;
  70. import org.libspark.thread.utils.IProgress;
  71. import org.libspark.thread.utils.IProgressNotifier;
  72. import org.libspark.thread.utils.MultiProgress;
  73. import org.libspark.thread.utils.ParallelExecutor;
  74. import org.libspark.thread.utils.SerialExecutor;
  75. internal var FILTER_BLUR:BlurFilter = new BlurFilter(44, BitmapFilterQuality.LOW);
  76. internal var POINT_ZERO:Point = new Point();
  77. import flash.display.Shape;
  78. internal class Indicator extends Shape
  79. {
  80.     public function Indicator()
  81.     {
  82.         var i:uint,
  83.             cx:Number, cy:Number,
  84.             numNeedles:uint = 12,
  85.             innerR:Number = 7,
  86.             outerR:Number = 5,
  87.             cAngle:Number = -Math.PI / 2,
  88.             nAngle:Number;
  89.         nAngle = Math.PI * 2 / numNeedles;
  90.         for (i=0; i<numNeedles; i++)
  91.         {
  92.             cAngle += nAngle;
  93.             cx = Math.cos(cAngle) * innerR;
  94.             cy = Math.sin(cAngle) * innerR;
  95.             graphics.moveTo(cx, cy);
  96.             cx = Math.cos(cAngle) * outerR;
  97.             cy = Math.sin(cAngle) * outerR;
  98.             graphics.lineStyle(2, 0xffffff, i/numNeedles);
  99.             graphics.lineTo(cx, cy);
  100.         }
  101.     }
  102. }
  103. /////////////////////////////////////////////////////////////////////////// 
  104. //Thread Library だいたいここから
  105. ///////////////////////////////////////////////////////////////////////////
  106. // MainThreadを設置
  107. internal class MainThread extends Thread
  108. {
  109.     private var layer:DisplayObjectContainer;
  110.     private var imageLoader:LoadImageThread;
  111.     private var contents:Array;
  112.     private var canvas:Bitmap;
  113.     private var currentIndex:uint;
  114.     public function MainThread(layer:DisplayObjectContainer)
  115.     {
  116.         this.layer = layer;
  117.     }
  118.     override protected function run():void
  119.     {
  120.         var t:Thread;
  121.         t = new WaitAnimationThread(layer,"CLICK TO START");
  122.         t.start();
  123.         t.join();
  124.         next(loadImage);
  125.     }
  126.     
  127.     private function loadImage():void
  128.     {
  129.         var executor:ParallelExecutor;
  130.         executor = new ParallelExecutor();
  131.         imageLoader = new LoadImageThread();
  132.         executor.addThread(imageLoader);
  133.         executor.addThread(new LoadImageProgressThread(layer, imageLoader.progress));
  134.         executor.start();
  135.         executor.join();
  136.         next(loadComplete);
  137.     }
  138.     private function loadComplete():void
  139.     {
  140.         var s:Stage,
  141.             data:BitmapData;
  142.         contents = imageLoader.contents.concat();
  143.         imageLoader.contents.length = 0;
  144.         imageLoader.contents = null;
  145.         currentIndex = 0;
  146.         s = layer.stage;
  147.         data = new BitmapData(450450true0);
  148.         canvas = new Bitmap(data);
  149.         canvas.x = (s.stageWidth - canvas.width) / 2;
  150.         canvas.y = (s.stageHeight - canvas.height) / 2;
  151.         layer.addChild(canvas);
  152.         next(changeImage);
  153.     }
  154.     private function changeImage():void
  155.     {
  156.         if (currentIndex >= contents.length)
  157.         {
  158.             currentIndex = 0;
  159.         }
  160.         var image:Bitmap,
  161.             th:Thread;
  162.         image = contents[currentIndex++] as Bitmap;
  163.         th = new HandleImageThread(image, canvas);
  164.         th.start();
  165.         th.join();
  166.         next(changeImage);
  167.     }
  168.     override protected function finalize():void
  169.     {
  170.         layer = null;
  171.         imageLoader = null;
  172.     }
  173. }
  174. internal class WaitAnimationThread extends Thread
  175. {
  176.     private var layer:DisplayObjectContainer;
  177.     private var message:Bitmap;
  178.     private var str:String;
  179.     public function WaitAnimationThread(layer:DisplayObjectContainer, str)
  180.     {
  181.         this.layer = layer;
  182.         this.str = str;
  183.     }
  184.     override protected function run():void
  185.     {
  186.         var s:Stage,
  187.             txt:TextField,
  188.             fmt:TextFormat,
  189.             bmd:BitmapData;
  190.         trace("GGGGGGGGGGG");
  191.         s = layer.stage;
  192.         fmt = new TextFormat();
  193.         fmt.color = 0x000000;
  194.         fmt.size = 24;
  195.         fmt.font = 'Trebuchet MS';
  196.         txt = new TextField();
  197.         txt.autoSize = TextFieldAutoSize.LEFT;
  198.         txt.defaultTextFormat = fmt;
  199.         txt.text = str ;
  200.         bmd = new BitmapData(txt.textWidth, txt.textHeight, true0);
  201.         bmd.draw(txt);
  202.         message = new Bitmap(bmd);
  203.         message.blendMode = BlendMode.INVERT;
  204.         message.x = (s.stageWidth - message.width) / 2;
  205.         message.y = (s.stageHeight - message.height) / 2;
  206.         layer.addChild(message);
  207.         event(s, MouseEvent.CLICK, hideMessage);
  208.     }
  209.     private function hideMessage(evt:MouseEvent):void
  210.     {
  211.         new HideMessageThread(message).start();
  212.     }
  213.     override protected function finalize():void
  214.     {
  215.         layer = null;
  216.         message = null;
  217.     }
  218. }
  219. internal class HideMessageThread extends Thread
  220. {
  221.     private var message:DisplayObject;
  222.     private var wrapper:Bitmap;
  223.     private var parent:DisplayObjectContainer;
  224.     private var film:BitmapData;
  225.     private var particles:Vector.<HideMessageParticle>;
  226.     public function HideMessageThread(message:DisplayObject)
  227.     {
  228.         this.message = message;
  229.         this.parent = message.parent;
  230.         this.particles = new Vector.<HideMessageParticle>();
  231.     }
  232.     override protected function run():void
  233.     {
  234.         var s:Stage,
  235.             c:uint,
  236.             w:Number, h:Number,
  237.             offsetX:Number, offsetY:Number,
  238.             i:uint, j:uint,
  239.             bmd:BitmapData;
  240.         s = message.stage;
  241.         bmd = Bitmap(message).bitmapData;
  242.         w = bmd.width;
  243.         h = bmd.height;
  244.         offsetX = message.x;
  245.         offsetY = message.y;
  246.         for (i=0; i<w; i++)
  247.         {
  248.             for (j=0; j<h; j++)
  249.             {
  250.                 c = bmd.getPixel32(i,j);
  251.                 if (!c) continue;
  252.                 particles.push(new HideMessageParticle(offsetX + i, offsetY + j, c));
  253.             }
  254.         }
  255.         bmd.dispose();
  256.         film = new BitmapData(s.stageWidth, s.stageHeight, true0);
  257.         wrapper = new Bitmap(film);
  258.         wrapper.blendMode = BlendMode.INVERT;
  259.         parent.addChild(wrapper);
  260.         parent.removeChild(message);
  261.         next(step);
  262.     }
  263.     private function step():void
  264.     {
  265.         var i:uint,
  266.             l:uint,
  267.             s:Stage,
  268.             p:HideMessageParticle;
  269.         film.lock();
  270.         film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR);
  271.         l = particles.length;
  272.         for (i=0; i<l; i++)
  273.         {
  274.             p = particles[i];
  275.             p.update();
  276.             film.setPixel32(p.x, p.y, p.color);
  277.             if (!film.rect.contains(p.x, p.y))
  278.             {
  279.                 particles.splice(i, 1);
  280.                 i--;
  281.                 l = particles.length;
  282.             }
  283.         }
  284.         film.unlock();
  285.         if (l) next(step);
  286.     }
  287.     override protected function finalize():void
  288.     {
  289.         parent.removeChild(wrapper);
  290.         film.dispose();
  291.         parent = null;
  292.         wrapper = null;
  293.         message = null;
  294.     }
  295. }
  296. internal class LoadImageThread extends Thread implements IProgressNotifier
  297. {
  298.     public var contents:Array;
  299.     private var mainProgress:MultiProgress;
  300.     private var subProgress:MultiProgress;
  301.     private var jsonLoader:URLLoaderThread;
  302.     private var imageLoader:SerialExecutor;
  303.     public function get progress():IProgress
  304.     {
  305.         return mainProgress;
  306.     }
  307.     public function LoadImageThread()
  308.     {
  309.         var req:URLRequest,
  310.             data:URLVariables;
  311.         req = new URLRequest('http://query.yahooapis.com/v1/public/yql');
  312.         data = new URLVariables();
  313.         data['q'] = "SELECT * FROM flickr.photos.search(10) WHERE user_id='25105339@N07'";
  314.         data['format'] = 'json';
  315.         req.data = data;
  316.         jsonLoader = new URLLoaderThread(req);
  317.         mainProgress = new MultiProgress();
  318.         subProgress = new MultiProgress();
  319.         mainProgress.addProgress(jsonLoader.progress, 0.1);
  320.         mainProgress.addProgress(subProgress);
  321.     }
  322.     override protected function run():void
  323.     {
  324.         jsonLoader.start();
  325.         jsonLoader.join();
  326.         next(loadDataComplete);
  327.     }
  328.     private function loadDataComplete():void
  329.     {
  330.         var json:Object,
  331.             row:Object,
  332.             th:LoaderThread,
  333.             req:URLRequest,
  334.             ctx:LoaderContext,
  335.             flickr:FlickrPhoto;
  336.         json = JSON.decode(jsonLoader.loader.data);
  337.         ctx = new LoaderContext(true);
  338.         imageLoader = new SerialExecutor();
  339.         for each (row in json.query.results.photo)
  340.         {
  341.             flickr = new FlickrPhoto(row);
  342.             req = new URLRequest(flickr.thumbnailURL);
  343.             th = new LoaderThread(req, ctx);
  344.             imageLoader.addThread(th);
  345.             subProgress.addProgress(th.progress);
  346.         }
  347.         imageLoader.start();
  348.         imageLoader.join();
  349.         next(loadImageComplete);
  350.     }
  351.     private function loadImageComplete():void
  352.     {
  353.         var i:uint,
  354.             l:uint,
  355.             th:LoaderThread;
  356.         contents = [];
  357.         l = imageLoader.numThreads;
  358.         for (i=0; i<l; i++)
  359.         {
  360.             th = imageLoader.getThreadAt(i) as LoaderThread;
  361.             contents.push(th.loader.content);
  362.         }
  363.     }
  364.     override protected function finalize():void
  365.     {
  366.         jsonLoader = null;
  367.         imageLoader = null;
  368.     }
  369. }
  370. internal class LoadImageProgressThread extends Thread
  371. {
  372.     private var progress:IProgress;
  373.     private var layer:DisplayObjectContainer;
  374.     private var indicator:HandleIndicatorThread;
  375.     public function LoadImageProgressThread(layer:DisplayObjectContainer, progress:IProgress)
  376.     {
  377.         this.layer = layer;
  378.         this.progress = progress;
  379.     }
  380.     override protected function run():void
  381.     {
  382.         indicator = new HandleIndicatorThread(layer);
  383.         indicator.start();
  384.         next(step);
  385.     }
  386.     private function step():void
  387.     {
  388.         if (progress.isCompleted||progress.isFailed||progress.isCanceled)
  389.         {
  390.             next(shutDown);
  391.             return;
  392.         }
  393.         //  TODO: なにかしらやる。
  394.         var percent:Number = progress.percent;
  395.         if (percent >= 1)
  396.         {
  397.             next(shutDown);
  398.         }
  399.         else
  400.         {
  401.             next(step);
  402.         }
  403.     }
  404.     private function shutDown():void
  405.     {
  406.         indicator.interrupt();
  407.     }
  408.     override protected function finalize():void
  409.     {
  410.         progress = null;
  411.         layer = null;
  412.         indicator = null;
  413.     }
  414. }
  415. internal class HandleImageThread extends Thread
  416. {
  417.     public static const PARTICLE_MARGIN:Number = 6;
  418.     private var original:Bitmap;
  419.     private var destination:Bitmap;
  420.     private var showParticles:Vector.<ShowImageParticle>;
  421.     private var hideParticles:Vector.<HideImageParticle>;
  422.     public function HandleImageThread(original:Bitmap, destination:Bitmap)
  423.     {
  424.         this.original = original;
  425.         this.destination = destination;
  426.         this.showParticles = new Vector.<ShowImageParticle>();
  427.         this.hideParticles = new Vector.<HideImageParticle>();
  428.     }
  429.     override protected function run():void
  430.     {
  431.         var w:Number, h:Number, c:uint,
  432.             tx:Number, ty:Number,
  433.             sx:Number, sy:Number,
  434.             cx:Number, cy:Number,
  435.             angle:Number,
  436.             i:uint, j:uint,
  437.             s:Stage,
  438.             data:BitmapData;
  439.         s = destination.stage;
  440.         data = original.bitmapData;
  441.         w = data.width;
  442.         h = data.height;
  443.         cx = s.stageWidth / 2;
  444.         cy = s.stageHeight / 2;
  445.         for (i=0; i<w; i++)
  446.         {
  447.             for (j=0; j<h; j++)
  448.             {
  449.                 c = data.getPixel32(i, j);
  450.                 if (!c) continue;
  451.                 angle = Math.random() * Math.PI * 2;
  452.                 sx = Math.cos(angle) * 500 + cx;
  453.                 sy = Math.sin(angle) * 500 + cy;
  454.                 tx = i * PARTICLE_MARGIN;
  455.                 ty = j * PARTICLE_MARGIN;
  456.                 showParticles.push(new ShowImageParticle(sx, sy, tx, ty, c));
  457.                 hideParticles.push(new HideImageParticle(tx, ty, sx, sy, c, s.frameRate));
  458.             }
  459.         }
  460.         next(showStep);
  461.     }
  462.     private function showStep():void
  463.     {
  464.         var i:uint,
  465.             l:uint,
  466.             c:uint,
  467.             a:Number,
  468.             f:Boolean,
  469.             p:ShowImageParticle,
  470.             data:BitmapData;
  471.         data = destination.bitmapData;
  472.         data.lock();
  473.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  474.         l = showParticles.length;
  475.         f = false;
  476.         for (i=0; i<l; i++)
  477.         {
  478.             p = showParticles[i];
  479.             if (p.isAlive)
  480.             {
  481.                 f = true;
  482.                 p.update();
  483.             }
  484.             data.setPixel32(p.x, p.y, p.color);
  485.         }
  486.         data.unlock();
  487.         if (!f)
  488.         {
  489.             next(fixedImage);
  490.         }
  491.         else
  492.         {
  493.             next(showStep);
  494.         }
  495.     }
  496.     private function hideStep():void
  497.     {
  498.         var i:uint,
  499.             l:uint,
  500.             c:uint,
  501.             a:Number,
  502.             f:Boolean,
  503.             p:HideImageParticle,
  504.             data:BitmapData;
  505.         data = destination.bitmapData;
  506.         data.lock();
  507.         data.colorTransform(data.rect, new ColorTransform(111, .970000));
  508.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  509.         l = hideParticles.length;
  510.         for (i=0; i<l; i++)
  511.         {
  512.             p = hideParticles[i];
  513.             p.update();
  514.             data.setPixel32(p.x, p.y, p.color)
  515.             if (!data.rect.contains(p.x, p.y))
  516.             {
  517.                 hideParticles.splice(i, 1);
  518.                 i--;
  519.                 l = hideParticles.length;
  520.             }
  521.         }
  522.         data.unlock();
  523.         //trace(p.x, p.y);
  524.         if (l) next(hideStep);
  525.     }
  526.     private function fixedImage():void
  527.     {
  528.         sleep(3000);
  529.         next(hideStep);
  530.     }
  531.     override protected function finalize():void
  532.     {
  533.         original = null;
  534.         destination = null;
  535.         showParticles.length = 0;
  536.         showParticles = null;
  537.         hideParticles.length = 0;
  538.         hideParticles = null;
  539.     }
  540. }
  541. internal class HandleIndicatorThread extends Thread
  542. {
  543.     private var layer:DisplayObjectContainer;
  544.     private var indicator:DisplayObject;
  545.     public function HandleIndicatorThread(layer:DisplayObjectContainer)
  546.     {
  547.         this.layer = layer;
  548.     }
  549.     override protected function run():void
  550.     {
  551.         Mouse.hide();
  552.         layer.stage.mouseChildren = false;
  553.         indicator = new Indicator();
  554.         indicator.x = layer.mouseX;
  555.         indicator.y = layer.mouseY;
  556.         layer.addChild(indicator);
  557.         next(step);
  558.     }
  559.     private function step():void
  560.     {
  561.         if (checkInterrupted()) return;
  562.         indicator.rotation = (indicator.rotation + 360 / indicator.stage.frameRate) % 360;
  563.         indicator.x = layer.mouseX;
  564.         indicator.y = layer.mouseY;
  565.         next(step);
  566.     }
  567.     override protected function finalize():void
  568.     {
  569.         Mouse.show();
  570.         layer.stage.mouseChildren = true;
  571.         layer.removeChild(indicator);
  572.         layer = null;
  573.         indicator = null;
  574.     }
  575. }
  576. /////////////////////////////////////////////////////////////////////////// 
  577. // Thread Library なんかだいたいここまで
  578. ///////////////////////////////////////////////////////////////////////////
  579. internal class HideMessageParticle
  580. {
  581.     public var x:Number;
  582.     public var y:Number;
  583.     public var ax:Number;
  584.     public var ay:Number;
  585.     public var vx:Number;
  586.     public var vy:Number;
  587.     public var color:uint;
  588.     public function HideMessageParticle(x:Number, y:Number, color:Number)
  589.     {
  590.         var len:Number,
  591.             angle:Number;
  592.         len = Math.random() * 5;
  593.         angle = Math.random() * Math.PI * 2;
  594.         this.ax = Math.cos(angle) * len;
  595.         this.ay = Math.sin(angle) * len;
  596.         this.x = x;
  597.         this.y = y;
  598.         this.color = color;
  599.         this.vx = 0;
  600.         this.vy = 0;
  601.     }
  602.     public function update():void
  603.     {
  604.         vx += ax;
  605.         vy += ay;
  606.         x += vx;
  607.         y += vy;
  608.     }
  609. }
  610. import flash.geom.Point;
  611. internal class ShowImageParticle
  612. {
  613.     public var x:Number;
  614.     public var y:Number;
  615.     public var color:uint;
  616.     private var targetX:Number;
  617.     private var targetY:Number;
  618.     private var _isAlive:Boolean;
  619.     public function get isAlive():Boolean
  620.     {
  621.         return _isAlive;
  622.     }
  623.     public function ShowImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint)
  624.     {
  625.         this.x = x;
  626.         this.y = y;
  627.         this.color = color;
  628.         this.targetX = targetX;
  629.         this.targetY = targetY;
  630.         this._isAlive = true;
  631.     }
  632.     public function update():void
  633.     {
  634.         x += (targetX - x) * .05;
  635.         y += (targetY - y) * .05;
  636.         if (Math.abs(targetX - x) < .5 && Math.abs(targetY - y) < .5)
  637.         {
  638.             x = targetX;
  639.             y = targetY;
  640.             _isAlive = false;
  641.         }
  642.     }
  643. }
  644. internal class HideImageParticle
  645. {
  646.     public var x:Number;
  647.     public var y:Number;
  648.     public var color:uint;
  649.     private var vx:Number;
  650.     private var vy:Number;
  651.     private var ax:Number;
  652.     private var ay:Number;
  653.     private var rate:Number;
  654.     public function HideImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint, rate:Number)
  655.     {
  656.         var dx:Number,
  657.             dy:Number,
  658.             len:Number,
  659.             angle:Number;
  660.         dx = targetX - x;
  661.         dy = targetY - y;
  662.         len = 9.8;
  663.         angle = Math.atan2(dy, dx);
  664.         this.x = x;
  665.         this.y = y;
  666.         this.vx = 0;
  667.         this.vy = 0;
  668.         this.ax = Math.cos(angle) * len;
  669.         this.ay = Math.sin(angle) * len;
  670.         this.color = color;
  671.         this.rate = rate;
  672.     }
  673.     public function update():void
  674.     {
  675.         vx += ax / rate;
  676.         vy += ay / rate;
  677.         x += vx;
  678.         y += vy;
  679.     }
  680. }
  681. internal class FlickrPhoto
  682. {
  683.     private var _id:String;
  684.     public function get id():String
  685.     {
  686.         return _id;
  687.     }
  688.     private var _secret:String;
  689.     public function get secret():String
  690.     {
  691.         return _secret;
  692.     }
  693.     private var _server:String;
  694.     public function get server():String
  695.     {
  696.         return _server;
  697.     }
  698.     private var _farm:String;
  699.     public function get farm():String
  700.     {
  701.         return _farm;
  702.     }
  703.     public function get thumbnailURL():String
  704.     {
  705.         return ['http://farm', farm, '.static.flickr.com/', server, '/', id, '_', secret, '_s.jpg'].join('');
  706.     }
  707.     public function FlickrPhoto(data:Object)
  708.     {
  709.         this._id = data['id'] || '';
  710.         this._secret = data['secret'] || '';
  711.         this._server = data['server'] || '';
  712.         this._farm = data['farm'] || '';
  713.     }
  714. }
noswf
  1. // forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
  2. /**
  3.  *  ActionScript3 Thread library のサンプルになれば幸いです :-)
  4.  *
  5.  *  @see    http://www.flickr.com/photos/auroracrowley/
  6.  *  @see    http://www.libspark.org/htdocs/as3/thread-files/document/
  7.  */
  8. package
  9. {
  10.     import flash.display.Sprite;
  11.     import flash.display.StageAlign;
  12.     import flash.display.StageQuality;
  13.     import flash.display.StageScaleMode;
  14.     import flash.events.Event;
  15.     import org.libspark.thread.EnterFrameThreadExecutor;
  16.     import org.libspark.thread.Thread;
  17.     [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]
  18.     public class Tmp extends Sprite
  19.     {
  20.         public function Tmp()
  21.         {
  22.             addEventListener(Event.ADDED_TO_STAGE, initialize);
  23.         }
  24.         private function initialize(evt:Event):void
  25.         {
  26.             removeEventListener(Event.ADDED_TO_STAGE, initialize);
  27.             stage.align = StageAlign.TOP_LEFT;
  28.             stage.quality = StageQuality.HIGH;
  29.             stage.scaleMode = StageScaleMode.NO_SCALE;
  30.             if (!Thread.isReady)
  31.             {
  32.                 Thread.initialize(new EnterFrameThreadExecutor());
  33.             }
  34.             new MainThread(this).start();
  35.         }
  36.     }
  37. }
  38. import flash.display.Bitmap;
  39. import flash.display.BitmapData;
  40. import flash.display.BlendMode;
  41. import flash.display.DisplayObject;
  42. import flash.display.DisplayObjectContainer;
  43. import flash.display.Stage;
  44. import flash.events.MouseEvent;
  45. import flash.filters.BitmapFilter;
  46. import flash.filters.BitmapFilterQuality;
  47. import flash.filters.BlurFilter;
  48. import flash.geom.ColorTransform;
  49. import flash.geom.Point;
  50. import flash.net.URLRequest;
  51. import flash.net.URLVariables;
  52. import flash.system.LoaderContext;
  53. import flash.text.TextField;
  54. import flash.text.TextFieldAutoSize;
  55. import flash.text.TextFormat;
  56. import flash.ui.Mouse;
  57. import com.adobe.serialization.json.JSON;
  58. import org.libspark.thread.Thread;
  59. import org.libspark.thread.threads.display.LoaderThread;
  60. import org.libspark.thread.threads.net.URLLoaderThread;
  61. import org.libspark.thread.utils.IProgress;
  62. import org.libspark.thread.utils.IProgressNotifier;
  63. import org.libspark.thread.utils.MultiProgress;
  64. import org.libspark.thread.utils.ParallelExecutor;
  65. import org.libspark.thread.utils.SerialExecutor;
  66. internal var FILTER_BLUR:BlurFilter = new BlurFilter(44, BitmapFilterQuality.LOW);
  67. internal var POINT_ZERO:Point = new Point();
  68. import flash.display.Shape;
  69. internal class Indicator extends Shape
  70. {
  71.     public function Indicator()
  72.     {
  73.         var i:uint,
  74.             cx:Number, cy:Number,
  75.             numNeedles:uint = 12,
  76.             innerR:Number = 7,
  77.             outerR:Number = 5,
  78.             cAngle:Number = -Math.PI / 2,
  79.             nAngle:Number;
  80.         nAngle = Math.PI * 2 / numNeedles;
  81.         for (i=0; i<numNeedles; i++)
  82.         {
  83.             cAngle += nAngle;
  84.             cx = Math.cos(cAngle) * innerR;
  85.             cy = Math.sin(cAngle) * innerR;
  86.             graphics.moveTo(cx, cy);
  87.             cx = Math.cos(cAngle) * outerR;
  88.             cy = Math.sin(cAngle) * outerR;
  89.             graphics.lineStyle(2, 0xffffff, i/numNeedles);
  90.             graphics.lineTo(cx, cy);
  91.         }
  92.     }
  93. }
  94. internal class MainThread extends Thread
  95. {
  96.     private var layer:DisplayObjectContainer;
  97.     private var imageLoader:LoadImageThread;
  98.     private var contents:Array;
  99.     private var canvas:Bitmap;
  100.     private var currentIndex:uint;
  101.     public function MainThread(layer:DisplayObjectContainer)
  102.     {
  103.         this.layer = layer;
  104.     }
  105.     override protected function run():void
  106.     {
  107.         var t:Thread;
  108.         t = new WaitAnimationThread(layer);
  109.         t.start();
  110.         t.join();
  111.         next(loadImage);
  112.     }
  113.     private function loadImage():void
  114.     {
  115.         var executor:ParallelExecutor;
  116.         executor = new ParallelExecutor();
  117.         imageLoader = new LoadImageThread();
  118.         executor.addThread(imageLoader);
  119.         executor.addThread(new LoadImageProgressThread(layer, imageLoader.progress));
  120.         executor.start();
  121.         executor.join();
  122.         next(loadComplete);
  123.     }
  124.     private function loadComplete():void
  125.     {
  126.         var s:Stage,
  127.             data:BitmapData;
  128.         contents = imageLoader.contents.concat();
  129.         imageLoader.contents.length = 0;
  130.         imageLoader.contents = null;
  131.         currentIndex = 0;
  132.         s = layer.stage;
  133.         data = new BitmapData(450450true0);
  134.         canvas = new Bitmap(data);
  135.         canvas.x = (s.stageWidth - canvas.width) / 2;
  136.         canvas.y = (s.stageHeight - canvas.height) / 2;
  137.         layer.addChild(canvas);
  138.         next(changeImage);
  139.     }
  140.     private function changeImage():void
  141.     {
  142.         if (currentIndex >= contents.length)
  143.         {
  144.             currentIndex = 0;
  145.         }
  146.         var image:Bitmap,
  147.             th:Thread;
  148.         image = contents[currentIndex++] as Bitmap;
  149.         th = new HandleImageThread(image, canvas);
  150.         th.start();
  151.         th.join();
  152.         next(changeImage);
  153.     }
  154.     override protected function finalize():void
  155.     {
  156.         layer = null;
  157.         imageLoader = null;
  158.     }
  159. }
  160. internal class WaitAnimationThread extends Thread
  161. {
  162.     private var layer:DisplayObjectContainer;
  163.     private var message:Bitmap;
  164.     public function WaitAnimationThread(layer:DisplayObjectContainer)
  165.     {
  166.         this.layer = layer;
  167.     }
  168.     override protected function run():void
  169.     {
  170.         var s:Stage,
  171.             txt:TextField,
  172.             fmt:TextFormat,
  173.             bmd:BitmapData;
  174.         s = layer.stage;
  175.         fmt = new TextFormat();
  176.         fmt.color = 0x000000;
  177.         fmt.size = 24;
  178.         fmt.font = 'Trebuchet MS';
  179.         txt = new TextField();
  180.         txt.autoSize = TextFieldAutoSize.LEFT;
  181.         txt.defaultTextFormat = fmt;
  182.         txt.text = 'click to start.';
  183.         bmd = new BitmapData(txt.textWidth, txt.textHeight, true0);
  184.         bmd.draw(txt);
  185.         message = new Bitmap(bmd);
  186.         message.blendMode = BlendMode.INVERT;
  187.         message.x = (s.stageWidth - message.width) / 2;
  188.         message.y = (s.stageHeight - message.height) / 2;
  189.         layer.addChild(message);
  190.         event(s, MouseEvent.CLICK, hideMessage);
  191.     }
  192.     private function hideMessage(evt:MouseEvent):void
  193.     {
  194.         new HideMessageThread(message).start();
  195.     }
  196.     override protected function finalize():void
  197.     {
  198.         layer = null;
  199.         message = null;
  200.     }
  201. }
  202. internal class HideMessageThread extends Thread
  203. {
  204.     private var message:DisplayObject;
  205.     private var wrapper:Bitmap;
  206.     private var parent:DisplayObjectContainer;
  207.     private var film:BitmapData;
  208.     private var particles:Vector.<HideMessageParticle>;
  209.     public function HideMessageThread(message:DisplayObject)
  210.     {
  211.         this.message = message;
  212.         this.parent = message.parent;
  213.         this.particles = new Vector.<HideMessageParticle>();
  214.     }
  215.     override protected function run():void
  216.     {
  217.         var s:Stage,
  218.             c:uint,
  219.             w:Number, h:Number,
  220.             offsetX:Number, offsetY:Number,
  221.             i:uint, j:uint,
  222.             bmd:BitmapData;
  223.         s = message.stage;
  224.         bmd = Bitmap(message).bitmapData;
  225.         w = bmd.width;
  226.         h = bmd.height;
  227.         offsetX = message.x;
  228.         offsetY = message.y;
  229.         for (i=0; i<w; i++)
  230.         {
  231.             for (j=0; j<h; j++)
  232.             {
  233.                 c = bmd.getPixel32(i,j);
  234.                 if (!c) continue;
  235.                 particles.push(new HideMessageParticle(offsetX + i, offsetY + j, c));
  236.             }
  237.         }
  238.         bmd.dispose();
  239.         film = new BitmapData(s.stageWidth, s.stageHeight, true0);
  240.         wrapper = new Bitmap(film);
  241.         wrapper.blendMode = BlendMode.INVERT;
  242.         parent.addChild(wrapper);
  243.         parent.removeChild(message);
  244.         next(step);
  245.     }
  246.     private function step():void
  247.     {
  248.         var i:uint,
  249.             l:uint,
  250.             s:Stage,
  251.             p:HideMessageParticle;
  252.         film.lock();
  253.         film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR);
  254.         l = particles.length;
  255.         for (i=0; i<l; i++)
  256.         {
  257.             p = particles[i];
  258.             p.update();
  259.             film.setPixel32(p.x, p.y, p.color);
  260.             if (!film.rect.contains(p.x, p.y))
  261.             {
  262.                 particles.splice(i, 1);
  263.                 i--;
  264.                 l = particles.length;
  265.             }
  266.         }
  267.         film.unlock();
  268.         if (l) next(step);
  269.     }
  270.     override protected function finalize():void
  271.     {
  272.         parent.removeChild(wrapper);
  273.         film.dispose();
  274.         parent = null;
  275.         wrapper = null;
  276.         message = null;
  277.     }
  278. }
  279. internal class LoadImageThread extends Thread
  280. implements IProgressNotifier
  281. {
  282.     public var contents:Array;
  283.     private var mainProgress:MultiProgress;
  284.     private var subProgress:MultiProgress;
  285.     private var jsonLoader:URLLoaderThread;
  286.     private var imageLoader:SerialExecutor;
  287.     public function get progress():IProgress
  288.     {
  289.         return mainProgress;
  290.     }
  291.     public function LoadImageThread()
  292.     {
  293.         var req:URLRequest,
  294.             data:URLVariables;
  295.         req = new URLRequest('http://query.yahooapis.com/v1/public/yql');
  296.         data = new URLVariables();
  297.         data['q'] = "SELECT * FROM flickr.photos.search(10) WHERE user_id='20974929@N02'";
  298.         data['format'] = 'json';
  299.         req.data = data;
  300.         jsonLoader = new URLLoaderThread(req);
  301.         mainProgress = new MultiProgress();
  302.         subProgress = new MultiProgress();
  303.         mainProgress.addProgress(jsonLoader.progress, 0.1);
  304.         mainProgress.addProgress(subProgress);
  305.     }
  306.     override protected function run():void
  307.     {
  308.         jsonLoader.start();
  309.         jsonLoader.join();
  310.         next(loadDataComplete);
  311.     }
  312.     private function loadDataComplete():void
  313.     {
  314.         var json:Object,
  315.             row:Object,
  316.             th:LoaderThread,
  317.             req:URLRequest,
  318.             ctx:LoaderContext,
  319.             flickr:FlickrPhoto;
  320.         json = JSON.decode(jsonLoader.loader.data);
  321.         ctx = new LoaderContext(true);
  322.         imageLoader = new SerialExecutor();
  323.         for each (row in json.query.results.photo)
  324.         {
  325.             flickr = new FlickrPhoto(row);
  326.             req = new URLRequest(flickr.thumbnailURL);
  327.             th = new LoaderThread(req, ctx);
  328.             imageLoader.addThread(th);
  329.             subProgress.addProgress(th.progress);
  330.         }
  331.         imageLoader.start();
  332.         imageLoader.join();
  333.         next(loadImageComplete);
  334.     }
  335.     private function loadImageComplete():void
  336.     {
  337.         var i:uint,
  338.             l:uint,
  339.             th:LoaderThread;
  340.         contents = [];
  341.         l = imageLoader.numThreads;
  342.         for (i=0; i<l; i++)
  343.         {
  344.             th = imageLoader.getThreadAt(i) as LoaderThread;
  345.             contents.push(th.loader.content);
  346.         }
  347.     }
  348.     override protected function finalize():void
  349.     {
  350.         jsonLoader = null;
  351.         imageLoader = null;
  352.     }
  353. }
  354. internal class LoadImageProgressThread extends Thread
  355. {
  356.     private var progress:IProgress;
  357.     private var layer:DisplayObjectContainer;
  358.     private var indicator:HandleIndicatorThread;
  359.     public function LoadImageProgressThread(layer:DisplayObjectContainer, progress:IProgress)
  360.     {
  361.         this.layer = layer;
  362.         this.progress = progress;
  363.     }
  364.     override protected function run():void
  365.     {
  366.         indicator = new HandleIndicatorThread(layer);
  367.         indicator.start();
  368.         next(step);
  369.     }
  370.     private function step():void
  371.     {
  372.         if (progress.isCompleted||progress.isFailed||progress.isCanceled)
  373.         {
  374.             next(shutDown);
  375.             return;
  376.         }
  377.         //  TODO: なにかしらやる。
  378.         var percent:Number = progress.percent;
  379.         if (percent >= 1)
  380.         {
  381.             next(shutDown);
  382.         }
  383.         else
  384.         {
  385.             next(step);
  386.         }
  387.     }
  388.     private function shutDown():void
  389.     {
  390.         indicator.interrupt();
  391.     }
  392.     override protected function finalize():void
  393.     {
  394.         progress = null;
  395.         layer = null;
  396.         indicator = null;
  397.     }
  398. }
  399. internal class HandleImageThread extends Thread
  400. {
  401.     public static const PARTICLE_MARGIN:Number = 6;
  402.     private var original:Bitmap;
  403.     private var destination:Bitmap;
  404.     private var showParticles:Vector.<ShowImageParticle>;
  405.     private var hideParticles:Vector.<HideImageParticle>;
  406.     public function HandleImageThread(original:Bitmap, destination:Bitmap)
  407.     {
  408.         this.original = original;
  409.         this.destination = destination;
  410.         this.showParticles = new Vector.<ShowImageParticle>();
  411.         this.hideParticles = new Vector.<HideImageParticle>();
  412.     }
  413.     override protected function run():void
  414.     {
  415.         var w:Number, h:Number, c:uint,
  416.             tx:Number, ty:Number,
  417.             sx:Number, sy:Number,
  418.             cx:Number, cy:Number,
  419.             angle:Number,
  420.             i:uint, j:uint,
  421.             s:Stage,
  422.             data:BitmapData;
  423.         s = destination.stage;
  424.         data = original.bitmapData;
  425.         w = data.width;
  426.         h = data.height;
  427.         cx = s.stageWidth / 2;
  428.         cy = s.stageHeight / 2;
  429.         for (i=0; i<w; i++)
  430.         {
  431.             for (j=0; j<h; j++)
  432.             {
  433.                 c = data.getPixel32(i, j);
  434.                 if (!c) continue;
  435.                 angle = Math.random() * Math.PI * 2;
  436.                 sx = Math.cos(angle) * 500 + cx;
  437.                 sy = Math.sin(angle) * 500 + cy;
  438.                 tx = i * PARTICLE_MARGIN;
  439.                 ty = j * PARTICLE_MARGIN;
  440.                 showParticles.push(new ShowImageParticle(sx, sy, tx, ty, c));
  441.                 hideParticles.push(new HideImageParticle(tx, ty, sx, sy, c, s.frameRate));
  442.             }
  443.         }
  444.         next(showStep);
  445.     }
  446.     private function showStep():void
  447.     {
  448.         var i:uint,
  449.             l:uint,
  450.             c:uint,
  451.             a:Number,
  452.             f:Boolean,
  453.             p:ShowImageParticle,
  454.             data:BitmapData;
  455.         data = destination.bitmapData;
  456.         data.lock();
  457.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  458.         l = showParticles.length;
  459.         f = false;
  460.         for (i=0; i<l; i++)
  461.         {
  462.             p = showParticles[i];
  463.             if (p.isAlive)
  464.             {
  465.                 f = true;
  466.                 p.update();
  467.             }
  468.             data.setPixel32(p.x, p.y, p.color);
  469.         }
  470.         data.unlock();
  471.         if (!f)
  472.         {
  473.             next(fixedImage);
  474.         }
  475.         else
  476.         {
  477.             next(showStep);
  478.         }
  479.     }
  480.     private function hideStep():void
  481.     {
  482.         var i:uint,
  483.             l:uint,
  484.             c:uint,
  485.             a:Number,
  486.             f:Boolean,
  487.             p:HideImageParticle,
  488.             data:BitmapData;
  489.         data = destination.bitmapData;
  490.         data.lock();
  491.         data.colorTransform(data.rect, new ColorTransform(111, .970000));
  492.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  493.         l = hideParticles.length;
  494.         for (i=0; i<l; i++)
  495.         {
  496.             p = hideParticles[i];
  497.             p.update();
  498.             data.setPixel32(p.x, p.y, p.color);
  499.             if (!data.rect.contains(p.x, p.y))
  500.             {
  501.                 hideParticles.splice(i, 1);
  502.                 i--;
  503.                 l = hideParticles.length;
  504.             }
  505.         }
  506.         data.unlock();
  507.         //trace(p.x, p.y);
  508.         if (l) next(hideStep);
  509.     }
  510.     private function fixedImage():void
  511.     {
  512.         sleep(3000);
  513.         next(hideStep);
  514.     }
  515.     override protected function finalize():void
  516.     {
  517.         original = null;
  518.         destination = null;
  519.         showParticles.length = 0;
  520.         showParticles = null;
  521.         hideParticles.length = 0;
  522.         hideParticles = null;
  523.     }
  524. }
  525. internal class HandleIndicatorThread extends Thread
  526. {
  527.     private var layer:DisplayObjectContainer;
  528.     private var indicator:DisplayObject;
  529.     public function HandleIndicatorThread(layer:DisplayObjectContainer)
  530.     {
  531.         this.layer = layer;
  532.     }
  533.     override protected function run():void
  534.     {
  535.         Mouse.hide();
  536.         layer.stage.mouseChildren = false;
  537.         indicator = new Indicator();
  538.         indicator.x = layer.mouseX;
  539.         indicator.y = layer.mouseY;
  540.         layer.addChild(indicator);
  541.         next(step);
  542.     }
  543.     private function step():void
  544.     {
  545.         if (checkInterrupted()) return;
  546.         indicator.rotation = (indicator.rotation + 360 / indicator.stage.frameRate) % 360;
  547.         indicator.x = layer.mouseX;
  548.         indicator.y = layer.mouseY;
  549.         next(step);
  550.     }
  551.     override protected function finalize():void
  552.     {
  553.         Mouse.show();
  554.         layer.stage.mouseChildren = true;
  555.         layer.removeChild(indicator);
  556.         layer = null;
  557.         indicator = null;
  558.     }
  559. }
  560. internal class HideMessageParticle
  561. {
  562.     public var x:Number;
  563.     public var y:Number;
  564.     public var ax:Number;
  565.     public var ay:Number;
  566.     public var vx:Number;
  567.     public var vy:Number;
  568.     public var color:uint;
  569.     public function HideMessageParticle(x:Number, y:Number, color:Number)
  570.     {
  571.         var len:Number,
  572.             angle:Number;
  573.         len = Math.random() * 5;
  574.         angle = Math.random() * Math.PI * 2;
  575.         this.ax = Math.cos(angle) * len;
  576.         this.ay = Math.sin(angle) * len;
  577.         this.x = x;
  578.         this.y = y;
  579.         this.color = color;
  580.         this.vx = 0;
  581.         this.vy = 0;
  582.     }
  583.     public function update():void
  584.     {
  585.         vx += ax;
  586.         vy += ay;
  587.         x += vx;
  588.         y += vy;
  589.     }
  590. }
  591. import flash.geom.Point;
  592. internal class ShowImageParticle
  593. {
  594.     public var x:Number;
  595.     public var y:Number;
  596.     public var color:uint;
  597.     private var targetX:Number;
  598.     private var targetY:Number;
  599.     private var _isAlive:Boolean;
  600.     public function get isAlive():Boolean
  601.     {
  602.         return _isAlive;
  603.     }
  604.     public function ShowImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint)
  605.     {
  606.         this.x = x;
  607.         this.y = y;
  608.         this.color = color;
  609.         this.targetX = targetX;
  610.         this.targetY = targetY;
  611.         this._isAlive = true;
  612.     }
  613.     public function update():void
  614.     {
  615.         x += (targetX - x) * .05;
  616.         y += (targetY - y) * .05;
  617.         if (Math.abs(targetX - x) < .5 && Math.abs(targetY - y) < .5)
  618.         {
  619.             x = targetX;
  620.             y = targetY;
  621.             _isAlive = false;
  622.         }
  623.     }
  624. }
  625. internal class HideImageParticle
  626. {
  627.     public var x:Number;
  628.     public var y:Number;
  629.     public var color:uint;
  630.     private var vx:Number;
  631.     private var vy:Number;
  632.     private var ax:Number;
  633.     private var ay:Number;
  634.     private var rate:Number;
  635.     public function HideImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint, rate:Number)
  636.     {
  637.         var dx:Number,
  638.             dy:Number,
  639.             len:Number,
  640.             angle:Number;
  641.         dx = targetX - x;
  642.         dy = targetY - y;
  643.         len = 9.8;
  644.         angle = Math.atan2(dy, dx);
  645.         this.x = x;
  646.         this.y = y;
  647.         this.vx = 0;
  648.         this.vy = 0;
  649.         this.ax = Math.cos(angle) * len;
  650.         this.ay = Math.sin(angle) * len;
  651.         this.color = color;
  652.         this.rate = rate;
  653.     }
  654.     public function update():void
  655.     {
  656.         vx += ax / rate;
  657.         vy += ay / rate;
  658.         x += vx;
  659.         y += vy;
  660.     }
  661. }
  662. internal class FlickrPhoto
  663. {
  664.     private var _id:String;
  665.     public function get id():String
  666.     {
  667.         return _id;
  668.     }
  669.     private var _secret:String;
  670.     public function get secret():String
  671.     {
  672.         return _secret;
  673.     }
  674.     private var _server:String;
  675.     public function get server():String
  676.     {
  677.         return _server;
  678.     }
  679.     private var _farm:String;
  680.     public function get farm():String
  681.     {
  682.         return _farm;
  683.     }
  684.     public function get thumbnailURL():String
  685.     {
  686.         return ['http://farm', farm, '.static.flickr.com/', server, '/', id, '_', secret, '_s.jpg'].join('');
  687.     }
  688.     public function FlickrPhoto(data:Object)
  689.     {
  690.         this._id = data['id'] || '';
  691.         this._secret = data['secret'] || '';
  692.         this._server = data['server'] || '';
  693.         this._farm = data['farm'] || '';
  694.     }
  695. }
noswf
  1. // forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
  2. /**
  3.  *  ActionScript3 Thread library のサンプルになれば幸いです :-)
  4.  *
  5.  *  @see    http://www.flickr.com/photos/auroracrowley/
  6.  *  @see    http://www.libspark.org/htdocs/as3/thread-files/document/
  7.  */
  8. package
  9. {
  10.     import flash.display.Sprite;
  11.     import flash.display.StageAlign;
  12.     import flash.display.StageQuality;
  13.     import flash.display.StageScaleMode;
  14.     import flash.events.Event;
  15.     import org.libspark.thread.EnterFrameThreadExecutor;
  16.     import org.libspark.thread.Thread;
  17.     [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]
  18.     public class Tmp extends Sprite
  19.     {
  20.         public function Tmp()
  21.         {
  22.             addEventListener(Event.ADDED_TO_STAGE, initialize);
  23.         }
  24.         private function initialize(evt:Event):void
  25.         {
  26.             removeEventListener(Event.ADDED_TO_STAGE, initialize);
  27.             stage.align = StageAlign.TOP_LEFT;
  28.             stage.quality = StageQuality.HIGH;
  29.             stage.scaleMode = StageScaleMode.NO_SCALE;
  30.             if (!Thread.isReady)
  31.             {
  32.                 Thread.initialize(new EnterFrameThreadExecutor());
  33.             }
  34.             new MainThread(this).start();
  35.         }
  36.     }
  37. }
  38. import flash.display.Bitmap;
  39. import flash.display.BitmapData;
  40. import flash.display.BlendMode;
  41. import flash.display.DisplayObject;
  42. import flash.display.DisplayObjectContainer;
  43. import flash.display.Stage;
  44. import flash.events.MouseEvent;
  45. import flash.filters.BitmapFilter;
  46. import flash.filters.BitmapFilterQuality;
  47. import flash.filters.BlurFilter;
  48. import flash.geom.ColorTransform;
  49. import flash.geom.Point;
  50. import flash.net.URLRequest;
  51. import flash.net.URLVariables;
  52. import flash.system.LoaderContext;
  53. import flash.text.TextField;
  54. import flash.text.TextFieldAutoSize;
  55. import flash.text.TextFormat;
  56. import flash.ui.Mouse;
  57. import com.adobe.serialization.json.JSON;
  58. import org.libspark.thread.Thread;
  59. import org.libspark.thread.threads.display.LoaderThread;
  60. import org.libspark.thread.threads.net.URLLoaderThread;
  61. import org.libspark.thread.utils.IProgress;
  62. import org.libspark.thread.utils.IProgressNotifier;
  63. import org.libspark.thread.utils.MultiProgress;
  64. import org.libspark.thread.utils.ParallelExecutor;
  65. import org.libspark.thread.utils.SerialExecutor;
  66. internal var FILTER_BLUR:BlurFilter = new BlurFilter(44, BitmapFilterQuality.LOW);
  67. internal var POINT_ZERO:Point = new Point();
  68. import flash.display.Shape;
  69. internal class Indicator extends Shape
  70. {
  71.     public function Indicator()
  72.     {
  73.         var i:uint,
  74.             cx:Number, cy:Number,
  75.             numNeedles:uint = 12,
  76.             innerR:Number = 7,
  77.             outerR:Number = 5,
  78.             cAngle:Number = -Math.PI / 2,
  79.             nAngle:Number;
  80.         nAngle = Math.PI * 2 / numNeedles;
  81.         for (i=0; i<numNeedles; i++)
  82.         {
  83.             cAngle += nAngle;
  84.             cx = Math.cos(cAngle) * innerR;
  85.             cy = Math.sin(cAngle) * innerR;
  86.             graphics.moveTo(cx, cy);
  87.             cx = Math.cos(cAngle) * outerR;
  88.             cy = Math.sin(cAngle) * outerR;
  89.             graphics.lineStyle(2, 0xffffff, i/numNeedles);
  90.             graphics.lineTo(cx, cy);
  91.         }
  92.     }
  93. }
  94. internal class MainThread extends Thread
  95. {
  96.     private var layer:DisplayObjectContainer;
  97.     private var imageLoader:LoadImageThread;
  98.     private var contents:Array;
  99.     private var canvas:Bitmap;
  100.     private var currentIndex:uint;
  101.     public function MainThread(layer:DisplayObjectContainer)
  102.     {
  103.         this.layer = layer;
  104.     }
  105.     override protected function run():void
  106.     {
  107.         var t:Thread;
  108.         t = new WaitAnimationThread(layer);
  109.         t.start();
  110.         t.join();
  111.         next(loadImage);
  112.     }
  113.     private function loadImage():void
  114.     {
  115.         var executor:ParallelExecutor;
  116.         executor = new ParallelExecutor();
  117.         imageLoader = new LoadImageThread();
  118.         executor.addThread(imageLoader);
  119.         executor.addThread(new LoadImageProgressThread(layer, imageLoader.progress));
  120.         executor.start();
  121.         executor.join();
  122.         next(loadComplete);
  123.     }
  124.     private function loadComplete():void
  125.     {
  126.         var s:Stage,
  127.             data:BitmapData;
  128.         contents = imageLoader.contents.concat();
  129.         imageLoader.contents.length = 0;
  130.         imageLoader.contents = null;
  131.         currentIndex = 0;
  132.         s = layer.stage;
  133.         data = new BitmapData(450450true0);
  134.         canvas = new Bitmap(data);
  135.         canvas.x = (s.stageWidth - canvas.width) / 2;
  136.         canvas.y = (s.stageHeight - canvas.height) / 2;
  137.         layer.addChild(canvas);
  138.         next(changeImage);
  139.     }
  140.     private function changeImage():void
  141.     {
  142.         if (currentIndex >= contents.length)
  143.         {
  144.             currentIndex = 0;
  145.         }
  146.         var image:Bitmap,
  147.             th:Thread;
  148.         image = contents[currentIndex++] as Bitmap;
  149.         th = new HandleImageThread(image, canvas);
  150.         th.start();
  151.         th.join();
  152.         next(changeImage);
  153.     }
  154.     override protected function finalize():void
  155.     {
  156.         layer = null;
  157.         imageLoader = null;
  158.     }
  159. }
  160. internal class WaitAnimationThread extends Thread
  161. {
  162.     private var layer:DisplayObjectContainer;
  163.     private var message:Bitmap;
  164.     public function WaitAnimationThread(layer:DisplayObjectContainer)
  165.     {
  166.         this.layer = layer;
  167.     }
  168.     override protected function run():void
  169.     {
  170.         var s:Stage,
  171.             txt:TextField,
  172.             fmt:TextFormat,
  173.             bmd:BitmapData;
  174.         s = layer.stage;
  175.         fmt = new TextFormat();
  176.         fmt.color = 0x000000;
  177.         fmt.size = 24;
  178.         fmt.font = 'Trebuchet MS';
  179.         txt = new TextField();
  180.         txt.autoSize = TextFieldAutoSize.LEFT;
  181.         txt.defaultTextFormat = fmt;
  182.         txt.text = 'click to start.';
  183.         bmd = new BitmapData(txt.textWidth, txt.textHeight, true0);
  184.         bmd.draw(txt);
  185.         message = new Bitmap(bmd);
  186.         message.blendMode = BlendMode.INVERT;
  187.         message.x = (s.stageWidth - message.width) / 2;
  188.         message.y = (s.stageHeight - message.height) / 2;
  189.         layer.addChild(message);
  190.         event(s, MouseEvent.CLICK, hideMessage);
  191.     }
  192.     private function hideMessage(evt:MouseEvent):void
  193.     {
  194.         new HideMessageThread(message).start();
  195.     }
  196.     override protected function finalize():void
  197.     {
  198.         layer = null;
  199.         message = null;
  200.     }
  201. }
  202. internal class HideMessageThread extends Thread
  203. {
  204.     private var message:DisplayObject;
  205.     private var wrapper:Bitmap;
  206.     private var parent:DisplayObjectContainer;
  207.     private var film:BitmapData;
  208.     private var particles:Vector.<HideMessageParticle>;
  209.     public function HideMessageThread(message:DisplayObject)
  210.     {
  211.         this.message = message;
  212.         this.parent = message.parent;
  213.         this.particles = new Vector.<HideMessageParticle>();
  214.     }
  215.     override protected function run():void
  216.     {
  217.         var s:Stage,
  218.             c:uint,
  219.             w:Number, h:Number,
  220.             offsetX:Number, offsetY:Number,
  221.             i:uint, j:uint,
  222.             bmd:BitmapData;
  223.         s = message.stage;
  224.         bmd = Bitmap(message).bitmapData;
  225.         w = bmd.width;
  226.         h = bmd.height;
  227.         offsetX = message.x;
  228.         offsetY = message.y;
  229.         for (i=0; i<w; i++)
  230.         {
  231.             for (j=0; j<h; j++)
  232.             {
  233.                 c = bmd.getPixel32(i,j);
  234.                 if (!c) continue;
  235.                 particles.push(new HideMessageParticle(offsetX + i, offsetY + j, c));
  236.             }
  237.         }
  238.         bmd.dispose();
  239.         film = new BitmapData(s.stageWidth, s.stageHeight, true0);
  240.         wrapper = new Bitmap(film);
  241.         wrapper.blendMode = BlendMode.INVERT;
  242.         parent.addChild(wrapper);
  243.         parent.removeChild(message);
  244.         next(step);
  245.     }
  246.     private function step():void
  247.     {
  248.         var i:uint,
  249.             l:uint,
  250.             s:Stage,
  251.             p:HideMessageParticle;
  252.         film.lock();
  253.         film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR);
  254.         l = particles.length;
  255.         for (i=0; i<l; i++)
  256.         {
  257.             p = particles[i];
  258.             p.update();
  259.             film.setPixel32(p.x, p.y, p.color);
  260.             if (!film.rect.contains(p.x, p.y))
  261.             {
  262.                 particles.splice(i, 1);
  263.                 i--;
  264.                 l = particles.length;
  265.             }
  266.         }
  267.         film.unlock();
  268.         if (l) next(step);
  269.     }
  270.     override protected function finalize():void
  271.     {
  272.         parent.removeChild(wrapper);
  273.         film.dispose();
  274.         parent = null;
  275.         wrapper = null;
  276.         message = null;
  277.     }
  278. }
  279. internal class LoadImageThread extends Thread
  280. implements IProgressNotifier
  281. {
  282.     public var contents:Array;
  283.     private var mainProgress:MultiProgress;
  284.     private var subProgress:MultiProgress;
  285.     private var jsonLoader:URLLoaderThread;
  286.     private var imageLoader:SerialExecutor;
  287.     public function get progress():IProgress
  288.     {
  289.         return mainProgress;
  290.     }
  291.     public function LoadImageThread()
  292.     {
  293.         var req:URLRequest,
  294.             data:URLVariables;
  295.         req = new URLRequest('http://query.yahooapis.com/v1/public/yql');
  296.         data = new URLVariables();
  297.         data['q'] = "SELECT * FROM flickr.photos.search(10) WHERE user_id='25105339@N07'";
  298.         data['format'] = 'json';
  299.         req.data = data;
  300.         jsonLoader = new URLLoaderThread(req);
  301.         mainProgress = new MultiProgress();
  302.         subProgress = new MultiProgress();
  303.         mainProgress.addProgress(jsonLoader.progress, 0.1);
  304.         mainProgress.addProgress(subProgress);
  305.     }
  306.     override protected function run():void
  307.     {
  308.         jsonLoader.start();
  309.         jsonLoader.join();
  310.         next(loadDataComplete);
  311.     }
  312.     private function loadDataComplete():void
  313.     {
  314.         var json:Object,
  315.             row:Object,
  316.             th:LoaderThread,
  317.             req:URLRequest,
  318.             ctx:LoaderContext,
  319.             flickr:FlickrPhoto;
  320.         json = JSON.decode(jsonLoader.loader.data);
  321.         ctx = new LoaderContext(true);
  322.         imageLoader = new SerialExecutor();
  323.         for each (row in json.query.results.photo)
  324.         {
  325.             flickr = new FlickrPhoto(row);
  326.             req = new URLRequest(flickr.thumbnailURL);
  327.             th = new LoaderThread(req, ctx);
  328.             imageLoader.addThread(th);
  329.             subProgress.addProgress(th.progress);
  330.         }
  331.         imageLoader.start();
  332.         imageLoader.join();
  333.         next(loadImageComplete);
  334.     }
  335.     private function loadImageComplete():void
  336.     {
  337.         var i:uint,
  338.             l:uint,
  339.             th:LoaderThread;
  340.         contents = [];
  341.         l = imageLoader.numThreads;
  342.         for (i=0; i<l; i++)
  343.         {
  344.             th = imageLoader.getThreadAt(i) as LoaderThread;
  345.             contents.push(th.loader.content);
  346.         }
  347.     }
  348.     override protected function finalize():void
  349.     {
  350.         jsonLoader = null;
  351.         imageLoader = null;
  352.     }
  353. }
  354. internal class LoadImageProgressThread extends Thread
  355. {
  356.     private var progress:IProgress;
  357.     private var layer:DisplayObjectContainer;
  358.     private var indicator:HandleIndicatorThread;
  359.     public function LoadImageProgressThread(layer:DisplayObjectContainer, progress:IProgress)
  360.     {
  361.         this.layer = layer;
  362.         this.progress = progress;
  363.     }
  364.     override protected function run():void
  365.     {
  366.         indicator = new HandleIndicatorThread(layer);
  367.         indicator.start();
  368.         next(step);
  369.     }
  370.     private function step():void
  371.     {
  372.         if (progress.isCompleted||progress.isFailed||progress.isCanceled)
  373.         {
  374.             next(shutDown);
  375.             return;
  376.         }
  377.         //  TODO: なにかしらやる。
  378.         var percent:Number = progress.percent;
  379.         if (percent >= 1)
  380.         {
  381.             next(shutDown);
  382.         }
  383.         else
  384.         {
  385.             next(step);
  386.         }
  387.     }
  388.     private function shutDown():void
  389.     {
  390.         indicator.interrupt();
  391.     }
  392.     override protected function finalize():void
  393.     {
  394.         progress = null;
  395.         layer = null;
  396.         indicator = null;
  397.     }
  398. }
  399. internal class HandleImageThread extends Thread
  400. {
  401.     public static const PARTICLE_MARGIN:Number = 6;
  402.     private var original:Bitmap;
  403.     private var destination:Bitmap;
  404.     private var showParticles:Vector.<ShowImageParticle>;
  405.     private var hideParticles:Vector.<HideImageParticle>;
  406.     public function HandleImageThread(original:Bitmap, destination:Bitmap)
  407.     {
  408.         this.original = original;
  409.         this.destination = destination;
  410.         this.showParticles = new Vector.<ShowImageParticle>();
  411.         this.hideParticles = new Vector.<HideImageParticle>();
  412.     }
  413.     override protected function run():void
  414.     {
  415.         var w:Number, h:Number, c:uint,
  416.             tx:Number, ty:Number,
  417.             sx:Number, sy:Number,
  418.             cx:Number, cy:Number,
  419.             angle:Number,
  420.             i:uint, j:uint,
  421.             s:Stage,
  422.             data:BitmapData;
  423.         s = destination.stage;
  424.         data = original.bitmapData;
  425.         w = data.width;
  426.         h = data.height;
  427.         cx = s.stageWidth / 2;
  428.         cy = s.stageHeight / 2;
  429.         for (i=0; i<w; i++)
  430.         {
  431.             for (j=0; j<h; j++)
  432.             {
  433.                 c = data.getPixel32(i, j);
  434.                 if (!c) continue;
  435.                 angle = Math.random() * Math.PI * 2;
  436.                 sx = Math.cos(angle) * 500 + cx;
  437.                 sy = Math.sin(angle) * 500 + cy;
  438.                 tx = i * PARTICLE_MARGIN;
  439.                 ty = j * PARTICLE_MARGIN;
  440.                 showParticles.push(new ShowImageParticle(sx, sy, tx, ty, c));
  441.                 hideParticles.push(new HideImageParticle(tx, ty, sx, sy, c, s.frameRate));
  442.             }
  443.         }
  444.         next(showStep);
  445.     }
  446.     private function showStep():void
  447.     {
  448.         var i:uint,
  449.             l:uint,
  450.             c:uint,
  451.             a:Number,
  452.             f:Boolean,
  453.             p:ShowImageParticle,
  454.             data:BitmapData;
  455.         data = destination.bitmapData;
  456.         data.lock();
  457.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  458.         l = showParticles.length;
  459.         f = false;
  460.         for (i=0; i<l; i++)
  461.         {
  462.             p = showParticles[i];
  463.             if (p.isAlive)
  464.             {
  465.                 f = true;
  466.                 p.update();
  467.             }
  468.             data.setPixel32(p.x, p.y, p.color);
  469.         }
  470.         data.unlock();
  471.         if (!f)
  472.         {
  473.             next(fixedImage);
  474.         }
  475.         else
  476.         {
  477.             next(showStep);
  478.         }
  479.     }
  480.     private function hideStep():void
  481.     {
  482.         var i:uint,
  483.             l:uint,
  484.             c:uint,
  485.             a:Number,
  486.             f:Boolean,
  487.             p:HideImageParticle,
  488.             data:BitmapData;
  489.         data = destination.bitmapData;
  490.         data.lock();
  491.         data.colorTransform(data.rect, new ColorTransform(111, .970000));
  492.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  493.         l = hideParticles.length;
  494.         for (i=0; i<l; i++)
  495.         {
  496.             p = hideParticles[i];
  497.             p.update();
  498.             data.setPixel32(p.x, p.y, p.color);
  499.             if (!data.rect.contains(p.x, p.y))
  500.             {
  501.                 hideParticles.splice(i, 1);
  502.                 i--;
  503.                 l = hideParticles.length;
  504.             }
  505.         }
  506.         data.unlock();
  507.         //trace(p.x, p.y);
  508.         if (l) next(hideStep);
  509.     }
  510.     private function fixedImage():void
  511.     {
  512.         sleep(3000);
  513.         next(hideStep);
  514.     }
  515.     override protected function finalize():void
  516.     {
  517.         original = null;
  518.         destination = null;
  519.         showParticles.length = 0;
  520.         showParticles = null;
  521.         hideParticles.length = 0;
  522.         hideParticles = null;
  523.     }
  524. }
  525. internal class HandleIndicatorThread extends Thread
  526. {
  527.     private var layer:DisplayObjectContainer;
  528.     private var indicator:DisplayObject;
  529.     public function HandleIndicatorThread(layer:DisplayObjectContainer)
  530.     {
  531.         this.layer = layer;
  532.     }
  533.     override protected function run():void
  534.     {
  535.         Mouse.hide();
  536.         layer.stage.mouseChildren = false;
  537.         indicator = new Indicator();
  538.         indicator.x = layer.mouseX;
  539.         indicator.y = layer.mouseY;
  540.         layer.addChild(indicator);
  541.         next(step);
  542.     }
  543.     private function step():void
  544.     {
  545.         if (checkInterrupted()) return;
  546.         indicator.rotation = (indicator.rotation + 360 / indicator.stage.frameRate) % 360;
  547.         indicator.x = layer.mouseX;
  548.         indicator.y = layer.mouseY;
  549.         next(step);
  550.     }
  551.     override protected function finalize():void
  552.     {
  553.         Mouse.show();
  554.         layer.stage.mouseChildren = true;
  555.         layer.removeChild(indicator);
  556.         layer = null;
  557.         indicator = null;
  558.     }
  559. }
  560. internal class HideMessageParticle
  561. {
  562.     public var x:Number;
  563.     public var y:Number;
  564.     public var ax:Number;
  565.     public var ay:Number;
  566.     public var vx:Number;
  567.     public var vy:Number;
  568.     public var color:uint;
  569.     public function HideMessageParticle(x:Number, y:Number, color:Number)
  570.     {
  571.         var len:Number,
  572.             angle:Number;
  573.         len = Math.random() * 5;
  574.         angle = Math.random() * Math.PI * 2;
  575.         this.ax = Math.cos(angle) * len;
  576.         this.ay = Math.sin(angle) * len;
  577.         this.x = x;
  578.         this.y = y;
  579.         this.color = color;
  580.         this.vx = 0;
  581.         this.vy = 0;
  582.     }
  583.     public function update():void
  584.     {
  585.         vx += ax;
  586.         vy += ay;
  587.         x += vx;
  588.         y += vy;
  589.     }
  590. }
  591. import flash.geom.Point;
  592. internal class ShowImageParticle
  593. {
  594.     public var x:Number;
  595.     public var y:Number;
  596.     public var color:uint;
  597.     private var targetX:Number;
  598.     private var targetY:Number;
  599.     private var _isAlive:Boolean;
  600.     public function get isAlive():Boolean
  601.     {
  602.         return _isAlive;
  603.     }
  604.     public function ShowImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint)
  605.     {
  606.         this.x = x;
  607.         this.y = y;
  608.         this.color = color;
  609.         this.targetX = targetX;
  610.         this.targetY = targetY;
  611.         this._isAlive = true;
  612.     }
  613.     public function update():void
  614.     {
  615.         x += (targetX - x) * .05;
  616.         y += (targetY - y) * .05;
  617.         if (Math.abs(targetX - x) < .5 && Math.abs(targetY - y) < .5)
  618.         {
  619.             x = targetX;
  620.             y = targetY;
  621.             _isAlive = false;
  622.         }
  623.     }
  624. }
  625. internal class HideImageParticle
  626. {
  627.     public var x:Number;
  628.     public var y:Number;
  629.     public var color:uint;
  630.     private var vx:Number;
  631.     private var vy:Number;
  632.     private var ax:Number;
  633.     private var ay:Number;
  634.     private var rate:Number;
  635.     public function HideImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint, rate:Number)
  636.     {
  637.         var dx:Number,
  638.             dy:Number,
  639.             len:Number,
  640.             angle:Number;
  641.         dx = targetX - x;
  642.         dy = targetY - y;
  643.         len = 9.8;
  644.         angle = Math.atan2(dy, dx);
  645.         this.x = x;
  646.         this.y = y;
  647.         this.vx = 0;
  648.         this.vy = 0;
  649.         this.ax = Math.cos(angle) * len;
  650.         this.ay = Math.sin(angle) * len;
  651.         this.color = color;
  652.         this.rate = rate;
  653.     }
  654.     public function update():void
  655.     {
  656.         vx += ax / rate;
  657.         vy += ay / rate;
  658.         x += vx;
  659.         y += vy;
  660.     }
  661. }
  662. internal class FlickrPhoto
  663. {
  664.     private var _id:String;
  665.     public function get id():String
  666.     {
  667.         return _id;
  668.     }
  669.     private var _secret:String;
  670.     public function get secret():String
  671.     {
  672.         return _secret;
  673.     }
  674.     private var _server:String;
  675.     public function get server():String
  676.     {
  677.         return _server;
  678.     }
  679.     private var _farm:String;
  680.     public function get farm():String
  681.     {
  682.         return _farm;
  683.     }
  684.     public function get thumbnailURL():String
  685.     {
  686.         return ['http://farm', farm, '.static.flickr.com/', server, '/', id, '_', secret, '_s.jpg'].join('');
  687.     }
  688.     public function FlickrPhoto(data:Object)
  689.     {
  690.         this._id = data['id'] || '';
  691.         this._secret = data['secret'] || '';
  692.         this._server = data['server'] || '';
  693.         this._farm = data['farm'] || '';
  694.     }
  695. }
noswf
  1. // forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
  2. /**
  3.  *  ActionScript3 Thread library のサンプルになれば幸いです :-)
  4.  *
  5.  *  @see    http://www.flickr.com/photos/auroracrowley/
  6.  *  @see    http://www.libspark.org/htdocs/as3/thread-files/document/
  7.  */
  8. package
  9. {
  10.     import flash.display.Sprite;
  11.     import flash.display.StageAlign;
  12.     import flash.display.StageQuality;
  13.     import flash.display.StageScaleMode;
  14.     import flash.events.Event;
  15.     import org.libspark.thread.EnterFrameThreadExecutor;
  16.     import org.libspark.thread.Thread;
  17.     [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]
  18.     public class Tmp extends Sprite
  19.     {
  20.         public function Tmp()
  21.         {
  22.             addEventListener(Event.ADDED_TO_STAGE, initialize);
  23.         }
  24.         private function initialize(evt:Event):void
  25.         {
  26.             removeEventListener(Event.ADDED_TO_STAGE, initialize);
  27.             stage.align = StageAlign.TOP_LEFT;
  28.             stage.quality = StageQuality.HIGH;
  29.             stage.scaleMode = StageScaleMode.NO_SCALE;
  30.             if (!Thread.isReady)
  31.             {
  32.                 Thread.initialize(new EnterFrameThreadExecutor());
  33.             }
  34.             new MainThread(this).start();
  35.         }
  36.     }
  37. }
  38. import flash.display.Bitmap;
  39. import flash.display.BitmapData;
  40. import flash.display.BlendMode;
  41. import flash.display.DisplayObject;
  42. import flash.display.DisplayObjectContainer;
  43. import flash.display.Stage;
  44. import flash.events.MouseEvent;
  45. import flash.filters.BitmapFilter;
  46. import flash.filters.BitmapFilterQuality;
  47. import flash.filters.BlurFilter;
  48. import flash.geom.ColorTransform;
  49. import flash.geom.Point;
  50. import flash.net.URLRequest;
  51. import flash.net.URLVariables;
  52. import flash.system.LoaderContext;
  53. import flash.text.TextField;
  54. import flash.text.TextFieldAutoSize;
  55. import flash.text.TextFormat;
  56. import flash.ui.Mouse;
  57. import com.adobe.serialization.json.JSON;
  58. import org.libspark.thread.Thread;
  59. import org.libspark.thread.threads.display.LoaderThread;
  60. import org.libspark.thread.threads.net.URLLoaderThread;
  61. import org.libspark.thread.utils.IProgress;
  62. import org.libspark.thread.utils.IProgressNotifier;
  63. import org.libspark.thread.utils.MultiProgress;
  64. import org.libspark.thread.utils.ParallelExecutor;
  65. import org.libspark.thread.utils.SerialExecutor;
  66. internal var FILTER_BLUR:BlurFilter = new BlurFilter(44, BitmapFilterQuality.LOW);
  67. internal var POINT_ZERO:Point = new Point();
  68. import flash.display.Shape;
  69. internal class Indicator extends Shape
  70. {
  71.     public function Indicator()
  72.     {
  73.         var i:uint,
  74.             cx:Number, cy:Number,
  75.             numNeedles:uint = 12,
  76.             innerR:Number = 7,
  77.             outerR:Number = 5,
  78.             cAngle:Number = -Math.PI / 2,
  79.             nAngle:Number;
  80.         nAngle = Math.PI * 2 / numNeedles;
  81.         for (i=0; i<numNeedles; i++)
  82.         {
  83.             cAngle += nAngle;
  84.             cx = Math.cos(cAngle) * innerR;
  85.             cy = Math.sin(cAngle) * innerR;
  86.             graphics.moveTo(cx, cy);
  87.             cx = Math.cos(cAngle) * outerR;
  88.             cy = Math.sin(cAngle) * outerR;
  89.             graphics.lineStyle(2, 0xffffff, i/numNeedles);
  90.             graphics.lineTo(cx, cy);
  91.         }
  92.     }
  93. }
  94. internal class MainThread extends Thread
  95. {
  96.     private var layer:DisplayObjectContainer;
  97.     private var imageLoader:LoadImageThread;
  98.     private var contents:Array;
  99.     private var canvas:Bitmap;
  100.     private var currentIndex:uint;
  101.     public function MainThread(layer:DisplayObjectContainer)
  102.     {
  103.         this.layer = layer;
  104.     }
  105.     override protected function run():void
  106.     {
  107.         var t:Thread;
  108.         t = new WaitAnimationThread(layer);
  109.         t.start();
  110.         t.join();
  111.         next(loadImage);
  112.     }
  113.     private function loadImage():void
  114.     {
  115.         var executor:ParallelExecutor;
  116.         executor = new ParallelExecutor();
  117.         imageLoader = new LoadImageThread();
  118.         executor.addThread(imageLoader);
  119.         executor.addThread(new LoadImageProgressThread(layer, imageLoader.progress));
  120.         executor.start();
  121.         executor.join();
  122.         next(loadComplete);
  123.     }
  124.     private function loadComplete():void
  125.     {
  126.         var s:Stage,
  127.             data:BitmapData;
  128.         contents = imageLoader.contents.concat();
  129.         imageLoader.contents.length = 0;
  130.         imageLoader.contents = null;
  131.         currentIndex = 0;
  132.         s = layer.stage;
  133.         data = new BitmapData(450450true0);
  134.         canvas = new Bitmap(data);
  135.         canvas.x = (s.stageWidth - canvas.width) / 2;
  136.         canvas.y = (s.stageHeight - canvas.height) / 2;
  137.         layer.addChild(canvas);
  138.         next(changeImage);
  139.     }
  140.     private function changeImage():void
  141.     {
  142.         if (currentIndex >= contents.length)
  143.         {
  144.             currentIndex = 0;
  145.         }
  146.         var image:Bitmap,
  147.             th:Thread;
  148.         image = contents[currentIndex++] as Bitmap;
  149.         th = new HandleImageThread(image, canvas);
  150.         th.start();
  151.         th.join();
  152.         next(changeImage);
  153.     }
  154.     override protected function finalize():void
  155.     {
  156.         layer = null;
  157.         imageLoader = null;
  158.     }
  159. }
  160. internal class WaitAnimationThread extends Thread
  161. {
  162.     private var layer:DisplayObjectContainer;
  163.     private var message:Bitmap;
  164.     public function WaitAnimationThread(layer:DisplayObjectContainer)
  165.     {
  166.         this.layer = layer;
  167.     }
  168.     override protected function run():void
  169.     {
  170.         var s:Stage,
  171.             txt:TextField,
  172.             fmt:TextFormat,
  173.             bmd:BitmapData;
  174.         s = layer.stage;
  175.         fmt = new TextFormat();
  176.         fmt.color = 0x000000;
  177.         fmt.size = 24;
  178.         fmt.font = 'Trebuchet MS';
  179.         txt = new TextField();
  180.         txt.autoSize = TextFieldAutoSize.LEFT;
  181.         txt.defaultTextFormat = fmt;
  182.         txt.text = 'click to start.';
  183.         bmd = new BitmapData(txt.textWidth, txt.textHeight, true0);
  184.         bmd.draw(txt);
  185.         message = new Bitmap(bmd);
  186.         message.blendMode = BlendMode.INVERT;
  187.         message.x = (s.stageWidth - message.width) / 2;
  188.         message.y = (s.stageHeight - message.height) / 2;
  189.         layer.addChild(message);
  190.         event(s, MouseEvent.CLICK, hideMessage);
  191.     }
  192.     private function hideMessage(evt:MouseEvent):void
  193.     {
  194.         new HideMessageThread(message).start();
  195.     }
  196.     override protected function finalize():void
  197.     {
  198.         layer = null;
  199.         message = null;
  200.     }
  201. }
  202. internal class HideMessageThread extends Thread
  203. {
  204.     private var message:DisplayObject;
  205.     private var wrapper:Bitmap;
  206.     private var parent:DisplayObjectContainer;
  207.     private var film:BitmapData;
  208.     private var particles:Vector.<HideMessageParticle>;
  209.     public function HideMessageThread(message:DisplayObject)
  210.     {
  211.         this.message = message;
  212.         this.parent = message.parent;
  213.         this.particles = new Vector.<HideMessageParticle>();
  214.     }
  215.     override protected function run():void
  216.     {
  217.         var s:Stage,
  218.             c:uint,
  219.             w:Number, h:Number,
  220.             offsetX:Number, offsetY:Number,
  221.             i:uint, j:uint,
  222.             bmd:BitmapData;
  223.         s = message.stage;
  224.         bmd = Bitmap(message).bitmapData;
  225.         w = bmd.width;
  226.         h = bmd.height;
  227.         offsetX = message.x;
  228.         offsetY = message.y;
  229.         for (i=0; i<w; i++)
  230.         {
  231.             for (j=0; j<h; j++)
  232.             {
  233.                 c = bmd.getPixel32(i,j);
  234.                 if (!c) continue;
  235.                 particles.push(new HideMessageParticle(offsetX + i, offsetY + j, c));
  236.             }
  237.         }
  238.         bmd.dispose();
  239.         film = new BitmapData(s.stageWidth, s.stageHeight, true0);
  240.         wrapper = new Bitmap(film);
  241.         wrapper.blendMode = BlendMode.INVERT;
  242.         parent.addChild(wrapper);
  243.         parent.removeChild(message);
  244.         next(step);
  245.     }
  246.     private function step():void
  247.     {
  248.         var i:uint,
  249.             l:uint,
  250.             s:Stage,
  251.             p:HideMessageParticle;
  252.         film.lock();
  253.         film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR);
  254.         l = particles.length;
  255.         for (i=0; i<l; i++)
  256.         {
  257.             p = particles[i];
  258.             p.update();
  259.             film.setPixel32(p.x, p.y, p.color);
  260.             if (!film.rect.contains(p.x, p.y))
  261.             {
  262.                 particles.splice(i, 1);
  263.                 i--;
  264.                 l = particles.length;
  265.             }
  266.         }
  267.         film.unlock();
  268.         if (l) next(step);
  269.     }
  270.     override protected function finalize():void
  271.     {
  272.         parent.removeChild(wrapper);
  273.         film.dispose();
  274.         parent = null;
  275.         wrapper = null;
  276.         message = null;
  277.     }
  278. }
  279. internal class LoadImageThread extends Thread
  280. implements IProgressNotifier
  281. {
  282.     public var contents:Array;
  283.     private var mainProgress:MultiProgress;
  284.     private var subProgress:MultiProgress;
  285.     private var jsonLoader:URLLoaderThread;
  286.     private var imageLoader:SerialExecutor;
  287.     public function get progress():IProgress
  288.     {
  289.         return mainProgress;
  290.     }
  291.     public function LoadImageThread()
  292.     {
  293.         var req:URLRequest,
  294.             data:URLVariables;
  295.         req = new URLRequest('http://query.yahooapis.com/v1/public/yql');
  296.         data = new URLVariables();
  297.         data['q'] = "SELECT * FROM flickr.photos.search(10) WHERE user_id='25105339@N07'";
  298.         data['format'] = 'json';
  299.         req.data = data;
  300.         jsonLoader = new URLLoaderThread(req);
  301.         mainProgress = new MultiProgress();
  302.         subProgress = new MultiProgress();
  303.         mainProgress.addProgress(jsonLoader.progress, 0.1);
  304.         mainProgress.addProgress(subProgress);
  305.     }
  306.     override protected function run():void
  307.     {
  308.         jsonLoader.start();
  309.         jsonLoader.join();
  310.         next(loadDataComplete);
  311.     }
  312.     private function loadDataComplete():void
  313.     {
  314.         var json:Object,
  315.             row:Object,
  316.             th:LoaderThread,
  317.             req:URLRequest,
  318.             ctx:LoaderContext,
  319.             flickr:FlickrPhoto;
  320.         json = JSON.decode(jsonLoader.loader.data);
  321.         ctx = new LoaderContext(true);
  322.         imageLoader = new SerialExecutor();
  323.         for each (row in json.query.results.photo)
  324.         {
  325.             flickr = new FlickrPhoto(row);
  326.             req = new URLRequest(flickr.thumbnailURL);
  327.             th = new LoaderThread(req, ctx);
  328.             imageLoader.addThread(th);
  329.             subProgress.addProgress(th.progress);
  330.         }
  331.         imageLoader.start();
  332.         imageLoader.join();
  333.         next(loadImageComplete);
  334.     }
  335.     private function loadImageComplete():void
  336.     {
  337.         var i:uint,
  338.             l:uint,
  339.             th:LoaderThread;
  340.         contents = [];
  341.         l = imageLoader.numThreads;
  342.         for (i=0; i<l; i++)
  343.         {
  344.             th = imageLoader.getThreadAt(i) as LoaderThread;
  345.             contents.push(th.loader.content);
  346.         }
  347.     }
  348.     override protected function finalize():void
  349.     {
  350.         jsonLoader = null;
  351.         imageLoader = null;
  352.     }
  353. }
  354. internal class LoadImageProgressThread extends Thread
  355. {
  356.     private var progress:IProgress;
  357.     private var layer:DisplayObjectContainer;
  358.     private var indicator:HandleIndicatorThread;
  359.     public function LoadImageProgressThread(layer:DisplayObjectContainer, progress:IProgress)
  360.     {
  361.         this.layer = layer;
  362.         this.progress = progress;
  363.     }
  364.     override protected function run():void
  365.     {
  366.         indicator = new HandleIndicatorThread(layer);
  367.         indicator.start();
  368.         next(step);
  369.     }
  370.     private function step():void
  371.     {
  372.         if (progress.isCompleted||progress.isFailed||progress.isCanceled)
  373.         {
  374.             next(shutDown);
  375.             return;
  376.         }
  377.         //  TODO: なにかしらやる。
  378.         var percent:Number = progress.percent;
  379.         if (percent >= 1)
  380.         {
  381.             next(shutDown);
  382.         }
  383.         else
  384.         {
  385.             next(step);
  386.         }
  387.     }
  388.     private function shutDown():void
  389.     {
  390.         indicator.interrupt();
  391.     }
  392.     override protected function finalize():void
  393.     {
  394.         progress = null;
  395.         layer = null;
  396.         indicator = null;
  397.     }
  398. }
  399. internal class HandleImageThread extends Thread
  400. {
  401.     public static const PARTICLE_MARGIN:Number = 6;
  402.     private var original:Bitmap;
  403.     private var destination:Bitmap;
  404.     private var showParticles:Vector.<ShowImageParticle>;
  405.     private var hideParticles:Vector.<HideImageParticle>;
  406.     public function HandleImageThread(original:Bitmap, destination:Bitmap)
  407.     {
  408.         this.original = original;
  409.         this.destination = destination;
  410.         this.showParticles = new Vector.<ShowImageParticle>();
  411.         this.hideParticles = new Vector.<HideImageParticle>();
  412.     }
  413.     override protected function run():void
  414.     {
  415.         var w:Number, h:Number, c:uint,
  416.             tx:Number, ty:Number,
  417.             sx:Number, sy:Number,
  418.             cx:Number, cy:Number,
  419.             angle:Number,
  420.             i:uint, j:uint,
  421.             s:Stage,
  422.             data:BitmapData;
  423.         s = destination.stage;
  424.         data = original.bitmapData;
  425.         w = data.width;
  426.         h = data.height;
  427.         cx = s.stageWidth / 2;
  428.         cy = s.stageHeight / 2;
  429.         for (i=0; i<w; i++)
  430.         {
  431.             for (j=0; j<h; j++)
  432.             {
  433.                 c = data.getPixel32(i, j);
  434.                 if (!c) continue;
  435.                 angle = Math.random() * Math.PI * 2;
  436.                 sx = Math.cos(angle) * 500 + cx;
  437.                 sy = Math.sin(angle) * 500 + cy;
  438.                 tx = i * PARTICLE_MARGIN;
  439.                 ty = j * PARTICLE_MARGIN;
  440.                 showParticles.push(new ShowImageParticle(sx, sy, tx, ty, c));
  441.                 hideParticles.push(new HideImageParticle(tx, ty, sx, sy, c, s.frameRate));
  442.             }
  443.         }
  444.         next(showStep);
  445.     }
  446.     private function showStep():void
  447.     {
  448.         var i:uint,
  449.             l:uint,
  450.             c:uint,
  451.             a:Number,
  452.             f:Boolean,
  453.             p:ShowImageParticle,
  454.             data:BitmapData;
  455.         data = destination.bitmapData;
  456.         data.lock();
  457.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  458.         l = showParticles.length;
  459.         f = false;
  460.         for (i=0; i<l; i++)
  461.         {
  462.             p = showParticles[i];
  463.             if (p.isAlive)
  464.             {
  465.                 f = true;
  466.                 p.update();
  467.             }
  468.             data.setPixel32(p.x, p.y, p.color);
  469.         }
  470.         data.unlock();
  471.         if (!f)
  472.         {
  473.             next(fixedImage);
  474.         }
  475.         else
  476.         {
  477.             next(showStep);
  478.         }
  479.     }
  480.     private function hideStep():void
  481.     {
  482.         var i:uint,
  483.             l:uint,
  484.             c:uint,
  485.             a:Number,
  486.             f:Boolean,
  487.             p:HideImageParticle,
  488.             data:BitmapData;
  489.         data = destination.bitmapData;
  490.         data.lock();
  491.         data.colorTransform(data.rect, new ColorTransform(111, .970000));
  492.         data.applyFilter(data, data.rect, POINT_ZERO, FILTER_BLUR);
  493.         l = hideParticles.length;
  494.         for (i=0; i<l; i++)
  495.         {
  496.             p = hideParticles[i];
  497.             p.update();
  498.             data.setPixel32(p.x, p.y, p.color);
  499.             if (!data.rect.contains(p.x, p.y))
  500.             {
  501.                 hideParticles.splice(i, 1);
  502.                 i--;
  503.                 l = hideParticles.length;
  504.             }
  505.         }
  506.         data.unlock();
  507.         //trace(p.x, p.y);
  508.         if (l) next(hideStep);
  509.     }
  510.     private function fixedImage():void
  511.     {
  512.         sleep(3000);
  513.         next(hideStep);
  514.     }
  515.     override protected function finalize():void
  516.     {
  517.         original = null;
  518.         destination = null;
  519.         showParticles.length = 0;
  520.         showParticles = null;
  521.         hideParticles.length = 0;
  522.         hideParticles = null;
  523.     }
  524. }
  525. internal class HandleIndicatorThread extends Thread
  526. {
  527.     private var layer:DisplayObjectContainer;
  528.     private var indicator:DisplayObject;
  529.     public function HandleIndicatorThread(layer:DisplayObjectContainer)
  530.     {
  531.         this.layer = layer;
  532.     }
  533.     override protected function run():void
  534.     {
  535.         Mouse.hide();
  536.         layer.stage.mouseChildren = false;
  537.         indicator = new Indicator();
  538.         indicator.x = layer.mouseX;
  539.         indicator.y = layer.mouseY;
  540.         layer.addChild(indicator);
  541.         next(step);
  542.     }
  543.     private function step():void
  544.     {
  545.         if (checkInterrupted()) return;
  546.         indicator.rotation = (indicator.rotation + 360 / indicator.stage.frameRate) % 360;
  547.         indicator.x = layer.mouseX;
  548.         indicator.y = layer.mouseY;
  549.         next(step);
  550.     }
  551.     override protected function finalize():void
  552.     {
  553.         Mouse.show();
  554.         layer.stage.mouseChildren = true;
  555.         layer.removeChild(indicator);
  556.         layer = null;
  557.         indicator = null;
  558.     }
  559. }
  560. internal class HideMessageParticle
  561. {
  562.     public var x:Number;
  563.     public var y:Number;
  564.     public var ax:Number;
  565.     public var ay:Number;
  566.     public var vx:Number;
  567.     public var vy:Number;
  568.     public var color:uint;
  569.     public function HideMessageParticle(x:Number, y:Number, color:Number)
  570.     {
  571.         var len:Number,
  572.             angle:Number;
  573.         len = Math.random() * 5;
  574.         angle = Math.random() * Math.PI * 2;
  575.         this.ax = Math.cos(angle) * len;
  576.         this.ay = Math.sin(angle) * len;
  577.         this.x = x;
  578.         this.y = y;
  579.         this.color = color;
  580.         this.vx = 0;
  581.         this.vy = 0;
  582.     }
  583.     public function update():void
  584.     {
  585.         vx += ax;
  586.         vy += ay;
  587.         x += vx;
  588.         y += vy;
  589.     }
  590. }
  591. import flash.geom.Point;
  592. internal class ShowImageParticle
  593. {
  594.     public var x:Number;
  595.     public var y:Number;
  596.     public var color:uint;
  597.     private var targetX:Number;
  598.     private var targetY:Number;
  599.     private var _isAlive:Boolean;
  600.     public function get isAlive():Boolean
  601.     {
  602.         return _isAlive;
  603.     }
  604.     public function ShowImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint)
  605.     {
  606.         this.x = x;
  607.         this.y = y;
  608.         this.color = color;
  609.         this.targetX = targetX;
  610.         this.targetY = targetY;
  611.         this._isAlive = true;
  612.     }
  613.     public function update():void
  614.     {
  615.         x += (targetX - x) * .05;
  616.         y += (targetY - y) * .05;
  617.         if (Math.abs(targetX - x) < .5 && Math.abs(targetY - y) < .5)
  618.         {
  619.             x = targetX;
  620.             y = targetY;
  621.             _isAlive = false;
  622.         }
  623.     }
  624. }
  625. internal class HideImageParticle
  626. {
  627.     public var x:Number;
  628.     public var y:Number;
  629.     public var color:uint;
  630.     private var vx:Number;
  631.     private var vy:Number;
  632.     private var ax:Number;
  633.     private var ay:Number;
  634.     private var rate:Number;
  635.     public function HideImageParticle(x:Number, y:Number, targetX:Number, targetY:Number, color:uint, rate:Number)
  636.     {
  637.         var dx:Number,
  638.             dy:Number,
  639.             len:Number,
  640.             angle:Number;
  641.         dx = targetX - x;
  642.         dy = targetY - y;
  643.         len = 9.8;
  644.         angle = Math.atan2(dy, dx);
  645.         this.x = x;
  646.         this.y = y;
  647.         this.vx = 0;
  648.         this.vy = 0;
  649.         this.ax = Math.cos(angle) * len;
  650.         this.ay = Math.sin(angle) * len;
  651.         this.color = color;
  652.         this.rate = rate;
  653.     }
  654.     public function update():void
  655.     {
  656.         vx += ax / rate;
  657.         vy += ay / rate;
  658.         x += vx;
  659.         y += vy;
  660.     }
  661. }
  662. internal class FlickrPhoto
  663. {
  664.     private var _id:String;
  665.     public function get id():String
  666.     {
  667.         return _id;
  668.     }
  669.     private var _secret:String;
  670.     public function get secret():String
  671.     {
  672.         return _secret;
  673.     }
  674.     private var _server:String;
  675.     public function get server():String
  676.     {
  677.         return _server;
  678.     }
  679.     private var _farm:String;
  680.     public function get farm():String
  681.     {
  682.         return _farm;
  683.     }
  684.     public function get thumbnailURL():String
  685.     {
  686.         return ['http://farm', farm, '.static.flickr.com/', server, '/', id, '_', secret, '_s.jpg'].join('');
  687.     }
  688.     public function FlickrPhoto(data:Object)
  689.     {
  690.         this._id = data['id'] || '';
  691.         this._secret = data['secret'] || '';
  692.         this._server = data['server'] || '';
  693.         this._farm = data['farm'] || '';
  694.     }
  695. }
noswf
  1. // forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
  2. /**
  3.  *  ActionScript3 Thread library のサンプルになれば幸いです :-)
  4.  *
  5.  *  @see    http://www.flickr.com/photos/auroracrowley/
  6.  *  @see    http://www.libspark.org/htdocs/as3/thread-files/document/
  7.  */
  8. package
  9. {
  10.     import flash.display.Sprite;
  11.     import flash.display.StageAlign;
  12.     import flash.display.StageQuality;
  13.     import flash.display.StageScaleMode;
  14.     import flash.events.Event;
  15.     import org.libspark.thread.EnterFrameThreadExecutor;
  16.     import org.libspark.thread.Thread;
  17.     [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]
  18.     public class Tmp extends Sprite
  19.     {
  20.         public function Tmp()
  21.         {
  22.             addEventListener(Event.ADDED_TO_STAGE, initialize);
  23.         }
  24.         private function initialize(evt:Event):void
  25.         {
  26.             removeEventListener(Event.ADDED_TO_STAGE, initialize);
  27.             stage.align = StageAlign.TOP_LEFT;
  28.             stage.quality = StageQuality.HIGH;
  29.             stage.scaleMode = StageScaleMode.NO_SCALE;
  30.             if (!Thread.isReady)
  31.             {
  32.                 Thread.initialize(new EnterFrameThreadExecutor());
  33.             }
  34.             new MainThread(this).start();
  35.         }
  36.     }
  37. }
  38. import flash.display.Bitmap;
  39. import flash.display.BitmapData;
  40. import flash.display.BlendMode;
  41. import flash.display.DisplayObject;
  42. import flash.display.DisplayObjectContainer;
  43. import flash.display.Stage;
  44. import flash.events.MouseEvent;
  45. import flash.filters.BitmapFilter;
  46. import flash.filters.BitmapFilterQuality;
  47. import flash.filters.BlurFilter;
  48. import flash.geom.ColorTransform;
  49. import flash.geom.Point;
  50. import flash.net.URLRequest;
  51. import flash.net.URLVariables;
  52. import flash.system.LoaderContext;
  53. import flash.text.TextField;
  54. import flash.text.TextFieldAutoSize;
  55. import flash.text.TextFormat;
  56. import flash.ui.Mouse;
  57. import com.adobe.serialization.json.JSON;
  58. import org.libspark.thread.Thread;
  59. import org.libspark.thread.threads.display.LoaderThread;
  60. import org.libspark.thread.threads.net.URLLoaderThread;
  61. import org.libspark.thread.utils.IProgress;
  62. import org.libspark.thread.utils.IProgressNotifier;
  63. import org.libspark.thread.utils.MultiProgress;
  64. import org.libspark.thread.utils.ParallelExecutor;
  65. import org.libspark.thread.utils.SerialExecutor;
  66. internal var FILTER_BLUR:BlurFilter = new BlurFilter(44, BitmapFilterQuality.LOW);
  67. internal var POINT_ZERO:Point = new Point();
  68. import flash.display.Shape;
  69. internal class Indicator extends Shape
  70. {
  71.     public function Indicator()
  72.     {
  73.         var i:uint,
  74.             cx:Number, cy:Number,
  75.             numNeedles:uint = 12,
  76.             innerR:Number = 7,
  77.             outerR:Number = 5,
  78.             cAngle:Number = -Math.PI / 2,
  79.             nAngle:Number;
  80.         nAngle = Math.PI * 2 / numNeedles;
  81.         for (i=0; i<numNeedles; i++)
  82.         {
  83.             cAngle += nAngle;
  84.             cx = Math.cos(cAngle) * innerR;
  85.             cy = Math.sin(cAngle) * innerR;
  86.             graphics.moveTo(cx, cy);
  87.             cx = Math.cos(cAngle) * outerR;
  88.             cy = Math.sin(cAngle) * outerR;
  89.             graphics.lineStyle(2, 0xffffff, i/numNeedles);
  90.             graphics.lineTo(cx, cy);
  91.         }
  92.     }
  93. }
  94. internal class MainThread extends Thread
  95. {
  96.     private var layer:DisplayObjectContainer;
  97.     private var imageLoader:LoadImageThread;
  98.     private var contents:Array;
  99.     private var canvas:Bitmap;
  100.     private var currentIndex:uint;
  101.     public function MainThread(layer:DisplayObjectContainer)
  102.     {
  103.         this.layer = layer;
  104.     }
  105.     override protected function run():void
  106.     {
  107.         var t:Thread;
  108.         t = new WaitAnimationThread(layer);
  109.         t.start();
  110.         t.join();
  111.         next(loadImage);
  112.     }
  113.     private function loadImage():void
  114.     {
  115.         var executor:ParallelExecutor;
  116.         executor = new ParallelExecutor();
  117.         imageLoader = new LoadImageThread();
  118.         executor.addThread(imageLoader);
  119.         executor.addThread(new LoadImageProgressThread(layer, imageLoader.progress));
  120.         executor.start();
  121.         executor.join();
  122.         next(loadComplete);
  123.     }
  124.     private function loadComplete():void
  125.     {
  126.         var s:Stage,
  127.             data:BitmapData;
  128.         contents = imageLoader.contents.concat();
  129.         imageLoader.contents.length = 0;
  130.         imageLoader.contents = null;
  131.         currentIndex = 0;
  132.         s = layer.stage;
  133.         data = new BitmapData(450450true0);
  134.         canvas = new Bitmap(data);
  135.         canvas.x = (s.stageWidth - canvas.width) / 2;
  136.         canvas.y = (s.stageHeight - canvas.height) / 2;
  137.         layer.addChild(canvas);
  138.         next(changeImage);
  139.     }
  140.     private function changeImage():void
  141.     {
  142.         if (currentIndex >= contents.length)
  143.         {
  144.             currentIndex = 0;
  145.         }
  146.         var image:Bitmap,
  147.             th:Thread;
  148.         image = contents[currentIndex++] as Bitmap;
  149.         th = new HandleImageThread(image, canvas);
  150.         th.start();
  151.         th.join();
  152.         next(changeImage);
  153.     }
  154.     override protected function finalize():void
  155.     {
  156.         layer = null;
  157.         imageLoader = null;
  158.     }
  159. }
  160. internal class WaitAnimationThread extends Thread
  161. {
  162.     private var layer:DisplayObjectContainer;
  163.     private var message:Bitmap;
  164.     public function WaitAnimationThread(layer:DisplayObjectContainer)
  165.     {
  166.         this.layer = layer;
  167.     }
  168.     override protected function run():void
  169.     {
  170.         var s:Stage,
  171.             txt:TextField,
  172.             fmt:TextFormat,
  173.             bmd:BitmapData;
  174.         s = layer.stage;
  175.         fmt = new TextFormat();
  176.         fmt.color = 0x000000;
  177.         fmt.size = 24;
  178.         fmt.font = 'Trebuchet MS';
  179.         txt = new TextField();
  180.         txt.autoSize = TextFieldAutoSize.LEFT;
  181.         txt.defaultTextFormat = fmt;
  182.         txt.text = 'click to start.';
  183.         bmd = new BitmapData(txt.textWidth, txt.textHeight, true0);
  184.         bmd.draw(txt);
  185.         message = new Bitmap(bmd);
  186.         message.blendMode = BlendMode.INVERT;
  187.         message.x = (s.stageWidth - message.width) / 2;
  188.         message.y = (s.stageHeight - message.height) / 2;
  189.         layer.addChild(message);
  190.         event(s, MouseEvent.CLICK, hideMessage);
  191.     }
  192.     private function hideMessage(evt:MouseEvent):void
  193.     {
  194.         new HideMessageThread(message).start();
  195.     }
  196.     override protected function finalize():void
  197.     {
  198.         layer = null;
  199.         message = null;
  200.     }
  201. }
  202. internal class HideMessageThread extends Thread
  203. {
  204.     private var message:DisplayObject;
  205.     private var wrapper:Bitmap;
  206.     private var parent:DisplayObjectContainer;
  207.     private var film:BitmapData;
  208.     private var particles:Vector.<HideMessageParticle>;
  209.     public function HideMessageThread(message:DisplayObject)
  210.     {
  211.         this.message = message;
  212.         this.parent = message.parent;
  213.         this.particles = new Vector.<HideMessageParticle>();
  214.     }
  215.     override protected function run():void
  216.     {
  217.         var s:Stage,
  218.             c:uint,
  219.             w:Number, h:Number,
  220.             offsetX:Number, offsetY:Number,
  221.             i:uint, j:uint,
  222.             bmd:BitmapData;
  223.         s = message.stage;
  224.         bmd = Bitmap(message).bitmapData;
  225.         w = bmd.width;
  226.         h = bmd.height;
  227.         offsetX = message.x;
  228.         offsetY = message.y;
  229.         for (i=0; i<w; i++)
  230.         {
  231.             for (j=0; j<h; j++)
  232.             {
  233.                 c = bmd.getPixel32(i,j);
  234.                 if (!c) continue;
  235.                 particles.push(new HideMessageParticle(offsetX + i, offsetY + j, c));
  236.             }
  237.         }
  238.         bmd.dispose();
  239.         film = new BitmapData(s.stageWidth, s.stageHeight, true0);
  240.         wrapper = new Bitmap(film);
  241.         wrapper.blendMode = BlendMode.INVERT;
  242.         parent.addChild(wrapper);
  243.         parent.removeChild(message);
  244.         next(step);
  245.     }
  246.     private function step():void
  247.     {
  248.         var i:uint,
  249.             l:uint,
  250.             s:Stage,
  251.             p:HideMessageParticle;
  252.         film.lock();
  253.         film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR);
  254.         l = particles.length;
  255.         for (i=0; i<l; i++)
  256.         {
  257.             p = particles[i];
  258.             p.update();
  259.             film.setPixel32(p.x, p.y, p.color);
  260.             if (!film.rect.contains(p.x, p.y))
  261.             {
  262.                 particles.splice(i, 1);
  263.                 i--;
  264.                 l = particles.length;
  265.             }
  266.         }
  267.         film.unlock();
  268.         if (l) next(step);
  269.     }
  270.     override protected function finalize():void
  271.     {
  272.         parent.removeChild(wrapper);
  273.         film.dispose();
  274.         parent = null;
  275.         wrapper = null;
  276.         message = null;
  277.     }
  278. }
  279. internal class LoadImageThread extends Thread
  280. implements IProgressNotifier
  281. {
  282.     public var contents:Array;
  283.     private var mainProgress:MultiProgress;
  284.     private var subProgress:MultiProgress;
  285.     private var jsonLoader:URLLoaderThread;
  286.     private var imageLoader:SerialExecutor;
  287.     public function get progress():IProgress
  288.     {
  289.         return mainProgress;
  290.     }
  291.     public function LoadImageThread()
  292.     {
  293.         var req:URLRequest,
  294.             data:URLVariables;
  295.         req = new URLRequest('http://query.yahooapis.com/v1/public/yql');
  296.         data = new URLVariables();
  297.         data['q'] = "SELECT * FROM flickr.photos.search(10) WHERE user_id='25105339@N07'";
  298.         data['format'] = 'json';
  299.         req.data = data;
  300.         jsonLoader = new URLLoaderThread(req);
  301.         mainProgress = new MultiProgress();
  302.         subProgress = new MultiProgress();
  303.         mainProgress.addProgress(jsonLoader.progress, 0.1);
  304.         mainProgress.addProgress(subProgress);
  305.     }
  306.     override protected function run():void
  307.     {
  308.         jsonLoader.start();
  309.         jsonLoader.join();
  310.         next(loadDataComplete);
  311.     }
  312.     private function loadDataComplete():void
  313.     {
  314.         var json:Object,
  315.             row:Object,
  316.             th:LoaderThread,
  317.             req:URLRequest,
  318.             ctx:LoaderContext,
  319.             flickr:FlickrPhoto;
  320.         json = JSON.decode(jsonLoader.loader.data);
  321.         ctx = new LoaderContext(true);
  322.         imageLoader = new SerialExecutor();
  323.         for each (row in json.query.results.photo)
  324.         {
  325.             flickr = new FlickrPhoto(row);
  326.             req = new URLRequest(flickr.thumbnailURL);
  327.             th = new LoaderThread(req, ctx);
  328.             imageLoader.addThread(th);
  329.             subProgress.addProgress(th.progress);
  330.         }
  331.         imageLoader.start();
  332.         imageLoader.join();
  333.         next(loadImageComplete);
  334.     }
  335.     private function loadImageComplete():void
  336.     {
  337.         var i:uint,
  338.             l:uint,
  339.             th:LoaderThread;
  340.         contents = [];
  341.         l = imageLoader.numThreads;
  342.         for (i=0; i<l; i++)
  343.         {
  344.             th = imageLoader.getThreadAt(i) as LoaderThread;
  345.             contents.push(th.loader.content);
  346.         }
  347.     }
  348.     override protected function finalize():void
  349.     {
  350.         jsonLoader = null;
  351.         imageLoader = null;
  352.     }
  353. }
  354. internal class LoadImageProgressThread extends Thread
  355. {
  356.     private var progress:IProgress;
  357.     private var layer:DisplayObjectContainer;
  358.     private var indicator:HandleIndicatorThread;
  359.     public function LoadImageProgressThread(layer:DisplayObjectContainer, progress:IProgress)
  360.     {
  361.         this.layer = layer;
  362.         this.progress = progress;
  363.     }
  364.     override protected function run():void
  365.     {
  366.         indicator = new HandleIndicatorThread(layer);
  367.         indicator.start();
  368.         next(step);
  369.     }
  370.     private function step():void
  371.     {
  372.         if (progress.isCompleted||progress.isFailed||progress.isCanceled)
  373.         {
  374.             next(shutDown);
  375.             return;
  376.         }
  377.         //  TODO: なにかしらやる。
  378.         var percent:Number = progress.percent;
  379.         if (percent >= 1)
  380.         {
  381.             next(shutDown);
  382.         }
  383.         else
  384.         {
  385.             next(step);
  386.         }
  387.     }
  388.     private function shutDown():