「選択中のフレーム数表示・変更」コマンド

こちらは現在の所、仕様に迷っているところがあるので、テスト版です。

現在MIT ライセンスになってますが、将来的に著作者表示義務なしに変わるかもしれません。明文化してるもっと緩いライセンスがあればそちらを採用する予定です。

「選択中のフレーム数表示・変更」コマンドは、タイムライン上をダブルクリックすることで選択できる、キーフレームから次のキーフレームの間までのフレー ム数を数え、変更するのを第一の目的としています。

フレームを選択してないとアラートがでて選択されるように促されますので、最低1つ以上のフレームを選択して利用して下さい。

派生機能として、キーフレームによらず選択したフレームの数を表示できますが、その後フレーム数の増減 機能を利用する場合には、キーフレーム間を認識して調整を行います。

既知のバグ

  • CS4のトゥイーン(クラシックトゥイーンは平気)で使用するとそのレイヤーの総フレーム数が取れてしまう(1.0.1で対応済み)
  • 削除するフレームにレイヤーの終端フレームを含むとスクリプトエラーが発生する(1.0.1で対応済み)

現在の所存在しません

インストール方法

インストールには二つの方法があります。

  1. MXPファイルをダウンロードしてインストールする
  2. 直接ユーザごとに用意されているFlashのConfigurationフォルダに格納する

MXPファイルでインストール

誰でも簡単にインストールが行えます。アンインストールもAdobe Extension Managerを利用できるので扱いやすくなっています。

  1. Adobe Extension Manager CS3またはCS4(CS4以降専用)がインストール済みであることを確認して下さい(CS3が入っていればまず導入済みです)
  2. MXPファイルをダウンロードします
  3. MXPファイルをダブルクリックすると自動的にAdobe Extension Manager が起動してエクステンションのインストールが開始されます

直接ユーザごとに用意されているFlashのConfigurationフォルダに格納する

通常自分でFlashのCommandを登録する場合に、こちらを利用します。

ユーザーレベル設定フォルダにあるCommandsフォルダに下にあるコードをコピーして「選択中のフレーム数表示・変更.jsfl」ファイルを作成する。ユーザーレベル設定フォルダは次の通りです。(ヘルプを参考に自分の環境にあるフォルダをみて書いています。斜体は各自の環境に読み替えて下さい。)

Windows XPの場合
"ブートドライブDocuments and Settingsユーザー名Local SettingsApplication DataAdobeFlash バージョン言語ConfigurationCommands"
Windows Vistaの場合
"ブートドライブ¥Users¥ユーザー名¥AppData¥LocalAdobeFlash バージョンjaConfigurationCommands"
OS Xの場合
"起動ディスク/Users/ユーザー名/Library/Application Support/Adobe/Flash バージョン/言語/Configuration/"

選択中のフレーム数表示・変更.jsfl ソースコード

/*
   選択中のフレーム数表示・変更.jsfl
   バージョン 1.0.1

   Flash CS3/CS4でテストをしているコマンドです。
   選択中のフレーム数を表示し、指定するフレーム数/時間に調整します。
   0や極端に小さいフレーム数を指定すると、現在の表示中のフレームから
   次のキーフレーム(全レイヤーを確認)まで削除することもできます。
   連絡先 RsStudio 湯口りさ <risa.yuguchi@gmail.com>
   Twitter: http://twitter.com/risay
   
   履歴
   1.0.1
   ・各レイヤーの最終フレームを含むレイヤーを削除しようとするとキーフレームかどうかの判定でスクリプトエラーが出るのを削除
   ・CS4のオブジェクトベーストゥイーンをダブルクリックしたときフレーム数が正しくカウントされないのを修正
   1.0.0
   公開

The MIT License

Copyright (c) 2008 Risa Yuguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

/*
 環境取得
*/
//タイムラインの取得
var timeline = fl.getDocumentDOM().getTimeline();
//選択中のフレームの取得
var theSelectedFrames = timeline.getSelectedFrames();
//現在のフレームを取得
var currentFrame = timeline.currentFrame;
//現在のレイヤー
var currentLayer = timeline.currentLayer;
//現在のフレームレート
var frameRate = fl.getDocumentDOM().frameRate;

/*
 変数準備
*/
//エラーがあるかどうかのフラグ
var isError = false;
//選択フレームの登録用配列
var selected = [];
//メッセージの格納文字列
var msg = "";

/*
==========================================================================
メイン
==========================================================================
*/
fl.outputPanel.clear();
if(theSelectedFrames.length>0) {//選択しているフレームがあれば
	
	//選択フレームの開始位置、終了位置、フレーム数を記録
	var startIndex = getStartFrame();
	var endIndex = getEndFrame();
	var theSelectedFrameCount = endIndex - startIndex;
	
	//フレーム数変更のメイン処理へ
	changeFrame();
	
} else {
	msg = "フレームを選択して下さい";
	setError("noSelectedFrameError");
}

//以下最後の確認表示がいらない人はコメントアウトして下さい。
finalize();


/*
==========================================================================
サブルーチン
==========================================================================
*/

/**
 * メインのフレーム数調整用
 */
function changeFrame() {
	//選択したフレーム数を表示し、変更するかユーザに尋ねる
	
	var theOldTimes = changeFrames2Time(theSelectedFrameCount);
	var setFrame = prompt("変更後フレーム数は?" +
						"(現在: " + theSelectedFrameCount +
						"fr/" + theOldTimes +"秒)",
						theSelectedFrameCount);

	// 結果報告めっせーじの初期化
	msg = "変更はありませんでした。";
	
	//nullなら何もしない
	if (setFrame == null || setFrame == theSelectedFrameCount) {
		msg = "";
		return;
	}
	// 1sなら1秒のように秒数指定ができる
	if (String(setFrame).indexOf("s")>0) {
		setFrame = changeTime2Frames(setFrame.split("s")[0]);
		
	}
	//数字だったら
	if(!isNaN(setFrame)) {
		var def = setFrame-theSelectedFrameCount;
		endIndex += def;
		
		if (setFrame == 0) {//指定が0の場合
			msg = deleteFramesToNextKeyFrame();
		} else if (def>0) {//選択フレームより多い場合
			msg = addFrames(def);
		} else if (def<0) {//選択フレームより少ない場合
			def *= -1;
			msg = deleteFrames(def);
		}
		
		
		//レイヤーの選択状態を初期に戻す
		timeline.currentLayer = currentLayer;

		//選択状態をフレーム数変化後に
		for(var i=0;i<theSelectedFrames.length;i+=3) {
			var layer = theSelectedFrames[i];
			selected.push(layer)
			selected.push(startIndex)
			selected.push(endIndex);
		}
		//過去の選択状態を消した新しい選択状態をタイムラインに反映
		timeline.setSelectedFrames(selected,true);

		timeline.currentFrame = currentFrame-1;

		//メッセージに実行前実行後の結果表示
		var theNewTimes = changeFrames2Time(endIndex-startIndex);
		msg += "
実行前のフレーム数 "+theSelectedFrameCount+"("+theOldTimes+"秒)
"+
		"実行後のフレーム数 "+(endIndex-startIndex)+"("+theNewTimes+"秒)";

		
	} else {
		msg = "フレーム数は1以上数字か、「1s」(1秒)という形で入力して下さい";
		setError("invaildInput");
	}
}

/**
 * 終了処理
 */
function finalize() {
	if (msg=="") return;
	//注意書き追加
	msg += "
問題がある場合には、Ctrl+Z(cmd+Z)で一つ前の状態に戻って下さい。";

	if (isError) {//エラーがあるときは強制アラート
		alert(msg);
	} else {//無事終了したらTrace文
		fl.trace(msg);
	}
}

/**
 * オブジェクト基準のトゥイーンでも、通常のトゥイーンでも正常に選択開始フレーム番号を返す
 * @return Number フレーム番号
 */

function getStartFrame() {
	if (theSelectedFrames.length==3 && timeline.layers[currentLayer].frames[currentFrame].tweenType == "motion object") {
		return timeline.layers[currentLayer].frames[currentFrame].startFrame;
	} else {
		return theSelectedFrames[1];
	}
}
/**
 * オブジェクト基準のトゥイーンでも、通常のトゥイーンでも正常に選択終了フレーム番号を返す
 * @return Number フレーム番号
 */

function getEndFrame() {
	if (theSelectedFrames.length==3 && timeline.layers[currentLayer].frames[currentFrame].tweenType == "motion object") {
		return timeline.layers[currentLayer].frames[currentFrame].startFrame + timeline.layers[currentLayer].frames[currentFrame].duration;
	} else {
		return theSelectedFrames[2];
	}
}
/**
 * フレーム数から時間を生成
 * @param Number ターゲットとなるフレーム数
 * @return Number 再生時の時間
 */
function changeFrames2Time(targetFrames) {
	if (isNaN(targetFrames)|| targetFrames<1) {
		return 0;
	}
	return Math.floor(targetFrames/frameRate*10)/10;
}

/**
 * 時間からフレーム数を生成
 * @param Number ターゲットとなるフレーム数
 * @return Number フレーム数
 */
function changeTime2Frames(targetTime) {
	if (isNaN(targetTime)) {
		return 0;
	} else {
		return Math.max(0,Math.ceil(targetTime*frameRate));
	}
}

/**
 * フレームを指定数分追加
 * @param Number 追加フレーム数指定
 * @return String メッセージ
 */
function addFrames(frameNum) {
	if (isNaN(frameNum)) {
		setError("addFrameError");
		return "作業が実行できませんでした";
	} else {
		//現在のフレームで全フレームに指定数のフレームを増やす
		timeline.insertFrames(frameNum,true);
		return frameNum+"フレーム増やしました。";
	}
}

/**
 * フレームを指定数分削除
 * @param Number 削除フレーム数指定
 * @return String メッセージ
 */
function deleteFrames(frameNum) {

	var str = frameNum+"フレーム削除しました。";

	//フレーム選択を解除して、全レイヤーのフレームを削除できるようにする
	timeline.setSelectedFrames([]);
	
	//規定数まで1フレームずつフレームを削除(全レイヤーに適用するため)
	var layer;
	var isEnd = false;
	while(frameNum>0) {
		for(var i=0;i<timeline.layers.length;i++) {
			layer = timeline.layers[i];
			var flg = (layer.frames[timeline.currentFrame] && layer.frames[timeline.currentFrame].startFrame == timeline.currentFrame);
			if (flg) {
				if(!confirm("このまま実行するとレイヤー「"+layer.name+"」上のキーフレームが消える可能性がありますがよろしいですか?")) {
					str = "実行中にフレームの削除を停止しました。";
					setError("deleteFrameError", startIndex+frameNum);
					isEnd = true;
					break;
				}
			}
		}
		if (isEnd) {
			break;
		}
		timeline.removeFrames();
		frameNum--;
	}
	return str;
}

/**
 * フレームを現在のフレームから次のキーフレームまで削除
 * @param Number 削除フレーム数指定
 * @return String メッセージ
 */
function deleteFramesToNextKeyFrame() {
	var frameNum = 0;
	//フレーム選択を解除して、全レイヤーのフレームを削除できるようにする
	timeline.setSelectedFrames([]);

	var layer;
	var isEnd = false;
	while(timeline.frameCount>=timeline.currentFrame) {
		for(var i=0;i<timeline.layers.length;i++) {
			layer = timeline.layers[i];
			if (layer.frames[timeline.currentFrame] != null && layer.frames[timeline.currentFrame].startFrame == timeline.currentFrame) {
				isEnd = true;
				break;
			}
		}
		if (isEnd) {
			break;
		}
		timeline.removeFrames();
		frameNum++;
	}
	endIndex = currentFrame;
	return frameNum+"フレーム削除しました。";
}

/**
 * エラーフラグを立てエラーコードを出力にはきだし、必要なら処理をする
 * @param String エラーコード
 * @param * 処理が必要な場合はこの引数で引き渡す
 */
function setError(errorCode,val) {
	isError = true;
	switch (errorCode) {
		case "invaildInput":
		case "noSelectedFrameError":
		case "addFrameError":
			break;
		case "deleteFrameError":
			if(val != null && !isNaN(val)) {
				endIndex = arguments[1];
			}
			break;
	}
	fl.trace("コマンド実行中にエラーが発生しました:"+errorCode);
	fl.trace(msg);
}

使い方1:フレーム数の確認

任意のフレームをダブルクリックして、2つのキーフレームの間のフレームを選択し、「コマンド>選択中のフレーム数表示・変更」としてください。

次のようなダイヤログが現れ、現在選択している範囲のフレーム数と時間が表示されます。

tl_files/flash/framecount/framecount_02.png

使い方2:フレームを増減する

フレームを指定フレーム数または指定秒に増減させられます。

特に減らすときに問題になりますが、フレームを増減する起点が現在のレイヤーであることに注意が必要です。キーフレームやキーフレームを乗り越えた形でフレームが減ると意図しない結果になることが多いので、確認のアラートが出たときにはよく確かめて操作をして下さい。

フレーム数指定法

テキストフィールドに数字を入れます。

秒数指定方法

テキストフィールドに設定したい秒数+s(半角小文字)を書き入れます。1sなら、1秒になり、1.5sなら1.5秒分のフレーム数になります。(増加するか減少するかは現在のフレームで確認して下さい。

再生ヘッドから次のキーフレームまで削除する指定

テキストフィールドに0と書きます。0と書いたときは特別な数字と見なし、現在の再生ヘッドからタイムライン上の次のキーフレームまでフレームを削除します。

質問などなんでも受け付けています

*
*
7 と 3 の合計はいくつですか?
*