[JSFL]座標の小数点を丸めるJSFL使用時の注意(Windows FlashCS4,CS5で確認)

ステージ上のオブジェクトの座標を整数に丸めてくれる便利JSFLに罠があることに気づきました。
CS5で気づいて、CS4でも同じことになったから既知の現象でしょう。

丸めるJSFLはいろんな方が公開してくれてるのでボクもどこかで拾ったものを使ってます。
↓こんなの

var doc = fl.getDocumentDOM();
if (doc.selection.length) {
for (var i = 0 ; i < doc.selection.length ; i++){ var mat = doc.selection[i].matrix; mat.tx = Math.round(mat.tx); mat.ty = Math.round(mat.ty); doc.selection[i].matrix = mat; } } [/sourcecode] 選択したオブジェクトを一括でバーンと変換してくれて便利なんですが、保存時に結果を変換後の座標を保持してくれないことがあるようだということに気づき、なんとなく原因と対策っぽいこともわかったのでメモしときます。


まず、座標を保持しない再現手順を書きます。
(うちでの再現率:100%)

■手順(準備編)

  • 1.新規flaファイルを作成
  • 2.何でもいいから四角いシェイプを書いてMC化(シンボル1とする)
  • 3.シンボル1をさらにMC化(シンボル2とする)
  • 4.シンボル2の中に入り、シンボル1のx座標を0.5にする(プロパティパネルから数値変更)
  • 5.保存して、ファイルを閉じる。
  • 6.再度ファイルを開き、シンボル2の中のシンボル1の座標を確認するとx座標は0.5となっている。

→ここまでは何の問題もない

■手順(不具合発生編)

  • 7.シンボル1を選択した状態で上記JSFLを実行する。
  • 8.プロパティパネル上では0.5が1となっているはず。
  • 9.ファイルを上書き保存して閉じる。
  • 10.ファイルを開いて、シンボル2の中のシンボル1の座標を確認するとx座標は0.5となっている。

→なにこれ、ばかなの、しぬの


ちなみにJSFLを使わずに手動でプロパティパネルの数値を0.5→1に変更した場合は保存は反映されます。
(当たり前か)

では何が問題か。
ここからは推測ですが、上記JSFLでの結果ではflaファイル的には「変更扱いにされていない」っぽいようです。
ためしに上記手順8まで実行した状態でファイルを保存するまえにシンボル2の中のタイムラインのレイヤーをひとつふやしてから保存して開き直してみると、こんどはちゃんとシンボル1座標変更が反映されているのが確認できます。

ここで注意が必要なのは、シンボル2の中のタイムラインをいじったということ。

シンボル2のタイムラインではなく、メインタイムラインのレイヤーをひとつふやしてもシンボル1の座標変更は反映されません。
つまりはFlashはMC単位で変更があったかなかったかを判断して、状態を保存するかしないかを決めてるっぽいので関係ないタイムラインに変更を加えても意味がない、ということになりそうです。


というわけで、対策
確実に「MCに変更を加えたぞ」と判らせてあげるために、上記JSFLを改造。

var doc = fl.getDocumentDOM();
if (doc.selection.length) {
for (var i = 0 ; i < doc.selection.length ; i++){ var mat = doc.selection[i].matrix; mat.tx = Math.round(mat.tx); mat.ty = Math.round(mat.ty); doc.selection[i].matrix = mat; } } //追加:レイヤーを追加して、追加したレイヤーを消す doc.getTimeline().addNewLayer(); doc.getTimeline().deleteLayer(); [/sourcecode] 最後に2行追加しただけです。 レイヤーを追加してすぐにその追加したレイヤーを削除する。 結果的には何の変化もない意味のない処理ですが、これで「MCに変更を加えたぞ」とflaに判らせてあげることができるようになります。 このJSFLを用いて上記手順を実行すると小数点丸めは確実に保存時に反映されるようなりました。 かなり力技な感じですが、もっとマシな方法がありました教えてくださいませ。 (果たしてCS5.5では直ってるのか?・・・まぁ直ってないだろうな。。)

[JSFL]シンボル内の静止テキストのサイズ、フォントを変更するJSFL

製作経緯はこんなかんじ。
e-ラーニング系のコンテンツをタイムラインのアニメーションで製作中のこと。
静止テキストのモーショントゥイーンを大量にステージ配置。
雛形できたら大量生産するぜー、と5ファイルくらい作ってたところで、ここにきてテキスト関係の仕様の提示。
OH MY GOD(ってかちゃんと確認しないで作り始めたボクが悪い)
フォントサイズの変更、フォント色の変更、フォントの変更。。。
1個1個MCの中に入って静止テキストを変更するのめんどくさい。。。
1ファイルあたりMCが10個以上あるし。。。
!そうだ!これ、JSFLでできるんじゃね!?
とこんな感じ。

というわけで以前作ったソースをちょろっと変更してできたのはこんな感じ。
使い方
色を変更したいMCをライブラリで選択し(複数OK)、コマンドを実行。
それぞれ値を入力するダイアログがでるので値を入力すればOK。
※内部にテキストフィールドが1個だけあるようなシンボルの変更を想定してますのでそれ以外はどうなるかわかりません。。。

◆フォントサイズ変更

var doc = fl.getDocumentDOM();
var num = prompt(“フォントサイズを入力”, “18”);

var items = doc.library.getSelectedItems();
for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); doc.setElementTextAttr('size',num); doc.exitEditMode(); } [/sourcecode] ◆フォント変更 [sourcecode language='js'] var doc = fl.getDocumentDOM(); var fontName = prompt("フォントを指定", "A-OTF 新ゴ Pro L"); var items = doc.library.getSelectedItems(); for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); doc.setElementTextAttr('face',fontName); doc.exitEditMode(); } [/sourcecode] ※ここで引っかかったのはフォントの指定。 フォント名を指定するときに、flashのヒストリパネルに表示されるjsflをそのまま使ったらフォントが反映されない。 たとえば、新ゴProのLを指定したいときには、 jsflには、setElementTextAttr('face','ShinGoPro-Light');と表示されたのでそのままコピペしたら動作しない。 フォント名を取得するサンプルで取得したフォント名を使用すると上手くいった。
setElementTextAttr(‘face’,’A-OTF 新ゴ Pro L’);ってな感じになります。
この差異の原因はFlashが日本語版か英語版かってことなのかな、まぁよくわからん。

おまけ
色と、フォントと、サイズをいっぺんに変更できるやつ

◆いろいろいっぺんに変更

var doc = fl.getDocumentDOM();
var num = prompt(“フォントサイズを入力”, “18”);
var fontName = prompt(“フォントを指定”, “A-OTF 新ゴ Pro L”);
var color = prompt(“テキストの文字色を入力”, “#000000”);
var items = doc.library.getSelectedItems();
for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); //サイズ変更 doc.setElementTextAttr('size',num); //フォント変更 doc.setElementTextAttr('face',fontName); //色変更 doc.setFillColor(color); doc.exitEditMode(); } [/sourcecode] 一応、一式ダウンロードはこちら

[JSFL]シンボル内のオブジェクトの色を一括で変更するコマンド

製作経緯はこんなかんじ。
e-ラーニング系のコンテンツをタイムラインのアニメーションで製作中のこと。
静止テキストのモーショントゥイーンを大量にステージ配置。
あれ。。。よく確認してみたら仕様と違う。。。テキストの色間違ってるじゃん。。。
もう3ファイルくらい作ってて、静止テキストをラップしたMCが大量にあるよ。。。
1個1個MCの中に入って静止テキストの色を変更するのめんどくさい。。。
1ファイルあたりMCが10個以上あるし。。。
!そうだ!これ、JSFLでできるんじゃね!?
とこんな感じ。

そしてできたのはこんなかんじ。
使い方
色を変更したいMCをライブラリで選択し(複数OK)、コマンドを実行。
色を入力するダイアログがでるので色値を入力すればOK。
※MCだけじゃなくて、グラフィックとかボタンでもOK。
※静止テキストだけじゃなくて、シェイプの色も変わります。

var doc = fl.getDocumentDOM();
var items = doc.library.getSelectedItems();
ret = prompt("テキストの文字色を入力", "#000000");
//alert(ret);
for (var i = 0; i < items.length; i++) {
  doc.library.editItem(items[i].name);
  doc.selectAll();
  doc.setFillColor(ret);
  doc.exitEditMode();
}

当初はステージに配置してあるオブジェクトを選択して選択されたMCの中の色を変更しようとしてたのだけど、どうも上手くいかない。
でも良く考えたらこの動作ってライブラリ内のオブジェクトを変更するのと同じことだからこれでいいや、と。

欲しい人いるかはわからんけど一応zipでおいておこう。
シンボル内のオブジェクトの色変更する.jsfl

[JSFL][?]JSFLでモーショントゥイーン(色)させる

久しぶりにタイムラインでの作業。
MCのカラーを黒→赤、または赤→黒といったモーション(時間は4フレーム)で行うという作業が大量に発生。
最初はとりあえずクラシックトゥイーンにショートカットを割り当ててシコシコやっていたけど、よく考えたら、全部コマンド化して一括に実行すればいいんじゃね?と思い、試してみました。

まずはヒストリパネルから、必要な手順を選んでjsfl化しようと思ったのですが・・・
フレームの移動の部分をjsfl化してくれないので無理ということに。
※ヒストリパネルからコマンド作成は、↓の記事が参考になりました。
Mattari Blog:jsflのすすめ

じゃあ、足りない部分は自分でjsfl書いてみる!ということでjsfl初チャレンジ!!

で、できたのがこちら。

// 赤になる
// This command was recorded by Adobe Flash CS4.

//タイムラインを変数で保持
var path = fl.getDocumentDOM().getTimeline();

// インスタンスの濃淡: '#ff0000', 100%
fl.getDocumentDOM().setInstanceTint('#ff0000', 100);

//フレーム数を取得
var fr4 = path.currentFrame-4;

//指定したフレームをキーフレームに変換
path.convertToKeyframes(fr4);

//指定したフレーム数をモーショントゥイーンに変換
path.createMotionTween(fr4);
// 黒になる
// This command was recorded by Adobe Flash CS4.

var path = fl.getDocumentDOM().getTimeline();

// インスタンスプロパティ: colorMode, none
fl.getDocumentDOM().setElementProperty('colorMode', 'none');

//フレーム数を取得
var fr4 = path.currentFrame-4;

//指定したフレームをキーフレームに変換
path.convertToKeyframes(fr4);

//指定したフレーム数をモーショントゥイーンに変換
path.createMotionTween(fr4);

使い方としては、トゥイーンを終了させたい位置にキーフレームを打って、上記のコマンドを実行すると、
それぞれ4個前のフレームから始まるモーショントゥイーンが設定されます。

本当は、最初のキーフレームを打つ部分もjsflにまとめたかったのだけど、その処理を入れると色のプロパティを変更する処理が実行されなかったのよね・・・
なんかできそうな気はするけど、こんどえらい人に聞いてみよう。