Flashでシンボルの基準点を変更するコマンド

自分はここしばらく3D作業ばかりでFlashでの作業はなかったですが

同じチームのFlashでUI制作されてる方が『配置してしまったシンボルの基準点を変えられないかな』ということを言われていて、

検索してみたら下記のSHAKE blogさんの「JSFLでFlashを自動化して楽をする」というのを見つけました。

http://blog.spice-group.jp/archives/183

 

 

shakeCommandsというファイルを公開されていたので使用させて頂いたら、

基準点変更できました!!!!!

 

そして、その公開されていたshakeCommandsを実際の作業データに使ってもらってみました!

 

お、ちゃんと変わりましたよね?

 

あれ・・・

あれれ・・・

 

タイムラインを動かしてみるとつけていたアニメーションがズレています。

 

ああああああ!

まぁよく考えれば当たり前です。

使用させてもらったshakeCommandsは

ただ基準点を変更するだけだと位置がズレてしまうので変更した分の位置を戻しておられます。

しかし、最初のフレームだけ変えても他のフレームでアニメーションしている場合などは

位置を戻していないのでズレた状態のままです。

 

そのため、なんとかできないかなとSHAKE blogさんのshakeCommandsを参考にさせてもらって

すでにアニメーションがつけているモノにも対応したのを作ってみました。

 

まず変更する位置を決めるUIです。

AS3.0はほぼ書いたことないんでほんとに簡単なモノですが

Flashのコンポーネントからラジオボタンとボタン投げ入れてインスタンス名やラベルを入力していき、

それに加えて下記のASを書いています。

よくわかってないのですが各ラジオボタンのgroupNameに”GroupA”と入力しているのに

認識されてないようだったのでASでそこも書いています。

OK押した時にMMExcute('fl.runScript();')でjsflを指定して、

その中の関数に選択されてるラジオボタンのValueを渡しています。

 
 
import flash.events.MouseEvent;
import fl.controls.RadioButton;
import fl.controls.RadioButtonGroup;

var GroupA:RadioButtonGroup = new RadioButtonGroup("Group");

LT_btn.group = GroupA;
CT_btn.group = GroupA;
RT_btn.group = GroupA;
LM_btn.group = GroupA;
CM_btn.group = GroupA;
RM_btn.group = GroupA;
LB_btn.group = GroupA;
CB_btn.group = GroupA;
RB_btn.group = GroupA;


OK_btn.addEventListener(MouseEvent.CLICK, OK_click); 

function OK_click(event:MouseEvent):void{
          
        var jsfl:String = 'fl.configURI + "Commands/CRP/CRP_dialog/CPR_command.jsfl"';
        var func:String = "main";
        var pos:Object = GroupA.selectedData;
        MMExecute ('fl.runScript(' + jsfl + ',"' + func + '","' + pos + '");');
        //trace(pos +"が選ばれました");
}



Cancel_btn.addEventListener(MouseEvent.CLICK, Cancel_click); 

function Cancel_click(event:MouseEvent):void{
         MMExecute("fl.xmlui.cancel();");
}

↑このswfをダイアログとして表示させるためのxmlが下記になります。

今回はswfをダイアログとして使用していますが、

swfを用意しなくてもXMLに表示するダイアログの内容を同じようなことはできます。

<?xml version="1.0" encoding="UTF-8"?>
<dialog id="CRP_dialog" title="基準点の変更">
  <flash id="CRP_dialog" width="200" height="200" src="CRF_dialog.swf" />
</dialog>

そして実行するコマンドの中身であるjsflが下記になります。

var doc = fl.getDocumentDOM();

var panel = doc.xmlPanel(fl.configURI + "Commands/CRP/CPR_dialog.xml");
fl.trace(panel);

function main(pos){
        fl.xmlui.accept();
        //posはswfから取得してくる選択部分
        var pos1 = pos.charAt(0);
        var pos2 = pos.charAt(1);
        
        fl.outputPanel.clear();
        var selectedItems = doc.selection;
        var numItem = selectedItems.length;
        if(numItem == 0){
                fl.trace('何も選択されていません');
        }
        else{
                doc.selectNone();
                for(var i = 0; i < numItem; i++){
                        var elem = selectedItems[i];
                        execControlPointFix(elem, pos1, pos2);
                }
                fl.trace("処理が完了しました");
        }
}

function execControlPointFix(target, pos1, pos2){
        doc.selectNone();
        target.selected = true;
        //fl.trace("pos1は "+ pos1 + " pos2は " +pos2);
           
        var curLayer = doc.getTimeline().currentLayer;
        var frameArray = doc.getTimeline().layers[curLayer].frames; 
        var n = frameArray.length;
        var startArray = new Array();
        //アクティブレイヤー内を順番に見ていき、それがstartFrameで、さらにそこにシンボルがあればstartArrayの配列に追加
        for(j=0; j<n; j++){
                if(j == frameArray[j].startFrame){
                        if(frameArray[j].elements == "[object SymbolInstance]"){
                                startArray.push(j)
                        }
                }
        }
        
        //↑で入った配列、つまり空白のキーフレームではないstartFrameだけの配列内をまわす
        for(i=0; i<startArray.length; i++){
                if(i==0){
                        //シンボルが入っている最初のアニメーションキーフレームへカレントフレームを移動
                        doc.getTimeline().currentFrame = startArray[i];
                        doc.selectAll();
                        
                        doc.enterEditMode('inPlace');
                        //↓ここからシンボル内の階層での編集==========================
                        doc.selectAll();
                        var beforeRect = doc.getSelectionRect();
                        var w = beforeRect.right - beforeRect.left;
                        var h = beforeRect.bottom - beforeRect.top;
                        
                        var transP = doc.getTransformationPoint();
                        var transX = transP.x;
                        var transY = transP.y;
                        
                        w = Math.round(w);
                        h = Math.round(h);
                        //fl.trace("フレーム"+ i + "  幅w " + w + " 高さh " + h);
                        
                        var nLeft = 0;
                        var nTop = 0;
                        
                        switch(pos1){
                                case 'L':nLeft = 0;break;
                                case 'C':nLeft = - w / 2;break;
                                case 'R':nLeft = -w;break;
                        }
                        
                        switch(pos2){
                                case 'T':nTop = 0;break;
                                case 'M':nTop = -h / 2;break;
                                case 'B':nTop = -h;break;
                        }
                        
                        //端数の調整
                        nLeft = Math.round(nLeft);
                        nTop = Math.round(nTop);
                        var nRight = Math.round(nLeft + w);
                        var nBottom = Math.round(nTop + h);
                        //fl.trace("nLeftは" + nLeft + " nTopは " + nTop);
                        
                        //移動する分を戻す数値を計算
                        var afterRect = doc.getSelectionRect();
                        var moveX = Math.round(afterRect.left - nLeft);
                        var moveY = Math.round(afterRect.top - nTop);
                        //fl.trace("フレーム"+ i + "  座標は " + beforeRect.left + " " + beforeRect.top);
                        //内容物の移動
                        doc.setSelectionBounds({left:nLeft, top:nTop, right:nRight, bottom:nBottom});
                        
                        doc.exitEditMode();
                        //↑ここでシンボル内の階層から出て元の階層に==========================
                        
                        //移動する分を戻す処理
                        doc.moveSelectionBy({x:moveX, y:moveY});
                        
                        doc.setTransformationPoint({x:0, y:0});
                }else{
                        //以下は最初のフレーム以外の位置修正
                        //2つ目以降のアニメーションキーフレームにカレントフレームを移動
                        fl.getDocumentDOM().getTimeline().currentFrame = startArray[i];
                          
                        doc.selectAll();
                        doc.moveSelectionBy({x:moveX, y:moveY});
                        doc.setTransformationPoint({x:0, y:0});
                        //fl.trace("フレーム"+ i + "  moveX " + moveX + " moveY " + moveY);
                }
        }
}

swfから送られた選択した位置を表すValueの2文字の文字列を

charAtで1文字目と2文字目に分けています。

Valueの文字列は1文字目に左(L)・中(C)・右(R)、2文字目に上(T)・中(M)・下(B)で

これらの組み合わせで移動値の計算をしています。

 

あとは大体スクリプト内のコメントに書いていますが、

選択されているレイヤーの中をfor文でまわしてstartFrameがあったら

さらにシンボルがあるかを比較して(空白キーフレームじゃなければ)、

そのフレームの番号を配列に追加しています。

 

そのあとで配列に入ったフレームの中をさらにfor文でまわして

その配列の中の最初のフレームだけシンボルの中に入って基準点を変更して、

それ以降のフレームでは位置だけを戻しています。

 

使用上の注意点

・1レイヤー1シンボル(シンボルの基準点を変更しますので他のレイヤーでも併用していた場合そちらのレイヤーでの位置が変わったままになってしまっています)

・回転や拡大のアニメーションには対応していません…(移動のアニメーションがついてる場合にのみ対応できます。対応できないか考えましたが今の自分の頭ではいい解決法が見つかりませんでしたorz)

 

何かいい方法ご存知の方いらっしゃいましたらお教え下さい。

 

※このスクリプトを利用した際に生じたいかなる損害に対しても補償できかねますので、

自己責任にてご使用ください。


zipファイルのDL

http://sdrv.ms/135sL14

 

DLされましたらFlashのCommandsのフォルダにコピーしてもらえば使えます。

例)C:\Users\ユーザー名\AppData\Local\Adobe\Flash CS5\ja_JP\Configuration\Commands

 

コメントをお書きください

コメント: 2
  • #1

    Carli Surber (日曜日, 22 1月 2017 18:43)


    It's a shame you don't have a donate button! I'd definitely donate to this outstanding blog! I suppose for now i'll settle for bookmarking and adding your RSS feed to my Google account. I look forward to new updates and will share this website with my Facebook group. Chat soon!

  • #2

    dobry sex telefon (水曜日, 01 11月 2017 02:06)

    nieposykiwanie