※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!

wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)

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


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
:
:
Flickrbitmapparticleパーティクルで背景ランダム切り替わり。キレイ!
:
:
:
spots,morphimage morph effect
:
:
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. 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:Array=[];
  209.     public function HideMessageThread(message:DisplayObject)
  210.     {
  211.         this.message = message;
  212.         this.parent = message.parent;
  213.        
  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:Array = [];
  405.     private var hideParticles:Array = [];
  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():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);