POPSブログ

三次ベジェ曲線で文字を動かす/2

88

  Category:  as32012/04/19 pops 

三次ベジェ曲線で文字を動かす2、三次ベジェ曲線を使用した運動をさせてみました。シュミュレーション(simulation)2表示。


三次ベジェ曲線と文字の運動との関係2

三次ベジェ曲線を使用した文字運動をさせてみました。波形は事前に作り登録しています。


三次ベジェ曲線曲線を使用した運動のシュミュレーションテスト2

条件を変えて実行してください。


簡単な動作の説明

説明図


1.3次ベジェ曲線関数により、右より左に移動しているだけです。
2.ベジェ曲線の種類を指定できます。現在0-5番まで6種類あります。
3.Y軸およびX軸で反転させて、方向を違わせています。ここでは位相の切り替えと呼んでいます。
4.位置の指定ができます。指定位置からの場合ラインが変形します。
5.アニメ処理はdelay値を変えるためのみ使用され、ベジェ曲線運動はonEnterFrameで処理します。delay値をもっとかえれば拠り複雑な動きになります。
6.文字のSpriteを運動用のSpriteの中に入れてonEnterFrame処理しています。パーテクルのようなものです。
7.注意、文字にグラデーションマスクを使用した場合に大きさ(scaleX scaleY)を0にしないでください。文字が消滅します。グラデーション部分が復活できないようです。


AS3

FlashTest181.as


//動く文字表示テスト
//FlashTest181
//三次ベジェ曲線
//
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="465", height="465", frameRate="30", backgroundColor="0xFFFFFF")]

	public class FlashTest181 extends Sprite {
		
		//補間数(高いほど綺麗で重い)
		static public const	INTERPOLATE:Number = 50;
		
		private var d:Number = 0;// 係数
		private var plus:Number = 0.01;// 加算量
		
		private var layer0:Sprite;
		private var layer1:Sprite;
		private var layer2:Sprite;
		private var layer3:Sprite;
		private var layer4:Sprite;
		private var layer5:Sprite;
		private var container:Sprite;
		
		private var tf:TextField;
		private var tf2:TextField;
		private var tf3:TextField;
		private var tf4:TextField;
		private var tf5:TextField;
		private var tf6:TextField;
		
		private var btn_1:Sprite;
		private var btn_2:Sprite;
		private var btn_3:Sprite;
		private var btn_4:Sprite;
		private var btn_5:Sprite;
		private var btn_6:Sprite;
		private var btn_7:Sprite;
		
		//文字初期位置、通常はありません
		private var pointer4:Sprite;
		private var pointer4_x:Number = 410;
		private var pointer4_y:Number = 250;
		
		//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 bez_balls:Array = [];//要素bez_ball格納容器
		private var count_bez:Array = [];//INTERPOLATE減算用配列
		
		//特殊処理大きさ受け渡し
		private var boxWidth_1:Number;
		private var boxHeight_1:Number;
		
		private var p0:Object;
		private var p1:Object;
		private var p2:Object;
		private var p3:Object;
		private var first_points:Array = [];//同一地点オブジェクト格納容器
		
		//個別に初期位置を同一にする/1=強制移動 0=移動しない
		private var firstPoint:int = 0;
		private var txs:Array = new Array('初期位置','指定位置');
		private var no:int = 0;
		private var rotatno:int = 0;
		private var rot:Array = [0, 360, -360];
		private var rot_v:Number = 0;//回転数
		//逆転係数
		private var chg_x:Number = 1;
		private var chg_y:Number = 1;
		private var chg_xyno:Number = 0;
		//順序切り替え
		private var delay_no:int = 0;
		private var delay_nm:Array = new Array('左', '右', '中', '外');
		//グローバルカウント
		private var gl_count:int = 0;
		//背景番号
		private var back_no:int = 0;
		
		public function FlashTest181():void {
			
			//回転数
			rot_v = rot[rotatno];
			
			//BASE/黒背景
			graphics.beginFill(0x000000);//0x000000
			graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			graphics.endFill();
			
			//白背景レーヤー
			layer0 = createSquare(0, 0, stage.stageWidth, stage.stageHeight, 0xFFFFFF, 1);
			addChild(layer0);
			layer0.visible = false;
			
			//layer1 文字関係をまとめた
			layer1 = new Sprite();
			addChild(layer1);
			//text
			tf = createTextField(10, 445, 400, 20);
			tf.textColor = 0xCCCCCC;
			tf.text = "";
			tf.selectable = false;
			layer1.addChild(tf);
			
			//BTN-7
			btn_7 = createRoundBTN("背景切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_7.x = 430;
			btn_7.y = 445;
			btn_7.buttonMode = true;
			layer1.addChild(btn_7);
			
			//MOVE文字レーヤーlayer2
			layer2 = createSquare(0, 0, stage.stageWidth, 1, 0xEEEEEE, 0);
			layer2.x = 5;//5
			layer2.y = 300;
			addChild(layer2);
			
			//ボタンレーヤー
			layer3 = new Sprite();
			addChild(layer3);
			//BTN-6
			btn_6 = createRoundBTN("順序切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_6.x = 80;
			btn_6.y = 15;
			btn_6.buttonMode = true;
			layer3.addChild(btn_6);
			//BTN-5
			btn_5 = createRoundBTN("位相切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_5.x = 150;
			btn_5.y = 15;
			btn_5.buttonMode = true;
			layer3.addChild(btn_5);
			//BTN-4
			btn_4 = createRoundBTN("回転切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_4.x = 220;
			btn_4.y = 15;
			btn_4.buttonMode = true;
			layer3.addChild(btn_4);
			//BTN-3
			btn_3 = createRoundBTN("番号切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_3.x = 290;
			btn_3.y = 15;
			btn_3.buttonMode = true;
			layer3.addChild(btn_3);
			//BTN-2
			btn_2 = createRoundBTN("位置切替", 13, 0x000000, 60, 20, 0xEEEEEE, 1, 5);
			btn_2.x = 360;
			btn_2.y = 15;
			btn_2.buttonMode = true;
			layer3.addChild(btn_2);
			//BTN-1
			btn_1 = createRoundBTN("アニメ実行", 13, 0x000000, 60, 20, 0xFF69B4, 1, 5);
			btn_1.x = 430;
			btn_1.y = 15;
			btn_1.buttonMode = true;
			layer3.addChild(btn_1);
			layer3.visible = false;
			
			//TEXTレーヤー
			layer5 = new Sprite();
			addChild(layer5);
			//text6
			tf6 = createTextField(50, 30, 60, 20);
			tf6.textColor = 0xCCCCCC;
			tf6.text = "左";
			layer5.addChild(tf6);
			//text5
			tf5 = createTextField(120, 30, 60, 20);
			tf5.textColor = 0xCCCCCC;
			tf5.text = "位相 0";
			layer5.addChild(tf5);
			//text4
			tf4 = createTextField(190, 30, 60, 20);
			tf4.textColor = 0xCCCCCC;
			tf4.text = "回転 0";
			layer5.addChild(tf4);
			//text3
			tf3 = createTextField(260, 30, 60, 20);
			tf3.textColor = 0xCCCCCC;
			tf3.text = "番号 0";
			layer5.addChild(tf3);
			//text2
			tf2 = createTextField(330, 30, 60, 20);
			tf2.textColor = 0xCCCCCC;
			tf2.text = "初期位置";
			layer5.addChild(tf2);
			
			//ドラッグがテキストにじゃまされて聞きにくいので一番上にした
			//曲線
			container = createSquare(0, 0, 1, 1, 0x000000, 0);
			addChild(container);
			
			//goto-init
			init();
		}
		
		// INIT
		private function init():void {
			
			//5 文字初期位置、通常はありません
			pointer4 = new MarkerBall(4, 0x8865B2) as Sprite;
			pointer4.x = pointer4_x;
			pointer4.y = pointer4_y;
			container.addChild(pointer4);
			//drag-Listener
			pointer4.addEventListener(MouseEvent.MOUSE_DOWN, onFileMouseDown);
			pointer4.addEventListener(MouseEvent.MOUSE_UP, onFileMouseUp);
			
			//goto-main
			main_action();
		}
		
		// MAIN-ACTION
		private function main_action():void {
			//main_action as3 hear
			tf.text = "三次ベジェ曲線 ドラッグで移動可能です";
			
			//グラデマスクテキスト MASK-TEXT
			make_MaskText();
			
		}
		//グラデマスクテキスト MASK-TEXT
		private function make_MaskText():void {
			
			//tf.text = "[ _sansでも使用できるように改造 文字の渦運動テスト]";
			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 文字色自由
					60,					// Number 60 文字サイズ自由
					'rainbow',			// String normal random rainbow 色指定
					'mask',				// String mask none グラデーションマスク
					'_sans',				// String Embed-fontName font _sans arial _ゴシック
					-6,					// Number Space -4は引いてあるので差を入力
					false				// embedFonts true false embed文字使用の場合true
			);
				
			//class配列を取り込む
			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];
				sps1[i].z = 0;
				
				//BezBallクラス生成/Ballクラスに工夫しても、BallクラスにaddChildしても何らかの処理が可能
				var ball:BezBall = new BezBall();
				//識別番号をいれる
				ball.count_no = i;
				bez_balls[i] = ball;
				
				//layer2 text_container	特殊なためtext_containerに入れた
				ball.addChild(sps1[i]);
				layer2.addChild(ball);
				
			}
			
			//重要、大きさ
			boxWidth_1 = sps1[txline1 - 1].x + sps1[txline1 - 1].width / 2;
			boxHeight_1 = sps1[0].height;
			
			//btn_1にListenerを設定
			btn_1.addEventListener( MouseEvent.CLICK, animate2 );
			//btn_2にListenerを設定
			btn_2.addEventListener( MouseEvent.CLICK, setpoint_chg );
			//btn_3にListenerを設定
			btn_3.addEventListener( MouseEvent.CLICK, number_chg );
			//btn_4にListenerを設定
			btn_4.addEventListener( MouseEvent.CLICK, rotat_chg );
			//btn_5にListenerを設定
			btn_5.addEventListener( MouseEvent.CLICK, xy_chg );
			//btn_6にListenerを設定
			btn_6.addEventListener( MouseEvent.CLICK, delay_chg );
			//btn_7にListenerを設定
			btn_7.addEventListener( MouseEvent.CLICK, back_chg );
			
			//GOTO-animate
			animate2();
			
		}
		
		//背景切り替え
		private function back_chg(e:MouseEvent):void {
			if (back_no == 0) { back_no = 1; layer0.visible = true;}
			else { back_no = 0; layer0.visible = false; }
		}
		//順序切り替え
		private function delay_chg(e:MouseEvent):void {
			delay_no ++;
			if (delay_no > 3) { delay_no = 0; }
			tf6.text = "" + delay_nm[delay_no];
		}
		//位相切り替え
		private function xy_chg(e:MouseEvent):void {
			chg_xyno ++;
			if (chg_xyno > 3) { chg_xyno = 0; }
			//位相切り替え
			if (chg_xyno == 0) { chg_x = 1; chg_y = 1; }
			if (chg_xyno == 1) { chg_x = 1; chg_y = -1; }
			if (chg_xyno == 2) { chg_x = -1; chg_y = 1; }
			if (chg_xyno == 3) { chg_x = -1; chg_y = -1; }
			tf5.text = "" + chg_xyno;
		}
		//回転切り替え
		private function rotat_chg(e:MouseEvent):void {
			//0 360 -360
			rotatno ++;
			if (rotatno > 2 ) { rotatno = 0; }
			rot_v = rot[rotatno];
			tf4.text = "" + rot_v;
		}
		//番号切り替え
		private function number_chg(e:MouseEvent):void {
			//0-5
			no ++;
			if (no > 5 ) { no = 0; }
			tf3.text = "" + no;
		}
		//初期位置切り替え
		private function setpoint_chg(e:MouseEvent):void {
			//
			firstPoint ++;
			if (firstPoint > 1) { firstPoint = 0; }
			//if (firstPoint == 1) { firstPoint = 0; } else { firstPoint = 1; }
			tf2.text = "" + txs[firstPoint];
		}
		
		//animate2
		private function animate2( e:MouseEvent = null ):void {
			
			//ボタン非表示/アニメ途中おされるとくるう
			layer3.visible = false;
			
			//no = Math.random() * 6;
			tf.text = "三次ベジェ曲線 アニメ";
			
			var p0_v:Object;
			var p1_v:Object;
			var p2_v:Object;
			var p3_v:Object;
			
			//
			switch (no) {
				case 0:
					p0_v = {x:0,y:0};
					p1_v = {x:30,y:-150};
					p2_v = {x:320,y:-150};
					p3_v = {x:350, y:0};
				break;
				case 1:
					p0_v = {x:0,y:0};
					p1_v = {x:130,y:-80};
					p2_v = {x:220,y:-80};
					p3_v = {x:350,y:0};
				break;
				case 2:
					p0_v = {x:0,y:0};
					p1_v = {x:-130,y:-150};
					p2_v = {x:220,y:-80};
					p3_v = {x:350,y:0};
				break;
				case 3:
					p0_v = {x:0,y:0};
					p1_v = {x:150,y:-180};
					p2_v = {x:200,y:180};
					p3_v = {x:350,y:0};
				break;
				case 4:
					p0_v = {x:0,y:0};
					p1_v = {x:0,y:150};
					p2_v = {x:130,y:220};
					p3_v = {x:350,y:0};
				break;
				case 5:
					p0_v = {x:0,y:0};
					p1_v = {x:130,y:50};
					p2_v = {x:0,y:-250};
					p3_v = {x:350,y:0};
				break;
				default:
					//ノーマル
					p0_v = {x:0,y:0};
					p1_v = {x:30,y:-150};
					p2_v = {x:320,y:-150};
					p3_v = {x:350, y:0};
			}
			
			//位相切り替え
			p0_v.x *=chg_x;
			p0_v.y *=chg_y;
			p1_v.x *=chg_x;
			p1_v.y *=chg_y;
			p2_v.x *=chg_x;
			p2_v.y *=chg_y;
			p3_v.x *=chg_x;
			p3_v.y *=chg_y;

			//出現位置を文字初期位置に強制移動
			if (firstPoint) {
				p3_v = { x:pointer4.x - layer2.x, y:pointer4.y - layer2.y };
			}
			
			//グローバルに代入
			p0 = p0_v, p1 = p1_v, p2 = p2_v, p3 = p3_v;
			
			//順序切り替え
			var delay_v:Number = 0;
			var delay_total:Number = txline1 * 0.5;
			var txline_mv:Number = (txline1 - 1) / 2;
			
			var i:int = 0;
			for (i = 0; i < txline1; i++) {
				
				//中の文字位置を00にセットする位置情報は外のspiral_ballsに設定した
				sps1[i].x = 0;
				sps1[i].y = 0;
				
				//同一地点オブジェクト格納容器に要素ごとの初期位置を代入
				if (firstPoint) {
					first_points[i] = { x:pointer4.x - layer2.x - cxs1[i], y:pointer4.y - layer2.y - cys1[i] }
				}
				
				//5 文字初期位置、ポインターにあわせる/1番目の文字位置、そのほかは実際右にある
				//現在文字はにあるので補正する
				if (firstPoint) {
					bez_balls[i].x = pointer4.x - layer2.x;
					bez_balls[i].y = pointer4.y - layer2.y;
				}
				else {
					//見えない場用に移動/位相補正
					bez_balls[i].x = (stage.stageWidth + 200)*chg_x;
					bez_balls[i].y = layer2.y;
				}
				
				//scale
				bez_balls[i].scaleX = 0.1;
				bez_balls[i].scaleY = 0.1;
				
				//INTERPOLATE減算用配列
				count_bez[i] = INTERPOLATE;//50
				
				//delay値
				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 - txline_mv)*0.5; }
				if (delay_no == 3) { delay_v = (delay_total / 2) - Math.abs(i - txline_mv) * 0.5; }
				
				//グローバルカウント
				gl_count = 0;
				
				//遅延させるTweenLite
				var myTween:TweenLite = new TweenLite(bez_balls[i],0.5,{delay:delay_v, scaleX:1, scaleY:1, onComplete:tw_onComplete,onCompleteParams:[i]});
				//
			}
		}
		//TweenLite-onComplete
		private function tw_onComplete(param1:int):void {
			//onEnterFrame処理
			bez_balls[param1].addEventListener(Event.ENTER_FRAME, onEnterFrame_bez);
		}
		
		//ball onEnterFrame
		private function onEnterFrame_bez(e:Event):void {
			//
			var count:Number = INTERPOLATE;//50
			//as Ballで問題なくコンパイル
			var mv_ball:BezBall = e.currentTarget as BezBall;
			var ball_no:int = mv_ball.count_no;
			
			if (gl_count < txline1) {
				//回転rot_vをcountでわる
				mv_ball.rotation += rot_v / count;
				
				//最後0になるように初めに減算する(INTERPOLATE)
				//INTERPOLATE減算用配列
				count_bez[ball_no] -= 1;
				
				var dd:Number = count_bez[ball_no] / count;
				if (dd > 1) { dd = 1; }//強制的に1にする
				if (dd < 0) { dd = 0; }//最後0にする
				
				//個別に初期位置を同一にする
				if (firstPoint) {
					p3 = first_points[ball_no];
				}
				
				//今回の座標
				var pos:Object = CubicBezPoint( p0, p1, p2, p3, dd);
				mv_ball.x = pos.x + cxs1[ball_no];
				mv_ball.y = pos.y + cys1[ball_no];
				//removeEventListener
				if (count_bez[ball_no] <= 0) {
					
					//グローバルカウント/反転するとカウントが正確でないのでこちらで判定
					gl_count ++;
					//回転0
					mv_ball.rotation = 0;
					bez_balls[ball_no].removeEventListener(Event.ENTER_FRAME, onEnterFrame_bez);
					//最後になったらボタン表示
					//if (mv_ball.count_no == txline1 - 1) { show_button(); }
					if (gl_count == txline1) { show_button(); }
				}
				
			}
		}
		//ボタン表示作動中にボタンを押すと崩れるので非表示にしている
		private function show_button ():void {
			gl_count = 0;
			layer3.visible = true;
		}
		
		/* --------------------------------------
		3次ベジェ曲線上の1点を取得する
		第01引数	頂点データ1(開始)
		第02引数	頂点データ2(制御1)
		第03引数	頂点データ3(制御2)
		第04引数	頂点データ4(終了)
		第05引数	係数(0 ~ 1)
		-------------------------------------- */
		private function CubicBezPoint( p0:Object, p1:Object, p2:Object, p3:Object, d:Number):Object {
			
			var o:Object = {x:0,y:0};
			var tmp:Number = (1 - d) * (1 - d) * (1 - d);
			
			o.x += tmp * p0.x;	
			o.y += tmp * p0.y;
			
			tmp = 3 * d * (1-d) * (1-d);
			o.x += tmp * p1.x;
			o.y += tmp * p1.y;
			
			tmp = 3 * d * d * (1-d);
			o.x += tmp * p2.x;
			o.y += tmp * p2.y;
			
			tmp = d * d * d;
			o.x += tmp * p3.x;
			o.y += tmp * p3.y;
			
			return o;
		}

		//簡易ドラッグ設定/注意Sprite容器でなければ機能しない
		private function onFileMouseDown(event:MouseEvent):void {
			event.currentTarget.startDrag();
		}
		private function onFileMouseUp(event:MouseEvent):void {
			event.currentTarget.stopDrag();
		}
		
		//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;
		}
	}
}

//MarkerBallクラス
import flash.display.Sprite;
class MarkerBall extends Sprite {
	//
	private var _color:uint;
	private var _radius:Number;	
	//未使用
	private var _x:Number = 0;
	private var _y:Number = 0;

	public function MarkerBall(radius:Number = 5, color:uint = 0xFF0000) {
		
		_color = color;
		_radius = radius;
		
		var b:Sprite = new Sprite();
		//xy
		b.x = 0;
		b.y = 0;
		//円の描画
		b.graphics.beginFill(_color, 1);
		b.graphics.drawCircle(0, 0, _radius);
		b.graphics.endFill();
		addChild(b);
		//
	}
}

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

	public var angle:Number;
	public var radian:Number;	
	public var pointX:Number;
	public var pointY:Number;

	public var point0:Object;
	public var point1:Object;
	public var point2:Object;
	public var point3:Object;
	//番号
	public var count_no:Number;
	//回転方向 0=左 1=右
	public var direction:int;
	//逆転係数
	public var chgFlag:Number = 1;
	//未使用
	private var _x:Number = 0;
	private var _y:Number = 0;

	public function BezBall() {
		var b:Sprite = new Sprite();
		//xy
		b.x = 0;
		b.y = 0;
		//文字を挿入するので円の描画はなくとも良い
		/*
		b.graphics.beginFill(Math.random() * 0xFF0000,1);
		b.graphics.drawCircle(0, 0, 5);
		b.graphics.endFill();
		*/
		addChild(b);
		//b.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
	}
}

//複数文字の グラデーションマスク クラス
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;
	}

}

三次ベジェ曲線を描くにHAKUHINさんの「3次ベジェ曲線を描画する」記事を参考にしました。

【参考】HAKUHIN's home page: 3次ベジェ曲線を描画する


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

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


以上です。



[ この記事のURL ]


タグ:series , as3 , ActionScript , flash

[ 三次ベジェ曲線で文字を動かす シリーズ記事 ]

三次ベジェ曲線で文字を動かす/42012.04.21
三次ベジェ曲線で文字を動かす/32012.04.20
三次ベジェ曲線で文字を動かす/22012.04.19
三次ベジェ曲線で文字を動かす/12012.04.17

 

ブログ記事一覧



[1]