POPSブログ

文字を分解してアニメ処理で表示/7

78

  Category:  as32012/04/08 pops 

文字を分解してアニメ処理で表示する7、事前にTextFieldを作り文字を表示して、TextFieldの文字位置情報を取得して、その位置に別途に作成した文字をアニメします。つまり改行などにも対応できます。


文字を分解してアニメ処理で表示7


今までのものは「1行の文字列」を扱いましたが、ここでは中央表示、折り返し、改行、しても使用できます。但し文字の位置情報を取得しなければなりませんので、事前にダミーのTextFieldを作り文字をいれます。その情報の元に、別途1文字ずつ作り指定位置に重ねて表示する手順です。実際使用の場合ダミーは非表示にします。
(前のものは、1文字の表示位置情報を操作すれば、位置を変えるのは可能ですがかなり面倒です)


FlashTest179.swf


Wonderflの記事TextMotionの判定の一部を引用しました。但し、文字の作成、アニメ、出来上がりなどは別物になっています。作りが違いますので、一部文字が完全に一致せず少しズレが発生しますが使用に差し支えあるものではありません。


簡単な説明

以前のものと違い、ここでは文字位置の計算が違います。事前に作ったTextFieldの文字位置情報を取得してそれを利用しますので、複数の改行段数に対応できます。なお、z軸の指定は処理の途中で使用者が設定ください。
TextField自体を動かしているものでは在りませんので、参照するTextFieldは非表示にして使用します。
文字の判定部分(改行など判定)を、下記記事(TextMotion)より引用しました。


簡単な設定の説明


クラスにアクセスする場合の記載方法

Embed文字を使用する場合は、Embed文字のfontNameを指定ください

//classで文字要素をつくる、_sansでもマスクOK
var p:Sprite = new MakeText(
	mvtext.charAt(i),	// String 1文字
	mvtextColor,			// uint 0xFFFFFF 文字色
	50,						// Number 60 文字サイズ
	'normal',				// String normal random rainbow 色指定/未使用
	'none',					// String mask none グラデーションマスク
	'_sans',					// String Embed-fontName font _sans arial _ゴシック
	false					// embedFonts true false
);

-----------------------------------------------------

_sansなどEmbedしないで使用する場合、z 設定で回転させても表示できます。
Embedしている文字では必要在りません

p.z = 0;


AS3

FlashTest179.as


//TextFieldの文字位置情報を取得
//FlashTest179

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.geom.*;
	import flash.system.*;
	import flash.utils.*;
	import flash.text.*;
	//Tween
	import com.greensock.TweenLite;
	import com.greensock.easing.*;
	//虹色用
	import frocessing.color.ColorHSV;

	[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#FFFFFF")]

	//
	public class FlashTest179 extends Sprite {
		
		private var letterSprite:Sprite;
		//上で設定しているので未使用
		private var mvtext_Width:Number;//全体の幅
		private var mvtext_Height:Number;//全体の高さ
		//layer
		private var layer1:Sprite;
		private var layer2:Sprite;
		private var layer3:Sprite;
		private var layer8:Sprite;
		private var layer9:Sprite;
		private var tf9:TextField;//説明用
		//MOVEtext用TextField
		private var tf:TextField;
		private var tf_boxs:Array = [];
		//格納容器1
		private var sps1:Array = [];//要素Sprite格納容器
		private var cxs1:Array = [];//X位置格納容器
		private var cys1:Array = [];//Y位置格納容器
		private var len_v:int = 0;
		//虹色にそめる
		private var rainbow_colored:int = 1;
		private var mvtextColor:uint = 0xFFFFFF;
		//BTN
		private var btn_1:Sprite;
		//FullScreenButton
		private var fullScreenBtn:Sprite;

		public function FlashTest179 () {
			
			//ステージ/ステージACTION削除
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.HIGH;
			//stage.scaleMode = StageScaleMode.NO_SCALE;//使用しない
			stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
			
			//BASE/黒背景
			var square:Sprite = new Sprite();
			square.graphics.beginFill(0x000000);//0x000000
			square.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			square.graphics.endFill();
			addChild(square);
			
			//layer1
			layer1 = new Sprite();
			addChild(layer1);
			//layer2
			layer2 = new Sprite();
			addChild(layer2);
			//layer3
			layer3 = new Sprite();
			addChild(layer3);
			
			//説明用
			tf9 = createTextField(10,0,stage.stageWidth-20,20);
			tf9.textColor = 0xFF0000;
			tf9.text = "CLICK";
			addChild(tf9);
			
			//BTN-1/createRoundBTN
			btn_1 = createRoundBTN("文字アニメ 1", 13, 0x000000, 100, 20, 0xEEEEEE, 1, 5);
			btn_1.x = 100;
			btn_1.y = 440;
			addChild(btn_1);
			btn_1.visible = false;
			
			//layer9/FullScreenButton収納用
			layer9 = new Sprite();
			layer9.x = stage.stageWidth - 35;
			layer9.y = stage.stageHeight - 25;
			addChild(layer9);
			//FullScreenButton
			fullScreenBtn = createFullScreenButton();
			fullScreenBtn.x = 0;
			fullScreenBtn.y = 0;
			//layer9に収納
			layer9.addChild(fullScreenBtn);
			
			//FULLSCREEN-ACTION
			fullScreenBtn.addEventListener(MouseEvent.CLICK, fullClickHandler);
			
			//1 全てを仮に表示
			makeTF();
			
			//移動表示
			splitTF();
			
		};
		
		//1
		private function makeTF():void {
			//文字列
			var mvtext:String = "WONDERFL.2012\rPOPSWEB";//対象文字列
			
			//基本的なTextFieldの設計
			tf = new TextField();
			tf.width = 465;//注意、クラスの場合はこの幅を受け渡さないようだ、AutoSizeなのでその幅になる
			
			//_sans _ゴシック
			var fmt:TextFormat = new TextFormat( "_sans", 50, null, null, null, null, null, null, TextFormatAlign.CENTER );
			
			fmt.letterSpacing = 0;//原則ゼロ Spacing 0/必要な場合はここで設定する、マイナス設定も可能、クラスではしない
			fmt.leading = -10;//行間の縦間隔を詰める
			tf.defaultTextFormat = fmt;
			tf.textColor = 0x555555;//模擬的な設定
			tf.selectable = false;
			tf.multiline = true;
			tf.wordWrap = true;
			tf.text = mvtext;
			tf.autoSize = TextFieldAutoSize.CENTER;
			
			tf.background = false;
			//layer1に仮表示
			tf.x = (stage.stageWidth - tf.width) / 2;
			tf.y = 150;
			layer1.addChild(tf);
			//tf.visible = false;
			
			//クラスでtfのTextFieldを受け渡した場合に幅が正確で無い場合が発生するが、うけわたさないで処理する場合は補正が要らないようだ
			//文字以外を含む文字数
			len_v = mvtext.length;//注意
			
			var nAngle:Number = Math.PI * 2 / mvtext.length;
			var cAngle:Number = 0;
			var currentChar:String;
			var i:int = 0
			for (i = 0; i < len_v; i++) {
				
				//1文字を取り出す
				currentChar = mvtext.charAt(i);
				//文字以外の処理を除外
				if ( currentChar == "\r" || currentChar == "\n" || currentChar == " " || currentChar == "\t" ) {
					continue;
				}
				
				//個別に色を変える
				if (rainbow_colored == 1) {
					//虹色にそめる/frocessingで虹色を求める
					var hsv:ColorHSV = new ColorHSV(0, 1, 1, 1);
					hsv.h = cAngle / Math.PI * 180;
					//虹色を取得受け渡す
					mvtextColor = hsv.value;
					cAngle += nAngle;
				}
				if (rainbow_colored > 1) {
					//ランダム色
					mvtextColor = 0xFFFFFF * Math.random();//random
				}
				
				//TextFieldの文字位置情報を取得
				var rect:Rectangle = tf.getCharBoundaries(i);
				//文字のrect中心を取得するように修正
				var _x:Number = rect.x + rect.width / 2;
				var _y:Number = rect.y + rect.height / 2;
				
				//classで文字要素をつくる、_sansでもマスクOK
				var p:Sprite = new MakeText(
						mvtext.charAt(i),	// String 1文字
						mvtextColor,			// uint 0xFFFFFF 文字色
						50,						// Number 60 文字サイズ
						'normal',				// String normal random rainbow 色指定/未使用
						'none',					// String mask none グラデーションマスク
						'_sans',					// String Embed-fontName font _sans arial _ゴシック
						false					// embedFonts true false
				);
				
				//重要、必要な場合z設定
				p.z = 0;
				//位置情報を保存
				cxs1.push(_x);
				cys1.push(_y);
				//文字収容BOXを保存
				sps1.push(p);
				
			}
			
			//文字数再計算/上で文字以外を除外しているので変わる場合がある
			len_v = cxs1.length;//注意
			
			//layer2の位置をtfにあわせる
			layer2.x = tf.x;
			layer2.y = tf.y;
			
			//文字位置にaddChild
			for (i = 0; i < len_v; i++) {
				//
				layer2.addChild(sps1[i]);
				sps1[i].x = cxs1[i];
				sps1[i].y = cys1[i];
			}
			
		}		
		
		//注意、getCharBoundariesでの補正
		private function splitTF():void {
			//btn_1にListenerを設定
			btn_1.visible = true;
			btn_1.addEventListener( MouseEvent.MOUSE_DOWN, animate );
		}
		
		//animate1
		private function animate( e:MouseEvent = null ):void {
			var generation:Number;
			var i:int = 0;
			for ( i = 0; i < len_v; ++i ) {
				
				//新しいTextを指定位置に移動する/原点が違うので注意
				sps1[i].x = Math.random() * stage.stageWidth;
				sps1[i].y = Math.random() * stage.stageHeight - 150;
				sps1[i].scaleX = 0.1;
				sps1[i].scaleY = 0.1;
				sps1[i].rotation = 180;
				sps1[i].alpha = 1;
				
				//delay-Time
				generation = i * 0.2;
				//Back.easeOut/ease:Circ.easeIn
				TweenLite.to( sps1[i], 1.5, {delay:generation, x:cxs1[i], y:cys1[i], scaleX:1, scaleY:1, rotation:0, alpha:1, ease:Back.easeOut} );
				
			}
		}
		
		//create-Roundbox
		private function createSquare2(x:Number, y:Number, width:Number, height:Number, color:uint, alpha:Number, round:Number):Sprite {
			var rs:Sprite = new Sprite();
			rs.graphics.beginFill(color, alpha);
			rs.graphics.drawRoundRect(x, y, width, height, round);
			rs.graphics.endFill();
			addChild(rs);
			return rs;
		}
		//create-text
		private function createTextField(x:Number, y:Number, width:Number, height:Number):TextField {
			var result:TextField = new TextField();
			result.x = x;
			result.y = y;
			result.width = width;
			result.height = height;
			addChild(result);
			return result;
		}
		//create-RoundBTN/原点中央
		private function createRoundBTN(text:String, t_size:int, t_color:uint, width:Number, height:Number, color:uint, alpha:Number, round:Number):Sprite {
			var rsbt:Sprite = new Sprite();
			rsbt.graphics.beginFill(color, alpha);
			rsbt.graphics.drawRoundRect(-width/2, -height/2, width, height, round);
			rsbt.graphics.endFill();
			addChild(rsbt);
			var r:TextField = new TextField();
			var fmt:TextFormat = new TextFormat('_ゴシック', t_size, null, null, null, null, null, null, TextFormatAlign.CENTER );
			r.defaultTextFormat = fmt;
			r.textColor = t_color;
			r.selectable = false;
			//r.autoSize = TextFieldAutoSize.LEFT;
			r.text = text;
			r.width = width;
			r.x = -width / 2;
			r.y = -height / 2 + 2;
			rsbt.addChild(r);
			return rsbt;
		}

		//FullScreenBtn CLICK
		private function fullClickHandler(e:MouseEvent):void {
			stage.displayState = (StageDisplayState.FULL_SCREEN==stage.displayState)?StageDisplayState.NORMAL:StageDisplayState.FULL_SCREEN
		}
		
		//FullScreenButton
		private function createFullScreenButton():Sprite {
			// 画面右下にボタン配置(YouTube風)
			var margin:Number = 10;
			var b:Sprite = new Sprite();
			b.graphics.lineStyle();
			b.graphics.beginFill(0x4d4d4d);
			b.graphics.drawRoundRect(7, 5, 21, 14, 3);
			b.graphics.beginFill(0xc1c1c1);
			b.graphics.drawRoundRect(8, 6, 10, 6, 2);
			b.graphics.endFill();
			b.buttonMode = true;
			return b;
		}

    }
}

//文字の グラデーションマスク クラス
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.system.*;

class MakeText extends Sprite {
	//変数
	private var tx:String;
	private var color:uint;
	private var color_type:String;
	private var mask_type:String;
	private var font_name:String;
	private var font_size:Number;
	private var embed:Boolean;

	public function MakeText(_tx:String, _color:uint, _font_size:Number, _color_type:String, _mask_type:String, _font_name:String, _embed:Boolean = false):void {
		//変数の代入
		tx = _tx;
		color = _color;
		color_type = _color_type;
		mask_type = _mask_type;
		font_name = _font_name;
		font_size = _font_size;
		embed = _embed;
		//作成
		maskText();
	}
	private function maskText():void {
		//
		var result:TextField = new TextField();
		var fmt:TextFormat = new TextFormat();
		//CENTERにするとスペースがなくなる
		fmt.size = font_size;//60
		fmt.font = font_name;
		fmt.rightMargin = 0;
		fmt.leftMargin = 0;
		result.defaultTextFormat = fmt;
		result.text = tx;
		result.autoSize = TextFieldAutoSize.LEFT;//LEFT autoSizeでなければならない
		result.textColor = color;
		result.background = false;
		result.embedFonts = embed;
		//result.condenseWhite = false;//HTMLの場合有効
		result.selectable = false;
		//中心補正
		result.x = -result.width / 2;
		result.y = -result.height / 2;
		//基盤Spriteを作る
		var text_sp:Sprite = new Sprite();
		
		//マスク処理
		if (mask_type=='mask') {
			//MASK/ShapeでもSpriteでもどちらでもOKのようだ
			var text_mask:Shape = new Shape();
			//var text_mask:Sprite = new Sprite();	
			//MASK,マスク透過グラデを作る
			var mtx:Matrix = new Matrix();
			mtx.createGradientBox(result.width, result.height, 0, 0, 0);
			//ずらした
			text_mask.graphics.beginGradientFill(
				GradientType.LINEAR,
				[0x00, 0x00],
				[1, 0],
				[50, 240],//[0, 255]
				mtx
			);
			text_mask.graphics.drawRect(0, 0, result.width, result.height);
			
			//マスク中心補正
			text_mask.x = -result.width / 2;
			text_mask.y = -result.height / 2;
			//マスクChildは必要
			text_sp.addChild(text_mask);
			//グラデマスク実行 TextFieldに直接実行してもOK
			result.mask = text_mask;
			//cacheAs
			result.cacheAsBitmap = true;
			text_mask.cacheAsBitmap = true;
		}
		//Child
		text_sp.addChild(result);
		//重要
		addChild(text_sp);
	}

}

【参考引用】wonderfl.netの記事: TextMotion

【参考】当方の記事: 文字を分解してアニメ処理で表示2


デバイスフォント表示の場合WindowsとMacでは少し違うそうです。詳細は下記記事を参照ください。

【参考】デバイスフォントの記事: Flashのデバイスフォント表示をMacとWinで比較


以上です。



[ この記事のURL ]


タグ:flash , ActionScript , as3 , series

[ 文字を分解してアニメ処理で表示 シリーズ記事 ]

サイン曲線で画像を動かすテストです/22012.04.22
サイン曲線で画像を動かすテストです/12012.04.21
三次ベジェ曲線で文字を動かす/22012.04.19
三次ベジェ曲線で文字を動かす/12012.04.17
文字を分解してアニメ処理で表示/112012.04.16
文字を分解してアニメ処理で表示/102012.04.14
文字を分解してアニメ処理で表示/92012.04.13
文字を分解してアニメ処理で表示/82012.04.12
文字を分解してアニメ処理で表示/72012.04.08
文字を分解してアニメ処理で表示/62012.04.07
文字を分解してアニメ処理で表示/52012.04.06
文字を分解してアニメ処理で表示/42012.04.05
文字を分解してアニメ処理で表示/32012.04.04
文字を分解してアニメ処理で表示/22012.04.03
文字を分解してアニメ処理で表示/12012.04.02

 

ブログ記事一覧

年別アーカイブ一覧



[1]