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

by tsu_droid
由来:http://pops-web.com/main/pops/archives/87
♥0 | Line 566 | Modified 2012-12-19 00:29:14 | MIT License
play

ActionScript3 source code

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

//三次ベジェ曲線
//補助線 MCは使用しない直接ラインで描く

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 FlashTest186 extends Sprite{
        
        static public const    INTERPOLATE:Number = 50;// 補間数(高いほど綺麗で重い)

        private var d:Number = 0;// 係数
        private var plus:Number = 0.01;// 加算量

        private var layer1:Sprite;
        private var layer2:Sprite;
        private var layer3:Sprite;
        private var container:Sprite;
        private var tf:TextField;
        private var tf2:TextField;
        private var tf3:TextField;
        private var btn_1:Sprite;
        private var btn_2:Sprite;
        private var btn_3:Sprite;
        private var btn_4:Sprite;
        
        private var pointer0:Sprite;
        private var pointer1:Sprite;
        private var pointer2:Sprite;
        private var pointer3:Sprite;
        private var move:Sprite;
        
        private var pointer0_x:Number = 50;
        private var pointer0_y:Number = 250;
        private var pointer1_x:Number = 80;
        private var pointer1_y:Number = 100;
        private var pointer2_x:Number = 370;
        private var pointer2_y:Number = 100;
        private var pointer3_x:Number = 400;
        private var pointer3_y:Number = 250;
        
        //文字初期位置、通常はありません
        private var pointer4:Sprite;
        private var pointer4_x:Number = 410;
        private var pointer4_y:Number = 250;
        private var firstPoint:int = 0;
        private var first_points:Array = [];//同一地点オブジェクト格納容器
        private var p3:Object;
        private var txs:Array = new Array('初期位置', '指定位置');
        
        //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 = [];
        
        //特殊処理大きさ受け渡し
        private var boxWidth_2:Number;
        private var boxHeight_2:Number;
        
        public function FlashTest186():void{
            //BASE/黒背景
            graphics.beginFill(0xFFFFFF);//0x000000
            graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            graphics.endFill();
            
            //
            layer1 = createSquare(0, 0, stage.stageWidth, stage.stageHeight, 0x000000, 0);
            var g:Graphics = layer1.graphics;
            g.lineStyle(1, 0xEFBAA8, 1);
            g.moveTo(pointer0_x,50);
            g.lineTo(pointer0_x, pointer0_y + 200);
            g.moveTo(0,pointer0_y);
            g.lineTo(stage.stageWidth, pointer0_y);
            g.moveTo(pointer3_x, pointer3_y - 20);
            g.lineTo(pointer3_x, pointer3_y + 20);
            addChild(layer1);
            //曲線
            //container = createSquare(0, 0, stage.stageWidth, stage.stageHeight, 0x000000, 0);
            //addChild(container);
            
            //layer3 文字関係をまとめた
            layer3 = new Sprite();
            addChild(layer3);
            
            //MOVE文字レーヤーlayer2
            layer2 = createSquare(0, 0, stage.stageWidth, 100, 0x000000, 0);
            layer2.x = 5;
            layer2.y = 300;
            addChild(layer2);
            
            //text
            tf = createTextField(10, 5, 380, 20);
            tf.textColor = 0x000000;
            tf.text = "";
            tf.selectable = false;
            layer3.addChild(tf);
            //text3
            tf3 = createTextField(5, 410, stage.stageWidth, 20);
            tf3.textColor = 0xFF0000;
            //tf3.text = "[ポイントA] を原点(0,0)とした場合の [ポイントB] と [ハンドル] の位置を表示します(切捨て)";
            tf3.text = "[ポイント] と [ハンドル] の位置を表示します(切捨て)";
            tf3.selectable = false;
            layer3.addChild(tf3);
            
            //BTN-3
            btn_3 = createRoundBTN("位置切替", 13, 0x000000, 80, 20, 0xEEEEEE, 1, 5);
            btn_3.x = 330;
            btn_3.y = 20;
            layer3.addChild(btn_3);
            
            //BTN-2
            btn_2 = createRoundBTN("文字アニメ", 13, 0x000000, 80, 20, 0xEEEEEE, 1, 5);
            btn_2.x = 420;
            btn_2.y = 20;
            layer3.addChild(btn_2);
            //btn_2.visible = false;
            
            //text2
            tf2 = createTextField(5, 430, stage.stageWidth, 35);
            tf2.textColor = 0x000000;
            tf2.text = "DATA---------------------";
            layer3.addChild(tf2);
            
            //BTN-4
            btn_4 = createRoundBTN("Aポイント 00", 13, 0x000000, 80, 20, 0xEEEEEE, 1, 5);
            btn_4.x = 420;
            btn_4.y = 420;
            layer3.addChild(btn_4);
            //createRoundBTN
            //BTN-1
            btn_1 = createRoundBTN("位置取得", 13, 0x000000, 80, 20, 0xEEEEEE, 1, 5);
            btn_1.x = 420;
            btn_1.y = 445;
            layer3.addChild(btn_1);
            
            //ドラッグがテキストにじゃまされて聞きにくいので一番上にした
            //曲線
            container = createSquare(0, 0, stage.stageWidth, stage.stageHeight, 0x000000, 0);
            addChild(container);
            
            //btn_1にListenerを設定
            btn_1.addEventListener( MouseEvent.MOUSE_DOWN, showdata );
            
            //goto-init
            init();
        }
        
        // INIT
        private function init():void{
            
            //補助線2本は直接ラインで描く
            //0
            pointer0 = new MarkerBall(6, 0xFF0000) as Sprite;
            pointer0.x = pointer0_x;
            pointer0.y = pointer0_y;
            container.addChild(pointer0);
            //drag-Listener
            pointer0.addEventListener(MouseEvent.MOUSE_DOWN, onFileMouseDown);
            pointer0.addEventListener(MouseEvent.MOUSE_UP, onFileMouseUp);
            //1
            pointer1 = new MarkerBall(5, 0xFF00FF) as Sprite;
            pointer1.x = pointer1_x;
            pointer1.y = pointer1_y;
            container.addChild(pointer1);
            //drag-Listener
            pointer1.addEventListener(MouseEvent.MOUSE_DOWN, onFileMouseDown);
            pointer1.addEventListener(MouseEvent.MOUSE_UP, onFileMouseUp);
            //2
            pointer2 = new MarkerBall(5, 0xFF00FF) as Sprite;
            pointer2.x = pointer2_x;
            pointer2.y = pointer2_y;
            container.addChild(pointer2);
            //drag-Listener
            pointer2.addEventListener(MouseEvent.MOUSE_DOWN, onFileMouseDown);
            pointer2.addEventListener(MouseEvent.MOUSE_UP, onFileMouseUp);
            //3
            pointer3 = new MarkerBall(6, 0xFF0000) as Sprite;
            pointer3.x = pointer3_x;
            pointer3.y = pointer3_y;
            container.addChild(pointer3);
            //drag-Listener
            pointer3.addEventListener(MouseEvent.MOUSE_DOWN, onFileMouseDown);
            pointer3.addEventListener(MouseEvent.MOUSE_UP, onFileMouseUp);
            
            move = new MarkerBall(3, 0x009CD1) as Sprite;
            move.x = pointer0_x;
            move.y = pointer0_y;
            container.addChild(move);
            
            //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 = "三次ベジェ曲線 ドラッグで移動可能です";
            //onEnterFrame-Listener
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            //グラデマスクテキスト 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);
                //
            }
            
            //btn_2にListenerを設定
            btn_2.visible = false;
            btn_2.addEventListener( MouseEvent.MOUSE_DOWN, animate2 );
            //btn_3にListenerを設定/位置切替
            btn_3.visible = false;
            btn_3.addEventListener( MouseEvent.MOUSE_DOWN, setpoint_chg  );
            //btn_4にListenerを設定/位置00
            btn_4.addEventListener( MouseEvent.MOUSE_DOWN, a_point_chg  );
            
            //GOTO-animate
            //animate();
            animate2();
            
        }
        
        //位置切替
        private function setpoint_chg ( e:MouseEvent ):void {
            if (firstPoint == 1) { firstPoint = 0; } else { firstPoint = 1; }
            tf.text = "[" + txs[firstPoint]  + "]";
        }
        //animate2
        private function animate2( e:MouseEvent = null ):void
        {
            
            tf.text = "Animate [" + txs[firstPoint]  + "]";
            
            //ボタン非表示
            btn_2.visible = false;
            btn_3.visible = false;
            
            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 + 100;
                    bez_balls[i].y = layer2.y;
                }
                
                //scale
                bez_balls[i].scaleX = 0.1;
                bez_balls[i].scaleY = 0.1;
                
                count_bez[i] = 50;
                
                //遅延させるTweenMax
                var myTween:TweenLite = new TweenLite(bez_balls[i],0.5,{delay:i * 0.5, 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 = 50;
            //as Ballで問題なくコンパイル
            var mv_ball:BezBall = e.currentTarget as BezBall;
            
            // 頂点1/00補正
            var p0:Object = {
                x:0,
                y:0
            };
            // 頂点2
            var p1:Object = {
                x:pointer1.x-pointer0.x,
                y:pointer1.y-pointer0.y
            };
            // 頂点3
            var p2:Object = {
                x:pointer2.x-pointer0.x,
                y:pointer2.y-pointer0.y
            };
            //頂点4
            var p3:Object = {
                x:pointer3.x-pointer0.x,
                y:pointer3.y-pointer0.y
            };
            
            if (count_bez[mv_ball.count_no] > 0) {
                
                //最後0になるように初めに減算する
                count_bez[mv_ball.count_no] -= 1;
                var dd:Number = count_bez[mv_ball.count_no] / count;
                if (dd > 1) { dd = 1; }//強制的に1にする
                if (dd < 0) { dd = 0; }//最後0にする
                
                //個別に初期位置を同一にする
                if (firstPoint) {
                    p3 = first_points[mv_ball.count_no];
                }
                
                // 今回の座標
                var pos:Object = CubicBezPoint( p0, p1, p2, p3, dd);
                mv_ball.x = pos.x + cxs1[mv_ball.count_no];
                mv_ball.y = pos.y + cys1[mv_ball.count_no];
                //removeEventListener
                if (count_bez[mv_ball.count_no] <= 0) {
                    bez_balls[mv_ball.count_no].removeEventListener(Event.ENTER_FRAME, onEnterFrame_bez);
                    //最後になったらボタン表示
                    if (mv_ball.count_no == txline1 - 1) { show_button(); }
                }
                
            }
        }
        //ボタン表示作動中にボタンを押すと崩れるので非表示にしている
        private function show_button ():void
        {
            btn_2.visible = true;
            btn_3.visible = true;
            tf.text = "三次ベジェ曲線 ドラッグで移動可能です";
        }
        
        //ポイントAを原点00に戻す
        private function a_point_chg (e:MouseEvent):void {
            pointer0.x = pointer0_x;
            pointer0.y = pointer0_y;
        }
        //データ取得表示
        private function showdata (e:MouseEvent):void
        {
            //ポイントA/pointer0_x pointer0_yはセット位置原点
            var data_p0:String = "ポイントA x:" + int(pointer0.x - pointer0_x) + " y: " + int(pointer0.y - pointer0_y);
            //ポイントB
            var data_p3:String = " / ポイントB x:" + int(pointer3.x - pointer0.x) + " y: " + int(pointer3.y - pointer0.y);
            //ハンドル1
            var data_p1:String = "ハンドル1 x:" + int(pointer1.x - pointer0.x) + " y: " + int(pointer1.y - pointer0.y);
            //ハンドル2
            var data_p2:String = " / ハンドル2 x:" + int(pointer2.x - pointer0.x) + " y: " + int(pointer2.y - pointer0.y);
            //
            tf2.text = "" + data_p0 + data_p3 +"\r"+ data_p1 + data_p2;
        }
        
        //onEnterFrame
        private function onEnterFrame(e:Event):void {
            //
            // 頂点1
            var p0:Object = {
                x:pointer0.x,
                y:pointer0.y
            };
            // 頂点2
            var p1:Object = {
                x:pointer1.x,
                y:pointer1.y
            };
            // 頂点3
            var p2:Object = {
                x:pointer2.x,
                y:pointer2.y
            };
            //頂点4
            var p3:Object = {
                x:pointer3.x,
                y:pointer3.y
            };
            
            //3次ベジェ曲線を配列にして抽出
            var list:Object = CubicBezStream(p0, p1, p2, p3, INTERPOLATE);
            var g:Graphics = container.graphics;
            // 0-1, 1-2, 2-3,…の順番に線を引く
            g.clear();
            g.lineStyle(1, 0x888888, 1);
            var i:int = 0;
            for(i = 0;i < INTERPOLATE - 1; i++){
                g.moveTo(list[i].x, list[i].y);
                g.lineTo(list[i+1].x, list[i+1].y);
            }
            // 前の座標
            var fpos:Object = CubicBezPoint( p0,p1,p2,p3,d);
            d += plus;
            if(d < 0)    plus *= -1;
            if(d > 1)    plus *= -1;
            // 今回の座標
            var pos:Object = CubicBezPoint( p0,p1,p2,p3,d);
            move.rotation = Math.atan2(pos.y - fpos.y,pos.x - fpos.x) * 180 / Math.PI;
            move.x = pos.x;
            move.y = pos.y;
                
            // 補助線 2本は直接ラインで描く
            g.lineStyle(1, 0xCCCCCC, 1);
            g.moveTo(p1.x, p1.y);
            g.lineTo(p0.x, p0.y);
            g.moveTo(p2.x, p2.y);
            g.lineTo(p3.x, p3.y);
            //
        }
        
        /* --------------------------------------
        3次ベジェ曲線上の点をまとめて取得する
        第01引数    頂点データ1(開始)
        第02引数    頂点データ2(制御1)
        第03引数    頂点データ3(制御2)
        第04引数    頂点データ4(終了)
        第05引数    補間数        
        -------------------------------------- */
        private function CubicBezStream( p0:Object, p1:Object, p2:Object, p3:Object, interpolate:Number):Object
        {
            var i:int = 0;
            var d:Number = 0;
            var out:Array = new Array();
            var tmp:Number;
            var plus:Number = 1.0 / (interpolate - 1);
            for(i=0;i<interpolate;i++){
                var o:Object = { x:0, y:0 };
                
                tmp = (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;
                
                out[i] = o;
                d += plus;
            }
    
            return out;
        }
        
        /* --------------------------------------
        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);
        //
    }
}

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

}

//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;
        addChild(b);
    }
}