In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: mozaic RSS reader

RSSの記事の文字で画像をトレースしています。放っておくと自動でスクロールします。
重めです。
/**
 * Copyright tomohiro8841 ( http://wonderfl.net/user/tomohiro8841 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/s1fD
 */

// forked from B44CCD21's mozaic RSS reader
// forked from Event's CBC NET
//RSSの記事の文字で画像をトレースしています。放っておくと自動でスクロールします。
//重めです。

package{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.Dictionary;
    import flash.utils.Timer;
    
    [SWF(width = "465", height = "465", frameRate = "15", backgroundColor = "#EEEEEE")]
    
    public class RSSReader extends Sprite{
        private static const XML_PATH:String="http://assets.wonderfl.net/static/assets/session5/cbcnet_feed.xml";
        //private static const LOGO_PATH:String="http://jsrun.it/static/assets/session5/cbcnet_logo.gif"
        public static const _PIXEL_SIZE:int=16;
        public static const _TEXT_FORMAT:TextFormat=new TextFormat(null,PIXEL_SIZE);
        private static const SCROLL_INTERVAL:int=5000;
        
        private static var charDictionary:Dictionary=new Dictionary();
        private var urlLoader:URLLoader;
        private var rss:XML;
        private static var rss_items:Array=new Array();
        private static var index:int=15;
        private var timer:Timer;
        
        public function RSSReader(){
            stage.align=StageAlign.TOP_LEFT;
            stage.scaleMode=StageScaleMode.NO_SCALE;
            
            urlLoader=new URLLoader();
            urlLoader.addEventListener(Event.COMPLETE,rssLoadCompleteHandler);
            urlLoader.load(new URLRequest(XML_PATH));
        }
        
        private function rssLoadCompleteHandler(event:Event):void{
            urlLoader.removeEventListener(Event.COMPLETE,rssLoadCompleteHandler);
            
            rss=XML(XML(urlLoader.data)["channel"]);
            
            timer=new Timer(SCROLL_INTERVAL,0);
            timer.addEventListener(TimerEvent.TIMER,function onTimerTickEvent(event:TimerEvent):void{
                scrollItems("down");
            });
            timer.start();
            stage.addEventListener(MouseEvent.MOUSE_MOVE,function onMouseMoveHandler(event:MouseEvent):void{
                timer.reset();
                timer.start();
            });
            
            scrollItems("down");
        }
        
        private function addRSSItem(direction:String):void{
            var rssItem:RSSItem=new RSSItem(rss["item"][index],null,direction);
            addChild(rssItem);
            
            if(direction=="up"){
                rss_items.unshift(rssItem)
                index=(index>0)?index-1:rss["item"].length()-1;
            }else{
                rss_items.push(rssItem);
                index=(index<(rss["item"].length()-1))?index+1:0;
            }
        }
        
        public function scrollItems(direction:String):void{
            timer.reset();
            timer.start();
            
            for each(var item:RSSItem in rss_items){
                item.scroll(direction);
            }
            if(rss_items.length>=3){
                if(direction=="up"){
                    rss_items.pop();
                }else{
                    rss_items.shift();
                }
            }
            addRSSItem(direction);
        }
        
         public static function createCharArray(str:String):Array{
            var charArray:Array=new Array();
            var tmp_dic:Dictionary=new Dictionary();
            for(var i:Number=0;i<str.length;i++){
                var c:String=str.charAt(i);
                if(charDictionary.hasOwnProperty(c.charCodeAt())){
                    if(!tmp_dic.hasOwnProperty(c.charCodeAt())){
                        tmp_dic[c.charCodeAt()]=true;
                        charArray.push(charDictionary[c.charCodeAt()]);
                    }
                    continue;
                }
                
                var tf:TextField=new TextField();
                tf.defaultTextFormat=_TEXT_FORMAT;
                tf.selectable=false;
                tf.text=c;
                if(tf.textWidth<=0||tf.textHeight<=0){continue;}
                tf.width=tf.textWidth+4;
                tf.height=tf.textHeight+4;
                
                var text_bmd:BitmapData=new BitmapData(tf.textWidth,tf.textHeight,false);
                text_bmd.draw(tf);
                
                var char_data:Object=new Object();
                char_data["string"]=c;
                char_data["brightness"]=calBrightness(text_bmd);
                char_data["bitmapData"]=text_bmd;
                
                charDictionary[c.charCodeAt()]=char_data;
                charArray.push(char_data);
            }
            charArray.sortOn("brightness");
            return charArray;
        }
        
        private static function calBrightness(src_bmd:BitmapData):Number{
            var b:Number=0;
            for (var x:int=0;x<src_bmd.width;x++){
                for (var y:int=0;y<src_bmd.height;y++){
                    var c:int=src_bmd.getPixel(x,y);
                    b+=(((c>>16)&255)+((c>>8)&255)+(c&255))/3;
                }
            }
            b/=(src_bmd.width*src_bmd.height);
            return b;
        }
        
        public static function get PIXEL_SIZE():int{
            return _PIXEL_SIZE;
        }
        
        public static function get TEXT_FORMAT():TextFormat{
            return _TEXT_FORMAT;
        }
    }
}

import gs    .TweenLite;

import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.ColorMatrixFilter;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.Dictionary;

import org.osmf.events.TimeEvent;

internal class RSSItem extends Sprite{
    private var item:XML;
    private var charArray:Array;
    
    private var loader:Loader;
    private var text_sp:Sprite;
    private var char_sp_array:Array;
    private var loader_mask_sp:Sprite;
    private var title_tf:TextField;
    private var description_tf:TextField;
    
    private var image_width:int;
    private var image_height:int;
    
    private var direction:String;
    private var position:String;
    
    private static const IMAGE_SCALE:Number=0.5;
    private static const PIXEL_SIZE:int=RSSReader.PIXEL_SIZE;
    private static const IMAGE_EDGE_WIDTH:Number=12;
    private static const HIT_RANGE:Number=8;
    private static const HIT_RANGE_SQUARE:Number=Math.pow(HIT_RANGE,2);
    private static const TEXT_MAGNIFICATION:Number=12.0;
    private static const FILTER_A:Number=1-2/3;
    private static const FILTER_B:Number=1/3;
    private static const GRAYSCALE_FILTER:ColorMatrixFilter=new ColorMatrixFilter(
        [FILTER_A,FILTER_B,FILTER_B,0,0,
            FILTER_B,FILTER_A,FILTER_B,0,0,
            FILTER_B,FILTER_B,FILTER_A,0,0,
            0,0,0,1,0]);
    
    public function RSSItem(item:XML,position:String,direction:String){
        this.item=item;
        this.position=position;
        this.direction=direction;
        var str:String=item["title"]+item["description"];
        
        charArray=RSSReader.createCharArray(str);
        
        loader=new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImageLoadCompleteHandler);
        loader.load(new URLRequest(item["image"].toString()));
    }
    
    private function destroy():void{
        parent.removeChild(this);
    }
    
    private function onImageLoadCompleteHandler(event:Event):void{
        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onImageLoadCompleteHandler);
        
        var reduced_bmd:BitmapData=createReducedBitmapData(loader);
        image_width=reduced_bmd.width*PIXEL_SIZE;
        image_height=reduced_bmd.height*PIXEL_SIZE;
        
        graphics.beginFill(0xFFFFFF);
        graphics.drawRect(IMAGE_EDGE_WIDTH,IMAGE_EDGE_WIDTH,image_width*IMAGE_SCALE,image_height*IMAGE_SCALE);
        graphics.endFill();
        
        var frame_sp:Sprite=new Sprite();
        frame_sp.graphics.beginFill(0x000000);
        frame_sp.graphics.drawRect(IMAGE_EDGE_WIDTH,0,image_width*IMAGE_SCALE,IMAGE_EDGE_WIDTH);
        frame_sp.graphics.drawRect(0,0,IMAGE_EDGE_WIDTH,image_height*IMAGE_SCALE+IMAGE_EDGE_WIDTH*2);
        frame_sp.graphics.drawRect(IMAGE_EDGE_WIDTH,image_height*IMAGE_SCALE+IMAGE_EDGE_WIDTH,image_width*IMAGE_SCALE,IMAGE_EDGE_WIDTH);
        frame_sp.graphics.drawRect(image_width*IMAGE_SCALE+IMAGE_EDGE_WIDTH,0,IMAGE_EDGE_WIDTH,image_height*IMAGE_SCALE+IMAGE_EDGE_WIDTH*2);
        frame_sp.graphics.endFill();
        
        loader.x=loader.y=IMAGE_EDGE_WIDTH;
        loader.scaleX=loader.scaleY=IMAGE_SCALE;
        
        loader_mask_sp=new Sprite();
        loader_mask_sp.cacheAsBitmap=true;
        loader.cacheAsBitmap=true;
        loader.mask=loader_mask_sp;
        
        text_sp=createTextSprite(reduced_bmd,charArray);
        text_sp.scaleX=text_sp.scaleY=IMAGE_SCALE;
        text_sp.x=IMAGE_EDGE_WIDTH;
        text_sp.y=IMAGE_EDGE_WIDTH;
        
        addChild(loader);
        addChild(frame_sp);
        addChild(loader_mask_sp);
        addChild(text_sp);
        
        x=(stage.stageWidth-width)/2;
        buttonMode=true;
        mouseChildren=false;
        
        scroll(direction);
    }
    
    public function scroll(direction:String):void{
        var i:int;
        if(direction=="up"){
            if(position==null){
                addEventListener(MouseEvent.CLICK,onBottomImageClickHandler);
                y=stage.stageHeight;
                TweenLite.to(this,0.4,{y:stage.stageHeight-20});
                position="bottom"
            }else if(position=="bottom"){
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onBottomImageClickHandler);
                }
                addEventListener(MouseEvent.CLICK,onCenterImageClickHandler);
                TweenLite.to(this,1.2,{y:(stage.stageHeight-height)/2});
                for(i=0;i<text_sp.numChildren;i++){
                    text_sp.getChildAt(i).addEventListener(Event.ENTER_FRAME,onCharSpriteEnterFrameHandler);
                }
                position="center"
            }else if(position=="center"){
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onCenterImageClickHandler);
                    removeEventListener(MouseEvent.CLICK,onLoaderClickHandler);
                }
                addEventListener(MouseEvent.CLICK,onTopImageClickHandler);
                TweenLite.to(this,1.2,{y:-height+20});
                for(i=0;i<text_sp.numChildren;i++){
                    text_sp.getChildAt(i).removeEventListener(Event.ENTER_FRAME,onCharSpriteEnterFrameHandler);
                }
                position="top"
            }else{
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onTopImageClickHandler);
                }
                TweenLite.to(this,1.2,{y:-height,onComplete:destroy});
            }
        }else if(direction=="down"){
            if(position==null){
                addEventListener(MouseEvent.CLICK,onTopImageClickHandler);
                y=-height;
                TweenLite.to(this,0.4,{y:-height+20});
                position="top"
            }else if(position=="top"){
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onTopImageClickHandler);
                }
                addEventListener(MouseEvent.CLICK,onCenterImageClickHandler);
                TweenLite.to(this,1.2,{y:(stage.stageHeight-height)/2});
                for(i=0;i<text_sp.numChildren;i++){
                    text_sp.getChildAt(i).addEventListener(Event.ENTER_FRAME,onCharSpriteEnterFrameHandler);
                }
                position="center"
            }else if(position=="center"){
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onCenterImageClickHandler);
                    removeEventListener(MouseEvent.CLICK,onLoaderClickHandler);
                }
                addEventListener(MouseEvent.CLICK,onBottomImageClickHandler);
                TweenLite.to(this,1.2,{y:stage.stageHeight-20});
                for(i=0;i<text_sp.numChildren;i++){
                    text_sp.getChildAt(i).removeEventListener(Event.ENTER_FRAME,onCharSpriteEnterFrameHandler);
                }
                position="bottom"
            }else{
                if(hasEventListener(MouseEvent.CLICK)){
                    removeEventListener(MouseEvent.CLICK,onBottomImageClickHandler);
                }
                TweenLite.to(this,1.2,{y:stage.stageHeight,onComplete:destroy});
            }
        }else{
            throw new Error();
        }
    }
    
    private function onTopImageClickHandler(event:MouseEvent):void{
        removeEventListener(MouseEvent.CLICK,onTopImageClickHandler);
        RSSReader(parent).scrollItems("down");
    }
    
    private function onCenterImageClickHandler(event:Event):void{
        removeEventListener(MouseEvent.CLICK,onCenterImageClickHandler);
        
        var index_x:Number=Math.round((this.mouseX-IMAGE_EDGE_WIDTH)/PIXEL_SIZE/IMAGE_SCALE);
        var index_y:Number=Math.round((this.mouseY-IMAGE_EDGE_WIDTH)/PIXEL_SIZE/IMAGE_SCALE);
        if(index_x<0){index_x=0;}else if(index_x>char_sp_array.length-1){index_x=char_sp_array.length-1;}
        if(index_y<0){index_y=0;}else if(index_y>char_sp_array[0].length-1){index_y=char_sp_array[0].length-1;}
        
        
        var cnt:Number=0;
        addEventListener(Event.ENTER_FRAME,function onClickEnterFrameHandler():void{
            for(var i:int=-cnt;i<=cnt;i++){
                if(!(index_x+i>=0&&index_x+i<char_sp_array.length)){continue;}
                if(i==-cnt||i==cnt){
                    char_sp_array[index_x+i][index_y].addEventListener(Event.ENTER_FRAME,onCharSpriteClickEnterFrameHandler);
                }else{
                    if(index_y+cnt-Math.abs(i)<char_sp_array[0].length){
                        char_sp_array[index_x+i][index_y+cnt-Math.abs(i)].addEventListener(Event.ENTER_FRAME,onCharSpriteClickEnterFrameHandler);
                    }
                    if(index_y-(cnt-Math.abs(i))>=0){
                        char_sp_array[index_x+i][index_y-(cnt-Math.abs(i))].addEventListener(Event.ENTER_FRAME,onCharSpriteClickEnterFrameHandler);
                    }
                }
            }
            if(++cnt>80){removeEventListener(Event.ENTER_FRAME,onClickEnterFrameHandler);}
        });
        addEventListener(MouseEvent.CLICK,onLoaderClickHandler);
    }
    
    private function onLoaderClickHandler(event:MouseEvent):void{
        navigateToURL(new URLRequest(item["link"].toString()));
    }
    private function onCharSpriteClickEnterFrameHandler(event:Event):void{
        event.target.alpha-=0.2;
        
        loader_mask_sp.graphics.beginFill(0x000000,1-event.target.alpha);
        
        loader_mask_sp.graphics.drawRect(
            IMAGE_EDGE_WIDTH+Math.round((event.target.x-IMAGE_EDGE_WIDTH)*IMAGE_SCALE),
            IMAGE_EDGE_WIDTH+Math.round((event.target.y-IMAGE_EDGE_WIDTH)*IMAGE_SCALE),
            PIXEL_SIZE,PIXEL_SIZE);
        loader_mask_sp.graphics.endFill();
        
        if(event.target.alpha<=0){
            event.target.alpha=0;
            event.target.removeEventListener(Event.ENTER_FRAME,onCharSpriteClickEnterFrameHandler);
        }            
    }
    
    private function onBottomImageClickHandler(event:MouseEvent):void{
        removeEventListener(MouseEvent.CLICK,onBottomImageClickHandler);
        RSSReader(parent).scrollItems("up");
    }
    
    private static function createReducedBitmapData(loader:Loader):BitmapData{
        var reduced_bmd:BitmapData=new BitmapData(loader.width/PIXEL_SIZE,loader.height/PIXEL_SIZE,false);
        var matrix:Matrix=new Matrix();
        matrix.scale(1/PIXEL_SIZE,1/PIXEL_SIZE);
        reduced_bmd.draw(loader,matrix);
        
        return reduced_bmd;
    }
    
    private function createTextSprite(src_bmd:BitmapData,charArray:Array):Sprite{
        char_sp_array=new Array();
        var sp:Sprite=new Sprite();
        for (var x:int=0;x<src_bmd.width;x++){
            char_sp_array[x]=new Array();
            for (var y:int=0;y<src_bmd.height;y++){
                var c:int=src_bmd.getPixel(x,y);
                var b:int=(((c>>16)&255)+((c>>8)&255)+(c&255))/3;
                var index:int=Math.floor(b/255*(charArray.length-1));
                
                var tf:TextField=new TextField();
                tf.defaultTextFormat=RSSReader.TEXT_FORMAT;
                tf.textColor=c;
                tf.autoSize=TextFieldAutoSize.LEFT;
                tf.selectable=false;
                tf.text=charArray[index]["string"];
                tf.x-=(2+tf.textWidth/2);
                tf.y-=(tf.textHeight/2);
                
                var char_sp:Sprite=new Sprite();
                char_sp.addChild(tf);
                char_sp.x=x*PIXEL_SIZE-tf.x;
                char_sp.y=y*PIXEL_SIZE-tf.y;
                char_sp.filters=[GRAYSCALE_FILTER];
                
                sp.addChild(char_sp);
                char_sp_array[x][y]=char_sp;
            }
        }
        return sp;
    }
    
    private function onCharSpriteEnterFrameHandler(event:Event):void{
        if(Math.abs(event.target.mouseX)<HIT_RANGE&&Math.abs(event.target.mouseY)<HIT_RANGE){
            var distance:Number=HIT_RANGE_SQUARE-(Math.pow(event.target.mouseX,2)+Math.pow(event.target.mouseY,2));
            var scale:Number=Math.pow(distance/HIT_RANGE_SQUARE,2);
            scale=Math.floor(scale*100)/100;
            event.target.scaleX=1+scale*TEXT_MAGNIFICATION;
            event.target.scaleY=1+scale*TEXT_MAGNIFICATION;
            event.target.filters=[getGrayScaleFilter(scale)];
        }else if(event.target.scaleX>1){
            event.target.scaleX/=1.2;
            event.target.scaleY/=1.2;
            if(event.target.scaleX<1){
                event.target.scaleX=event.target.scaleY=1;
                event.target.filters=[getGrayScaleFilter(0)];
            }
        }
    }
    
    private function getGrayScaleFilter(val:Number):ColorMatrixFilter{
        var a:Number=1-2/3*(1-val);
        var b:Number=1/3*(1-val);
        return new ColorMatrixFilter(
            [a,b,b,0,0,
             b,a,b,0,0,
             b,b,a,0,0,
             0,0,0,1,0]);
    }
}