flash on 2009-8-22

by umhr
♥0 | Line 241 | Modified 2009-08-22 18:21:43 | MIT License
play

ActionScript3 source code

/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qeQK
 */

/*
**このAS3のコードはMITライセンスですが、
**絵はGPLライセンスです。
http://start.typepad.jp/typecast/
アニメーションしない顔文字のgif
http://mztm.heteml.jp/umhr/wonderfl/emoticons.gif

縦書き+ケータの絵文字。
絵文字の指定方法は絵文字名がsunの
場合は[m:sun]と書く。

文字コードで指定できるようにすれば、
普通にケータイメールビューアーが作れるかもね。

なんかチェックメイトのお題が
テキストエンジンになってたのでついでに応募。
how to useの範囲内の使い方しかしてないので、
賑やかし要員の自覚ありですがw
Adobeさん、さらなるテキスト周りの機能拡充を
期待してますよ!
という願いを込めて。



参考
http://oshige.com/flash/as3note/

http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/text/engine/TextBlock.html
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/text/engine/EastAsianJustifier.html
http://level0.kayac.com/2008/12/textbox.php
*/

package {
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.text.engine.FontDescription;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextElement;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextRotation;
	import flash.text.engine.ElementFormat;
	import flash.text.engine.EastAsianJustifier;
	
	import flash.text.engine.GraphicElement;
	import flash.text.engine.GroupElement;
	//import flash.text.engine.TextLine;
	//import flash.text.engine.ElementFormat;
	//import flash.text.engine.FontDescription;
	import flash.text.engine.ContentElement;
	
	
	import flash.text.TextField;
	import flash.events.MouseEvent;
	
	[SWF(width = "465", height = "465", backgroundColor = 0xFFFFFF, frameRate = "2")]
	public class Main extends Sprite {
		
		private var numFromName:Array = ["sun","cloud","rain","snow","thunder","typhoon","mist","sprinkle","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricornus","aquarius","pisces","sports","baseball","golf","tennis","soccer","ski","basketball","motorsports","pocketbell","train","subway","bullettrain","car","rvcar","bus","ship","airplane","house","building","postoffice","hospital","bank","atm","hotel","24hours","gasstation","parking","signaler","toilet","restaurant","cafe","bar","beer","fastfood","boutique","hairsalon","karaoke","movie","upwardright","carouselpony","music","art","drama","event","ticket","smoking","nosmoking","camera","bag","book","ribbon","present","birthday","telephone","mobilephone","memo","tv","game","cd","heart","spade","diamond","club","eye","ear","rock","scissors","paper","downwardright","upwardleft","foot","shoe","eyeglass","wheelchair","newmoon","moon1","moon2","moon3","fullmoon","dog","cat","yacht","xmas","downwardleft","phoneto","mailto","faxto","info01","info02","mail","by-d","d-point","yen","free","id","key","enter","clear","search","new","flag","freedial","sharp","mobaq","one","two","three","four","five","six","seven","eight","nine","zero","ok","heart01","heart02","heart03","heart04","smile","angry","despair","sad","wobbly","up","note","cute","spa","kissmark","shine","flair","annoy","punch","bomb","notes","down","sleepy","sign01","sign02","sign03","impact","sweat01","sweat02","dash","sign04","sign05","slate","pouch","pen","shadow","chair","night","soon","on","end","clock","appli01","appli02","t-shirt","moneybag","rouge","denim","snowboard","bell","door","dollar","pc","loveletter","wrench","pencil","crown","ring","sandclock","bicycle","japanesetea","watch","think","confident","coldsweats01","coldsweats02","pout","gawk","lovely","good","bleah","wink","happy02","bearing","catface","crying","weep","ng","clip","copyright","tm","run","secret","recycle","r-mark","danger","ban","empty","pass","full","leftright","updown","school","wave","fuji","clover","cherry","tulip","banana","apple","bud","maple","cherryblossom","riceball","cake","bottle","noodle","bread","snail","chick","penguin","fish","delicious","happy01","horse","pig","wine","shock"];
		private var inputTF:TextField = new TextField();
		private var commentBase:Sprite = new Sprite();
        private var loadFiles_array:Array;
		private var MultiLoader:MultiLoaderClass = new MultiLoaderClass("http://mztm.heteml.jp/crossdomain.xml");
		private var emotionIcon0:Object = {};
		private var emotionIcon1:Object = {};
		private var emotionIcon2:Object = {};
		private var emotionIcon3:Object = {};
        public function Main():void {
			//xmlの読み込み
			loadFiles_array = MultiLoader.setLoad(["emoticons0.gif","emoticons1.gif","emoticons2.gif","emoticons3.gif"],onComp);
		}
		private function onComp():void {
			var length:int = numFromName.length
			for (var i:int = 0; i < length; i++) {
				for (var j:int = 0; j < 4; j++) {
					var bd:BitmapData = new BitmapData(20, 20, false);
					bd.draw(loadFiles_array[j], new Matrix(1, 0, 0, 1, -20 * (i % 20), -20 * (Math.floor(i * 0.05))));
					if (bd.getPixel(0, 0)) {
						this["emotionIcon" + j]["m" + i] = new Bitmap(bd);
					}else {
						this["emotionIcon" + j]["m" + i] = null;
					}
				}
			}
			
			addChild(commentBase);
			inputTF.x = 12;
			inputTF.y = this.stage.stageHeight-24-110;
			inputTF.width = this.stage.stageWidth - 24;
			inputTF.height = 108;
			inputTF.text = "ASオタク[m:pc][m:shadow][m:book]の諸君ハロー[m:sign01]\n[m:impact]むしむし蒸し暑い日[m:sun]が続いていますね[m:wobbly]。涼しい部屋[m:chair]でゲーム[m:tv][m:game]ばっかりしてないで、海[m:wave]へ山[m:fuji]へ外[m:shoe]で遊び[m:run]ましょう!\nそれと食事[m:restaurant]も忘れちゃいけない[m:sign02]暑い日にこそ熱い食べ物[m:noodle]で、たくさん汗[m:sweat01]をかいて[m:beer]たくさん笑って[m:smile]、ぐっすり[m:sleepy][m:confident]眠れば、心も体も夏バテ知らず[m:up]\n心技体揃ってこそコレ[m:thunder]Flash[m:shine]クリエイター[m:happy01]なり[m:scissors]\nとか無理してたくさん絵文字を使ってみましたが、なんか電車[m:train]内のレンタルパレットの広告みたいですよね。ヤングっぽいケータイ[m:mobilephone]文章の勘所が全くわかりません[m:shock]\n***\nこのAS3のコードはMITライセンスですが、絵はGPLライセンスです。ご注意ください。";
			inputTF.border = true;
			inputTF.type = "input";
			inputTF.wordWrap = true;
			addChild(inputTF);
			var btnText:TextField = new TextField();
			btnText.x = this.stage.stageWidth-90;
			btnText.y = this.stage.stageHeight - 18;
			btnText.width = 170;
			btnText.height = 21;
			btnText.text = "to TextBlock";
			btnText.selectable = false;
			addChild(btnText);
			
			var button:Sprite = new Sprite();
			button.graphics.lineStyle (2, 0x999999, 1.0);
			button.graphics.beginFill (0xCCCCCC, 0);
			button.graphics.drawRoundRect (this.stage.stageWidth-110, this.stage.stageHeight - 22 , 100 , 20 , 10 , 10);
			button.buttonMode = true;
			button.addEventListener(MouseEvent.CLICK,CLICK);
			addChild(button);
			
			
			CLICK();
		}
		private function CLICK(e:MouseEvent = null):void {
			while (commentBase.numChildren) {
				commentBase.removeChildAt(0);
			}
			var fontDescription:FontDescription = new FontDescription("MS Mincho");
			var format:ElementFormat = new ElementFormat();
			format.fontSize = 15;
			format.fontDescription = fontDescription;
			
			
			var txt_array:Array = inputTF.text.split("\r");
			var linePosition:Number = stage.stageWidth - 30;
			
			for (var i:int = 0; i < txt_array.length; i++) {
				setTB(groupElementFromText(txt_array[i]));
			}
			function setTB(groupElmt:GroupElement):void{
				var textBlock:TextBlock = new TextBlock(groupElmt,null,(new EastAsianJustifier()),TextRotation.ROTATE_90);
				var previousLine:TextLine = null;
				while (true) {
					var textLine:TextLine = textBlock.createTextLine(previousLine,300);
					if (textLine == null) 
						break;
					textLine.y = 16;
					textLine.x = linePosition;
					linePosition -= 24;
					commentBase.addChild(textLine);				
					previousLine = textLine;
				}
			}
		}
		private function groupElementFromText(txt:String):GroupElement{
			var i:int;
			var format:ElementFormat = new ElementFormat((new FontDescription("MS Mincho")),15);
			var format3:ElementFormat = new ElementFormat();
			format3.baselineShift = (20-format.fontSize)/2;
			
			//[m:sun]の部分を取り出す。
			var pattern:RegExp = /\[m:[a-zA-Z0-9]+\]/g;
			var num_array:Array = txt.match(pattern);
			var str_array:Array = txt.split(pattern);
			var _length:int = Math.max(num_array.length , str_array.length);
			var txt_array:Array = [];
			//文章と絵文字を組み合わせる。
			for (i = 0; i < _length; i++) {
				if(str_array[i]){
					txt_array.push(str_array[i])
				}
				if(num_array[i]){
					var num:int = numFromName.indexOf(num_array[i].slice(3,-1));
					txt_array.push(num)
				}
			}
			
			//文章と絵文字を場合分けしてgroupVectorに入れる。
			var groupVector:Vector.<ContentElement> = new Vector.<ContentElement>();
			for (i = 0; i < txt_array.length; i++) {
				if(isNaN(txt_array[i])){
					var textElement:TextElement = new TextElement(txt_array[i], format); 
					groupVector.push(textElement);
				}else{
					var graphicElmt1:GraphicElement = new GraphicElement(setSprite(emotionIcon0["m"+txt_array[i]],emotionIcon1["m"+txt_array[i]],emotionIcon2["m"+txt_array[i]],emotionIcon3["m"+txt_array[i]]) ,24, 24, format3);
					graphicElmt1.textRotation = TextRotation.ROTATE_270;
					groupVector.push(graphicElmt1);
				}
			}
			
			var groupElmt:GroupElement = new GroupElement(groupVector);
			return groupElmt;
		}
		private function setSprite(... args):Sprite {
			var sp:Sprite = new Sprite();
			for (var i:int = 0; i < 4; i++) {
				if (args[i]) {
					var bitmap:Bitmap = newBitmap( { draw:args[i] } );
					if(i>1){
						bitmap.visible = false;
					}
					sp.addChild(bitmap);
				}
			}
			if(sp.numChildren>1){
				sp.addEventListener(Event.ENTER_FRAME, ENTER_FRAME);
			}
			var count:int;
			function ENTER_FRAME(e:Event):void {
				sp.getChildAt(count).visible = false;
				count = (count+1)%sp.numChildren;
				sp.getChildAt(count).visible = true;
			}
			
			return sp;
		}
		private function newBitmap(... args):Bitmap {
			var _length:int = args.length;
			var bd:BitmapData;
			var bitmap:Bitmap;
			var strObj:Object = { width:100 , height:100, transparent:true, fillColor:0xFFFFFFFF };
			var tempDO:DisplayObject;
			for (var i:int = 0; i < _length; i++) {
				var _obj:Object = args[i];
				for (var _str:String in _obj) {
					if (_str == "draw") {
						tempDO = _obj[_str];
						strObj.width = _obj[_str].width;
						strObj.height = _obj[_str].height;
					}else {
						strObj[_str] = _obj[_str];
					}
				}
			}
			bd = new BitmapData(strObj.width, strObj.height, strObj.transparent, strObj.fillColor);
			if (tempDO) {
				bd.draw(tempDO)
			}
			bitmap = new Bitmap(bd);
			return bitmap;
		}
	}
}


class MultiLoaderClass{
	import flash.system.Security;
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.display.Loader;

	private var onComplete:Function = function():void{};
	private var loadNum:int;
	private var loadCompNum:int;

	public function MultiLoaderClass(_str:String = null){
		if(_str != null){
			Security.loadPolicyFile(_str);
		}
	}

	public function setLoad(__item_array:Array,_onComp:Function = null):Array{
		loadCompNum = loadNum = 0;
		onComplete = _onComp;
		var _array:Array = new Array();
		var _length:int = __item_array.length;
		for (var i:int = 0; i < _length; i++) {
			if(__item_array[i] == null){continue};
			var _extension:String = __item_array[i].substr(-4,4).toLowerCase();//拡張子を取り出す。
			if(_extension == ".xml"){
				loadNum ++;
				_array[i] = fnURLLoader(__item_array[i]);
			}else if(_extension == ".jpg" || _extension == ".png" || _extension == ".gif"){
				loadNum ++;
				_array[i] = fnLoader(__item_array[i]);
			}else{
				//_array[i] = null;
			}
		}
		return _array;
	}
	private function fnURLLoader(__url:String):URLLoader{
		var _loader : URLLoader = new URLLoader();
		_loader.load(new URLRequest(__url));
		_loader.addEventListener (Event.COMPLETE,completeHandler);
		_loader.addEventListener (IOErrorEvent.IO_ERROR, ioErrorHandler);
		return _loader;
	}

	private function fnLoader(__url:String):Loader{
		var _loader:Loader = new Loader();
		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		_loader.load(new URLRequest(__url));
		//_loader.name = __url;
		return _loader;
	}

	private function completeHandler(event:Event = null):void {
		loadCompNum ++;
		if(loadCompNum == loadNum){
			onComplete();
		}
		//var loaderInfo:LoaderInfo=event.currentTarget as LoaderInfo;
		//var loader:Loader=loaderInfo.loader;
		//addChild(loader);
	}

	private function ioErrorHandler(event:IOErrorEvent):void {
		//event.text = "Error #2035: URL が見つかりません。 URL: file:///~~~~~";
		//event.text = "Error #2036: 読み込みが未完了です。 URL: http://~~~~~";
		//から、URLのみを取り出す。
		//trace(String(event.text).substr(String(event.text).indexOf(" URL: ")+6),"*****");
		completeHandler();
	}
}