AS3将文字生成位图功能实现

最近做一个动画,需要将动态文本旋转以配合设计效果,但众所周知在Flash里有一个Bug,就是动态文本旋转之后就不可见了。

为了解决这一问题,问了百度,解决办法基本上是使用图片替换。网上流传的一些功能不够强大便捷,于是动手写了个静态类。

效果展示:

类原码:

package com.shirne.extend
{
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;
	import flash.text.StyleSheet;
	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.geom.Rectangle;
	import flash.geom.ColorTransform;

	public class ExBitmap
	{

		public function ExBitmap()
		{
		}
		
		public static function getTextFieldBitmap( t:TextField, trans:Boolean = true, smoothing:Boolean = true):Bitmap
		{
			var s:Sprite = new Sprite();
			s.addChild(t);
			var bitmapdata:BitmapData = new BitmapData(s.width,s.height);
			if(trans){
				bitmapdata.colorTransform(new Rectangle(0,0,s.width,s.height), new ColorTransform(0,0,0,0));
			}
			bitmapdata.draw(s,null,null,null,null,true);
			var bmp:Bitmap = new Bitmap(bitmapdata);
			bmp.smoothing = smoothing;
			return bmp;
		}

		/**
		 * 将文本转换为图像
		 * 文本为html文本,可以设定样式
		 * 默认背景透明,平滑处理
		 */
		public static function getHtmlTextBitmap(txt:String, style:StyleSheet=null, trans:Boolean = true, smoothing:Boolean = true):Bitmap
		{
			var t:TextField = new TextField();
			t.autoSize = TextFieldAutoSize.LEFT;
			if(style)t.styleSheet = style;
			t.htmlText = txt;
			return getTextFieldBitmap(t, trans, smoothing);
		}
		
		/**
		 * 将文本转换为图像
		 * 文本为纯文本,可以设定样式
		 * 默认背景透明,平滑处理
		 */
		public static function getTextBitmap(txt:String, tf:TextFormat = null, trans:Boolean = true, smoothing:Boolean = true):Bitmap
		{
			var t:TextField = new TextField();
			t.autoSize = TextFieldAutoSize.LEFT;
			t.text = txt;
			if(tf)t.setTextFormat(tf);
			return getTextFieldBitmap(t, trans, smoothing);
		}
		
		/**
		 * 将文本转换为图像
		 * 文本为纯文本,可以设定逐字样式
		 * 默认背景透明,平滑处理
		 */
		public static function getTextBitmapEx(txt:String, textFormats:Array = null, ratios:Array=null, trans:Boolean = true, smoothing:Boolean = true):Bitmap
		{
			var t:TextField = new TextField();
			t.autoSize = TextFieldAutoSize.LEFT;
			t.text = txt;
			if(textFormats){
				var i:int=0, l:int = textFormats.length, rl:int, j:int = 0;
				var tLen:int = txt.length;
				if(!ratios){
					//没有给定样式位置,则逐字设定
					for(i = 0; i < l - 1; i++){
						trace(i)
						if(textFormats[i])t.setTextFormat(textFormats[i],i,i+1);
					}
					//最后的样式应用于所有字体
					if(textFormats[i])t.setTextFormat(textFormats[i],i, tLen);
				}else{
					//给定样式位置,则依照给定位置设置
					rl = ratios.length;
					for(i = 0; i<Math.min(rl-1, l); i++){
						if(textFormats[i])t.setTextFormat(textFormats[i],ratios[i],ratios[i+1]);
					}
					if( textFormats[i])t.setTextFormat(textFormats[i],ratios[i], tLen);
				}
			}
			return getTextFieldBitmap(t, trans, smoothing);
		}

	}

}

这里面几个静态函数不仅实现了将普通文本转换为位图,还实现了可设定样式的文本位置转换和设定了样式的html文本转换。

以下是使用的示例代码(用到了greensock的一个动画库)

import com.shirne.extend.ExBitmap;
import flash.text.TextField;
import flash.text.StyleSheet;
import flash.text.TextFormat;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.events.MouseEvent;
import fl.controls.Button;
import com.greensock.TweenNano;
import flash.text.TextFieldAutoSize;

var step:int = 50;

var box:Sprite=new Sprite();
box.x = 30;
box.y = 30;
addChild(box);

var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.text= "原始动态文本组件,旋转就会消失"
box.addChild(txt);
addControl(txt);

var bmp1:Bitmap = ExBitmap.getTextBitmap('第一种方法,不带任何样式直接生成');
bmp1.y = step;
box.addChild(bmp1);
addControl(bmp1);


var ss:StyleSheet=new StyleSheet();
ss.setStyle('.normal',{color:'#aa6600',fontSize:'14px',fontWight:'bold'});
var bmp2:Bitmap = ExBitmap.getHtmlTextBitmap('<span class="normal">第二种方法,生成带样式的html文本</span>',ss);
bmp2.y = step * 2;
box.addChild(bmp2);
addControl(bmp2);


var tf:TextFormat = new TextFormat();
tf.color = 0x0066aa;
tf.size = 16;
tf.bold = true;
var bmp3:Bitmap = ExBitmap.getTextBitmap('第三种方法,生成带样式的普通文本',tf);
bmp3.y = step * 3;
box.addChild(bmp3);
addControl(bmp3);

var tf1:TextFormat = new TextFormat();
tf1.color = 0x0066aa;
tf1.size = 16;
tf1.bold = true;
var tf2:TextFormat = new TextFormat();
tf2.color = 0xaa66aa;
tf2.size = 22;
tf2.bold = true;
var tf3:TextFormat = new TextFormat();
tf3.color = 0xff00aa;
tf3.size = 14;
tf3.bold = true;
var bmp4:Bitmap = ExBitmap.getTextBitmapEx('第四种方法,生成带多种样式的普通文本',[tf1,tf2,tf3],[0,3,5]);
bmp4.y = step * 4;
box.addChild(bmp4);
addControl(bmp4);

function addControl(target:DisplayObject):void{
	var btn:Button = new Button();
	btn.label = '转一下看看';
	btn.y = target.y;
	btn.x = target.x + target.width + 50;
	btn.addEventListener(MouseEvent.CLICK,function(){
		TweenNano.to(target,1,{rotation:180,onComplete:function(){
			TweenNano.to(target,.5,{rotation:0});
		}});
	});
	box.addChild(btn);
}