POPSブログ

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

85

  Category:  as32012/04/14 pops 

文字を分解してアニメ処理で表示10。曲線を使用した運動IN用の簡略化したスクリプトです。


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


文字を分解してアニメ処理で表示してみます。曲線を使用した運動シュミュレーションではボタンなどが多く繁雑ですから、IN用の簡略化したスクリプトです。

曲線を使用した運動のテスト。(In専用)


簡単な動作設定等の説明

文字を分解してアニメ処理で表示8を参照ください。またはスクリプト中に詳細説明があります。


AS3

FlashTest184.as


//動く文字表示テスト
//FlashTest184
//640x200 IN
//sin関数/container収容

package
{
	
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.geom.*;
	import flash.system.*;
	import flash.utils.*;
	import flash.text.*;

	//TweenLite
	import com.greensock.*;
	import com.greensock.easing.*;
	
	//虹色用
	import frocessing.color.ColorHSV;

	[SWF(width="640", height="200", frameRate="30", backgroundColor="0xFFFFFF")]

	public class FlashTest184 extends Sprite
	{
		
		//補間数(高いほど綺麗で重い)
		static public const	INTERPOLATE:Number = 50;
		//layer	container
		private var layer1:Sprite;
		private var container:Sprite;
		//TEXT
		private var tf:TextField;
		//BTN
		private var btn_1:Sprite;
		
		//BIG-MOVE-TEXT-1変数
		private var mvlinetext1:String;
		private var txline1:int;
		//格納容器1
		private var tx_w1:Array = [];//TextFieldの幅
		private var tx_h1:Array = [];//TextFieldの高さ
		private var sps1:Array = [];//要素Sprite格納容器
		private var cxs1:Array = [];//X位置格納容器
		private var cys1:Array = [];//Y位置格納容器
		private var sin_balls:Array = [];//要素bez_ball格納容器
		private var count_sin:Array = [];//INTERPOLATE減算用配列
		//特殊処理大きさ受け渡し
		private var boxWidth_1:Number;
		private var boxHeight_1:Number;

		//透過切替,拡大切替,遅延反転,順序切替,位相切替,回転切替,番号切替,動作切替,距離切替
		//個別に初期位置を同一にする/移動すると形が変わる
		//曲線の番号0-4は強制移動の場合回転を加えると良い/文字の回転は無くなる
		//曲線の番号0-4は移動しない場合文字の回転が有効になる
		//5螺旋はどちらも文字の回転が反映されるが移動させると螺旋形状は無くなる
		private var firstPoint:int = 0;//0移動しない,1強制移動
		private var no:int = 5;//曲線の番号 0sin,12cos,34sincos,5螺旋
		//位相切り替え
		private var chg_xyno:Number = 3;//0そのまま,1X軸反転,2Y軸反転,3XY軸反転
		//回転切り替え
		private var rot_v:Number = 360;//回転数0,360,-360,270,-270
		//順序切り替え
		private var delay_no:int = 0;//0左に,1右に,2中から,3外から
		//振幅切り替え自由
		private var swing_x:Number = 100;
		private var swing_y:Number = 100;
		//距離切り替え自由
		private var ball_len_x:Number = 150;//150-350
		private var ball_len_y:Number = 350;//150-350未使用
		//遅延反転切り替え
		private var inversion_v:int = 2;//0通常動作,1交互遅延,2交互反転
		//大きさ透明度切り替え
		private var scale_v:Number = 5;//拡大する倍数を入力、1以下は入力しない 1,3,5,10 など
		private var alpha_flag:Number = 0;//alphaを変えるか 0透過しない,1透過する
		//-------------------------------------------
		
		private var alpha_v:Number = 1;//注意固定値
		//グローバルカウント
		private var gl_count:int = 0;
		//No5の進む角度/3.6
		private var angle5:Number = 3.6;
		//逆転係数
		private var chg_x:Number = 1;
		private var chg_y:Number = 1;
		
		//注意 複数種類Embedの場合はそのつどClassを設定する、下のようになる、違ったらコンパイルできない
		//指定するときはfontNameを使用
		//[Embed(systemFont = "Eras Bold ITC", fontName = "font", mimeType = "application/x-font")]
		//private var embedFont:Class;
		
		public function FlashTest184():void {
						
			//BASE/黒背景
			graphics.beginFill(0x000000);//0x000000
			graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			graphics.endFill();

			layer1 = new Sprite();
			addChild(layer1);
			//text
			tf = createTextField(10, 2, stage.stageWidth - 20, 20);
			tf.textColor = 0xCCCCCC;
			tf.text = "";
			tf.selectable = false;
			layer1.addChild(tf);
			
			//BTN 一旦非表示
			btn_1 = createRoundBTN("アニメ実行", 13, 0x000000, 60, 20, 0xFF69B4, 1, 5);
			btn_1.x = 600;
			btn_1.y = 15;
			btn_1.buttonMode = true;
			//btn_1にListenerを設定
			btn_1.addEventListener( MouseEvent.CLICK, animate2 );
			btn_1.visible = false;
			
			//MOVE文字container/位置さえ設定すれば、大きさは無くとも良い
			container = createSquare(0, 0, stage.stageWidth, 100, 0xEEEEEE, 0);
			container.x = 200;//表示位置X 文字はほぼここからはじまる
			container.y = 90;//表示位置Y 文字はこの下に来る
			addChild(container);
			
			//goto-init
			init();
		}
		
		// INIT
		private function init():void {
		
			//goto-main
			main_action();
		}
		
		// MAIN-ACTION
		private function main_action():void {
			//main_action as3 hear
			tf.text = "";
			
			//グラデマスクテキストを作るに進む
			make_MaskText();
			
		}
		//グラデマスクテキストMASK-TEXT
		private function make_MaskText():void {
			
			mvlinetext1 = "Popsweb.SlideShow";//wonderfl.SlideShow
			//textColor
			var mvtextColor:uint = 0xFFFFFF;
			//length
			txline1 = mvlinetext1.length;
			//位置計算用変数
			var mvbox_pointX:Number = 0;//文字要素のX位置計算用
			var width_b:Number = 0;//前の要素幅保存用
			
			//classで文字を作る、一括複数文字を作る
			var box1_v:MakeTextLine = new MakeTextLine(
					mvlinetext1,		// String 全ての文字
					mvtextColor,		// uint 0xFFFFFF 文字色自由
					30,					// Number 60 文字サイズ自由
					'rainbow',			// String normal random rainbow 色指定
					'none',				// String mask none グラデーションマスク
					'_sans',				// String Embed-fontName font _sans arial _ゴシック
					-2,					// Number Space -4は引いてあるので差を入力
					false				// embedFonts true false embed文字使用の場合true
			);
				
			//class配列を取り込む、extends ArrayでかえすとSpriteが戻らないのでこの方法を取る
			sps1 = box1_v.txsBoxArrays;//文字Sprite
			cxs1 = box1_v.cxsArrays;//文字のx位置
			cys1 = box1_v.cysArrays;//文字のy位置
			
			var i:int = 0;
			for (i = 0; i < txline1; i++) {
				
				//文字列位置確定
				sps1[i].x = cxs1[i];
				sps1[i].y = cys1[i];
				//重要、zの指定/embed文字使用の場合は何も書かないこと
				sps1[i].z = 0;
				
				//SinBallクラス生成/Ballクラスに工夫しても、BallクラスにaddChildしても何らかの処理が可能
				var ball:SinBall = new SinBall();
				//識別番号をいれる
				ball.count_no = i;
				sin_balls[i] = ball;
				
				//特殊なためcontainerに入れた
				ball.addChild(sps1[i]);
				container.addChild(ball);
				//
			}
			
			//重要、大きさ計算、但し利用はして居ない
			boxWidth_1 = sps1[txline1 - 1].x + sps1[txline1 - 1].width / 2;
			boxHeight_1 = sps1[0].height;
			//GOTO-animate
			animate2();
			
		}
				
		//animate2 アニメ処理
		private function animate2( e:MouseEvent = null ):void {
			
			//ボタン非表示
			btn_1.visible = false;
			tf.text = "SIN曲線 アニメ実行中です";
			
			//順序切り替え
			var delay_v:Number = 0;
			var delay_total:Number = txline1 * 0.5;
			var txline_mv:Number = (txline1 - 1) / 2;
			var flag3:int = 1;
			//alpha
			var alpha_v2:Number = 1;
			//中外の場合加算する数値
			var d_chg_v:Number = Math.floor(Math.random() * 4 ) * 0.25;
			//alpha
			if (alpha_flag == 0 ) { alpha_v2 = 1; }
			if (alpha_flag == 1 ) { alpha_v2 = 0; }
			
			var i:int = 0;
			for (i = 0; i < txline1; i++) {
				
				//中の文字位置を00にセットする位置情報は外のspiral_ballsに設定した
				sps1[i].x = 0;
				sps1[i].y = 0;
				
				//見えない場用に移動/2倍にしないと見える場合あり
				sin_balls[i].x = stage.stageWidth * 2 + (ball_len_x + cxs1[i]) * chg_x;
				sin_balls[i].y = 0;
				
				//scale、現在見えない場用に移動してあるから必ず必要では無い
				sin_balls[i].scaleX = 0.1;
				sin_balls[i].scaleY = 0.1;
				
				//減算用配列にINTERPOLATEを代入
				count_sin[i] = INTERPOLATE;//50
				
				//delay値の変化/中外4種類
				delay_v = i * 0.5;//左
				if (delay_no == 1) { delay_v = delay_total - i * 0.5; }//右
				if (delay_no == 2) { delay_v = Math.abs((i + d_chg_v) - txline_mv)*0.5; }//中
				if (delay_no == 3) { delay_v = (delay_total / 2) - Math.abs((i + d_chg_v) - txline_mv) * 0.5; }//外
				
				//遅延フラグクリア
				sin_balls[i]._chg_x = 1;
				sin_balls[i]._chg_y = 1;
				
				//遅延inversion_v/chgflag
				if (inversion_v == 1) {
					if (flag3 < 0) { delay_v += 2.25; }
				}
				//逆転inversion_v/chgflag
				if (inversion_v == 2) {
					if (flag3 < 0) {
						sin_balls[i]._chg_x = -1;
						sin_balls[i]._chg_y = -1;
					}
				}
				//scale
				if (scale_v < 1) { scale_v = 1; }
				
				//グローバルカウント
				gl_count = 0;
				
				//TEST sin
				sin_balls[i].radian = 0;
				//振幅
				swing_y = Math.floor(Math.random() * 5) * 10 + 50;
				
				//中を拡大する、外を拡大すると間隔なども大きくなるので見栄えがわるい
				sps1[i].scaleX = scale_v;
				sps1[i].scaleY = scale_v;
				
				//遅延させるTweenLite/遅延させるのが目的
				var myTween:TweenLite = new TweenLite(sin_balls[i],0.5,{delay:delay_v, scaleX:1, scaleY:1, alpha:alpha_v2, onComplete:tw_onComplete,onCompleteParams:[i]});
				flag3 *= -1;
			}
		}

		//TweenLite-onComplete
		private function tw_onComplete(param1:int):void {
			//onEnterFrame処理/delayのため順序が違うので、delay終了のもの順次ENTER_FRAMEを設定
			sin_balls[param1].addEventListener(Event.ENTER_FRAME, onEnterFrame_sin);
		}
		
		//ball onEnterFrame
		private function onEnterFrame_sin(e:Event):void {
			//
			var count:Number = INTERPOLATE;//50
			//as Ballで問題なくコンパイル/thisは使えない
			var mv_ball:SinBall = e.currentTarget as SinBall;
			var ball_no:int = mv_ball.count_no;
			
			if (gl_count < txline1) {
				//回転rot_vをcountでわる
				mv_ball.rotation += rot_v / count;
				//mv_ball.rotation = -30;
				
				//大きいなら
				if (sps1[ball_no].scaleX > 1) {
					sps1[ball_no].scaleX -= (scale_v - 1) / count;
					sps1[ball_no].scaleY -= (scale_v - 1) / count;
				}
				//alphaを変える設定ならばの判定
				//if (alpha_flag) {
					//mv_ball.alpha += alpha_v / count;	
				//}
				//alphaが小さいならの判定、INの場合これでも良い
				if (mv_ball.alpha < 1) {
					mv_ball.alpha += alpha_v / count;
				}
				
				//最後0になるように初めに減算する(INTERPOLATE)
				//INTERPOLATE減算用配列
				count_sin[ball_no] -= 1;
				
				//保存係数
				var cx:Number =	mv_ball._chg_x;
				var cy:Number =	mv_ball._chg_y;
				
				//X方向の計算
				var by:Number = (0 * count_sin[ball_no] / count);//まだ計算なし
				var bx:Number = (ball_len_x * count_sin[ball_no] / count);
				if (no != 5) {mv_ball.x = (bx * chg_x * cx + cxs1[ball_no])};
				if (firstPoint == 1) { sps1[ball_no].x = bx * chg_x * cx; }//中移動
				//螺旋X angle=3.6
				if (no == 5) {
					mv_ball.x = (Math.cos(angle5 * count_sin[ball_no] / count) * ball_len_x * count_sin[ball_no] / count) * chg_x * cx + cxs1[ball_no];
				}
				
				//sin Y方向の計算
				mv_ball.radian += mv_ball.radian_v/count/stage.frameRate;
				if (no == 0) {
					mv_ball.y = (Math.sin(mv_ball.radian) * swing_y + by) * chg_y*cy;//外振幅プラス
				}
				if (no == 1) {
					(mv_ball.y = Math.sin(mv_ball.radian/2) * swing_y * -1) * chg_y*cy;
				}
				if (no == 2) {
					mv_ball.y = Math.sin(mv_ball.radian/2) * swing_y * chg_y*cy;
				}
				//bxの幅基準
				//cos Y方向の計算
				if (no == 3) {
					mv_ball.y = Math.cos(mv_ball.radian/2) * bx * chg_y*cy;
				}
				//cos sinY/方向の計算振幅が減衰
				if (no == 4) {
					mv_ball.y = (Math.cos(mv_ball.radian/2) - Math.sin(mv_ball.radian)) * bx * chg_y*cy;
				}
				//螺旋 angle=3.6
				if (no == 5) {
					mv_ball.y = (Math.sin(angle5 * count_sin[ball_no] / count) * ball_len_x * count_sin[ball_no] / count) * chg_y * cy;
				}
				
				//removeEventListener
				if (count_sin[ball_no] <= 0) {
					
					//グローバルカウント/反転するとカウントが正確でないのでこちらで判定
					gl_count ++;
					//回転0
					sps1[ball_no].rotation = 0;
					mv_ball.rotation = 0;
					mv_ball.y = 0;
					//注意scaleは0にしないこと、文字にグラデマスクを使用していない場合はOK
					mv_ball.scaleX = 1;
					mv_ball.scaleY = 1;
					mv_ball.alpha = 1;
					
					//どちらでもOK
					//sin_balls[ball_no].removeEventListener(Event.ENTER_FRAME, onEnterFrame_sin);
					mv_ball.removeEventListener(Event.ENTER_FRAME, onEnterFrame_sin);
					//最後になったら最終処理に進む
					if (gl_count == txline1) { show_end(); }
				}
				
			}
		}
		
		//最終処理、すべてアニメが終了したらここにくる
		private function show_end ():void {
			gl_count = 0;
			tf.text = "SIN曲線 移動完了";
			//ボタン表示
			btn_1.visible = true;
		}
		
		//create-box
		private function createSquare(x:Number, y:Number, width:Number, height:Number, color:Number, alpha:Number):Sprite {
			var s:Sprite = new Sprite();
			s.graphics.beginFill(color, alpha);
			s.graphics.drawRect(x, y, width, height);
			s.graphics.endFill();
			//addChild(s);
			return s;
		}
		//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;
		}
	}
}

//SinBall運動クラス
import flash.display.*;
class SinBall extends Sprite {

	//番号
	public var count_no:Number;
	//回転方向 0=左 1=右
	public var direction:int;
	//逆転係数
	public var chgFlag:Number = 1;
	//逆転係数2
	public var _chg_x:Number = 1;
	public var _chg_y:Number = 1;
	//TEST
	public var radian:Number = 0;
	public var radian_v:Number = 180;
	//未使用
	private var _x:Number = 0;
	private var _y:Number = 0;

	public function SinBall() {
		var b:Sprite = new Sprite();
		//xy
		b.x = 0;
		b.y = 0;
		addChild(b);
	}
}

//複数文字の グラデーションマスク クラス
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.system.*;
import flash.utils.*;
//虹色用
import frocessing.color.ColorHSV;

class MakeTextLine extends Sprite {
	//受け渡し配列変数
	public var txsBoxArrays:Array;
	public var cxsArrays:Array;
	public var cysArrays:Array;
	//変数
	private var tx:String;
	private var txs: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;
	private var space:Number;
	private var space_v:Number = -4;
	private var len:Number;
	private var sps:Array;//要素Sprite格納容器
	
	public function MakeTextLine(_txs:String, _color:uint, _font_size:Number, _color_type:String, _mask_type:String, _font_name:String, _space:Number, _embed:Boolean = false):void {
		//変数の代入
		txs = _txs;
		color = _color;
		color_type = _color_type;
		mask_type = _mask_type;
		font_name = _font_name;
		font_size = _font_size;
		embed = _embed;
		space = _space;
		
		//受け渡し配列変数クリア
		txsBoxArrays = [];
		cxsArrays = [];
		cysArrays = [];
		sps = [];
		//作成
		maskText();
	}
	private function maskText():void {
		
			var mvlinetext:String = txs;
			var txline:int;
			var mvtext_pX:Number = 0;//先頭文字位置調整用
			var mvtext_pY:Number = 0;//先頭文字位置調整用
			var mvtext_len:Number = 0;//字位置調整用
			var cx:Number = 0;
			var cy:Number = 0;
			var cxs:Array = [];
			var cys:Array = [];
			var spase_t:Number = space_v + space;//文字間のスペース
			//length
			txline = mvlinetext.length;
			//1=虹色にそめる 0=指定色 2=ランダム色にそめるrandom rainbow 
			var rainbow_colored:int = 0;
			if (color_type == 'rainbow') {rainbow_colored = 1;}
			if (color_type == 'random') {rainbow_colored = 2;}
			//基本textColor
			var mvtextColor:uint = color;
			//虹色にそめる変数
			var nAngle:Number = Math.PI * 2 / txline;
			var cAngle:Number = 0;
			
			for (var i:int = 0; i < txline; i++) {
				//虹色にそめる
				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
				}
				//文字を作る
				var mvtext_sp:Sprite = maskBox(mvlinetext.charAt(i), mvtextColor, font_size, mask_type, font_name, embed);
				//表示位置決定のため半分の間隔をプラスする、中心補正
				mvtext_len += mvtext_sp.width / 2;//文字間補正1
				//位置確定
				cxs[i] = cx = mvtext_pX + mvtext_len;//
				cys[i] = cy = 0;
				//出来上がった文字BOX、mvtext_spを保存
				sps[i] = mvtext_sp;
				//次の文字位置のため、最後に現在文字の半分の間隔をプラスする
				mvtext_len += (mvtext_sp.width / 2) + spase_t;
			}
			
			//配列を受け渡し配列に代入
			txsBoxArrays = sps;
			cxsArrays = cxs;
			cysArrays = cys;

	}
	private function maskBox(tx:String, color:uint, font_size:Number, mask_type:String, font_name:String, embed:Boolean):Sprite {
		//maskBox
		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();	
			//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);
		return _text_sp;
	}

}

条件に拠る振る舞いは「文字を分解してアニメ処理で表示8」シュミュレーション(simulation)表示を参照ください。

【参考】シュミュレーション: 文字を分解してアニメ処理で表示8

複数の文字列を一括して処理するクラス。詳細は、次ぎのページを参照ください。

【参考】複数の文字列を一括して処理: 文字を分解してアニメ処理で表示6


以上です。



[ この記事の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]