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]);
}
}