2011-10-28

After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集

After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集

今回のテーマは「1行スクリプト」昔のプログラム雑誌でたまにあったネタです。
1行だけのコーディングでどれだけ出来るか競うものでなかなか面白いものですが、ちょっと企画倒れしてただの便利な関数集になっています。

1行の定義を半角255文字以内としています。まぁ昔のテキストエディタの1行の限界が8bit長だったのでそれを基準にしました。ですが、えらい読みづらいコードになってしまったので、80文字位を目安にインデントしています(1行じゃない^^;)

今回作成したスクリプトはひとつのファイル(prototypeUno.jsx)にまとめてあります。以下のリンクからダウンロード出来ます。
prototypeUno.zip

ファイル名から察することができますが、今回作った1行スクリプトは基本的にprototypeとして作成してあります。prototypeを使ったプログラミングの例として見てください。

最初はネタとして投稿するつもりでしたが、なんか意外につかえるライブラリになっていたので実用的なTips集みたいな感じになっています。

prototypeとは

まず最初にprototypeの簡単な説明です。

prototypeJavaScript独自の機能でかなり面白い仕組みで、詳細はgoogleさんで調べてもらったほうが早いと思います。ここでは簡単な使い方だけ説明します。

JavaScriptでは以下のサンプルのように適当なObjectに変数を追加することができます。

app.project.item(1).dummy = 1;
alert(app.project.item(1).dummy); //OK
 
alert(app.project.item(2).dummy); //エラー(undefined)になる
 
app.project.item(2).dummy = 2;
alert(app.project.item(2).dummy); //OKになる


このように動的に変数が追加できるのはJavaScriptの大きな特徴です。
ただ、Objectを作成するごとに変数を追加するのは面倒なので、元となるObjectクラスに変数を追加(拡張)できる機能をprototypeで実装できます。

使い方(宣言)の方法は簡単で、下のサンプルのようになります。

CompItem.prototype.defaultFrameRate = 24;
 
var ac = app.project.activeItem;//CompItemを選択しているとする。
alert(ac.defaultFrameRate);//ちゃんと24と表示される。


上のサンプルはCompItem ObjectdefaultFrameRate変数を追加しています。
このようにprototype定義された変数は同じ型のObject全てに追加されます。

本当はもっと複雑な仕組みですが、まぁこんな感じにアバウトに捉えてた方が使いやすいです。

興味のある方は”prototype“と”__proto__“をgoogleで調べてみると面白いと思います。

追加はObjectなら何でもいいのでFunction Objectつまり関数も定義できます。

CompItem.prototype.getSize = function(){ return [this.width,this.height];}
 
var ac = app.project.activeItem;//CompItemを選択しているとする。
alert(ac.getSize().toString());


prototypeで追加する変数に対して無名関数で関数を定義しています。
もちろん普通の関数も追加することができます。

function getSize()
{
	return [this.width,this.height];
}
CompItem.prototype.getSize = getSize;
 
var ac = app.project.activeItem;//CompItemを選択しているとする。
alert(ac.getSize().toString());


prototyepで宣言した変数・関数は後は普通の変数・関数と同じように使えます。
注意する点として動的に同名の変数で上書きしてしまっても、その後に作成したObjectには影響を受けないって事くらいです。

下のサンプルを実行してみると何となくわかると思います。

//あらかじめダミーのコンポを二つだけ作成すること
CompItem.prototype.foo = "foo"; //foo変数をfooで宣言
 
var comp1 = app.project.item(1);//CompItemだとする
var comp2 = app.project.item(2);//CompItemだとする
 
alert("comp1:"+comp1.foo);	//fooと表示される
alert("comp2:"+comp2.foo);	//fooと表示される
 
comp1.foo = "bar";	//barで上書き
alert("1 comp1:"+comp1.foo);	//barと表示される
alert("1 comp2:"+comp2.foo);	//fooと表示される
 
delete comp1.foo;	//わざと消す
 
alert("2 comp1:"+comp1.foo);	//fooと表示される。元のfooが復活してる
alert("2 comp2:"+comp2.foo);	//fooと表示される
 
CompItem.prototype.foo = "bar"; //foo変数をbarでprototypeを上書き
alert("3 comp1:"+comp1.foo);	//barと表示される。prototypeが上書きされたから
alert("3 comp2:"+comp2.foo);	//barと表示される


以上がprototypeの簡単な説明です。

1行スクリプト集(prototypeUno.jsx)について

prototypeUno.jsxは、実は僕が作っているbryfulライブラリをprototypeとして再定義したものになります。
元が関数スタイルのライブラリだったのですが、prototypeスタイルにしたら異様に使いやすくなってびっくりです。
prototypeUno.jsxは一回実行すればいいので、Scripts/Startupフォルダに入れておけば起動後すぐに使うことができます。

prototypeUno.jsxが実行されたかどうかは、(app.uno != undefined)で調べることができます。

例えば使われていない平面を収集するスクリプトを普通に書けば

var fld = app.project.items.addFolder("使われていない平面");
for ( var i=1; i < app.project.numItems; i++){
    var target = app.project.item(i);
    if ( target instanceof FootageItem){
        if ( target.mainSource.color != undefined){ //平面か調べる
            if (target.usedIn.length <=0) target.parentFolder = fld;
        }
    }
}


となりますが、prototypeUno.jsxで拡張された機能で書くと以下のようになります。

var fld = app.project.folder("使ってない平面");
app.project.getSolid().interate(
	function(t){
		if ( t.noneUsed()) t.parentFolder = fld;
	}
);


分かりやすくするためにインデントしてますが、ほぼ1行分のコードで実装できてしまいます。

深い階層のフォルダも一発で作れます。

//深い階層のフォルダを作成。
//同名フォルダがあったらそれを返す。
var fld = app.project.folder("foo1").folder("foo2").folder("foo3");


選択したコンポの大きさを変える

//選択したコンポの大きさを変更
var sz = app.compSizeDialog();
if ( sz !=null){
	app.beginUndo();
	app.project.getSelectedComp().interate(
		function(cmp){
			cmp.width = sz.width;
			cmp.height = sz.height;
		}
	);
	app.endUndo();
}


選択されたレイヤの位置をシフト(移動)するスクリプトも下のように簡単にかけます。

//選択したレイヤの位置をシフトする
var shiftPos = [100,50];//この値でシフトする
app.beginUndo();
function sft(v){ return [ v[0]+shiftPos[0], v[1]+shiftPos[1] ];}
app.project.selectedLayers().interate(
	function(tLayer){
		var p = tLayer.getPos();
		if ( p.numKeys==0){
			p.setValue(sft(p.value));
		}else{
			p.interate(
				function(pro,idx){pro.setValueAtKey(idx, sft(pro.keyValue(idx)));}
			);
		}
	}
);
app.endUndo();


ちなみに普通に書くと下のようになります。(意外と短くなった)

//選択したレイヤの位置をシフトする
var shiftPos = [100,50];
function sft(v){return [ v[0]+shiftPos[0], v[1]+shiftPos[1] ];}
var ai = app.project.activeItem;
if ( ai instanceof CompItem){
	if ( ai.selectedLayers.length>0){
		app.beginUndoGroup("Pos Shift");
		for ( var i=1; i<=ai.selectedLayers.length;i++){
			var p = ai.layer(i).property("ADBE Transform Group").property("ADBE Position");
			if ( p.numKeys==0){
				p.setValue(sft(p.value));
			}else{
				for ( var j=1; j<=p.numKeys; j++){
					p.setValueAtKey(j, sft(p.keyValue(j)));
				}
			}
		}
		app.endUndoGroup();
	}
}


prototypeUno.jsxの関数リスト

◎ロード確認用

元Object名称type内容
ApplicationunoObjectversion:”1.00″ ロード確認用の変数

◎ファイル名の処理

元Object名称type内容
StringgetParent()function親フォルダのパスを取り出す。
“/c/bin/aaa.ext”から”/c/bin”を切り出す
StringchangeExt(newExt)function指定した書拡張子に変更(dotを必ず入れること)空文字を入れれば拡張子の消去。
StringgetName()functionファイル名のみ取り出す(拡張子付き)
“/c/bin/aaa.ext”から”aaa.ext”を切り出す
String
File
getExt()function拡張子のみを取り出す。
“/c/bin/aaa.ext”から”.ext”を切り出す
String
File
getNameWithoutExt()function拡張子なしのファイル名を取り出す。
“/c/bin/aaa.ext”から”aaa”を切り出す

◎Stringの拡張

元Object名称type内容
StringreplaceAll(src,dst)function文字の置換。(全ての一致した部分を置換)
Stringtrim()function文字列の前後の空白・改行コードを取り除く


◎改行付きの文字列操作

元Object名称type内容
StringtoLines()function文字列を改行ごとに配列に変換
ArraytoLineStr()function配列を改行区切りの文字列に変換

◎Arrayの拡張

元Object名称type内容
ArrayindexIn(index)function指定した番号が配列の要素数内であればtrueを返す。
Arrayclear()function配列をクリア(要素数を0に)
Arrayclone()function配列を複製
Arrayfirst()function配列の先頭を取り出す
Arraylast()function配列の最後を取り出す
ArrayremoveAt(index)function指定したインデックス番号の要素を削除
Arrayswap(idx0,idx1)function指定したインデックス番号で要素を入れ替える

◎Collectionの配列化

元Object名称type内容
ItemCollection
LayerCollection
toArray()functionコレクションを普通の配列に変換
ArraytoArray()function配列自身を返す
StringtoArray()function文字列を1文字1文字で配列に変換

◎Numberの拡張

元Object名称type内容
Numberzero3()function値を先頭を0で埋めて3桁して文字列に変換。

◎テキストファイルの読み書き

元Object名称type内容
FileloadText()function文字列を読み込む
FilesaveText(str)function文字列を書き込む
Stringsave(file or path)function文字列を書き込む
引数は File objectかファイルのパス文字列

◎interate(配列の要素全てに指定した関数を適応させる。指定する関数の引数に注意)

元Object名称type内容
Array
ItemCollection
LayerCollection
interate(func(t,idx))function配列の要素全てにfnc関数を適応
Propertyinterate(func(this,idx))function配列の要素全てにfnc関数を適応

◎種類の識別用
種類の識別用にFootageItem/CompItem/FolderItemに以下の関数を定義する

元Object名称type内容
FootageItem
CompItem
FolderItem
isSound()functionwav等のサウンドフッテージならtrue
FootageItem
CompItem
FolderItem
isSolid()function平面フッテージならtrue
FootageItem
CompItem
FolderItem
isStill()function静止画フッテージならtrue
FootageItem
CompItem
FolderItem
isSequence()function動画フッテージならtrue
FootageItem
CompItem
FolderItem
isComp()functionコンポジションならtrue
FootageItem
CompItem
FolderItem
isFolder()functionフォルダーアイテムならtrue
FootageItem
CompItem
FolderItem
isNotStill()function秒数を持たないアイテムならtrue
FootageItemnoneUsed()functionフッテージアイテムが何も使われていないときはtrue

◎Application objectの拡張
種類の識別用にFootageItem/CompItem/FolderItemに以下の関数を定義する

元Object名称type内容
ApplicationversionNumber()functionAfterEffectsのバージョンを数値で獲得
900/1000
ApplicationmajorVersion()functionAfterEffectsのバージョンを文字列で獲得
CS4/CS5
Application__pushD__ArraypushD/popDで使用する変数
ApplicationpushD()function現在のカレントディレクトリを保存
ApplicationpopD()function保存したカレントディレクトリを復帰
ApplicationgetCurrentPath()functionカレントティレクトリのフルパス(デコード済み)
ApplicationgetCurrentPathD()functionカレントティレクトリのフルパス(デコード前)
ApplicationgetScriptFile()function現在実行中のスクリプトファイル自身の File objectを獲得
ApplicationgetScriptName()function現在実行中のスクリプトファイル名を獲得(デコード済み)
ApplicationgetScriptNameD()function現在実行中のスクリプトファイル名を獲得(デコード前)
ApplicationgetScriptTitle()function現在実行中のスクリプトファイル名(拡張子なし)を獲得
ApplicationgetScriptPath()function現在実行中のスクリプトファイルの親フォルダのパスを獲得(デコード済み)
ApplicationgetScriptPathD()function現在実行中のスクリプトファイルの親フォルダのパスを獲得(デコード前)
ApplicationbeginUndo()functionものぐさbeginUndoGroup
ApplicationendUndo()functionものぐさendUndoGroup

◎接続されているモニタの状態を獲得

元Object名称type内容
ApplicationgetScreenCount()functionPCに接続されているモニタの数を獲得
ApplicationgetMainScreenWidth()functionプライマリーモニタの横ピクセルを獲得
ApplicationgetMainScreenHeight()functionプライマリーモニタの縦ピクセルを獲得
ApplicationgetMainScreenSize()functionプライマリーモニタのサイズを配列で獲得
ApplicationgetSubScreenWidth()functionセカンダリーモニタの横ピクセルを獲得
ApplicationgetSubScreenHeight()functionセカンダリーモニタの縦ピクセルを獲得
ApplicationgetSubScreenSize()functionセカンダリーモニタのサイズを配列で獲得

◎CompItemの拡張

元Object名称type内容
CompItemgetFrame()functionコンポの長さをフレーム数で獲得
CompItemsetFrame()functionコンポの長さをフレーム数で設定
CompItem
FootageItem
createComp()functionコンポ・フッテージと同じ大きさ長さのコンポを作成
Application
CompItem
compSizeDialog()functionコンポの大きさを入力するダイアログの表示。

◎AVLayerの拡張

元Object名称type内容
AVLayercutAtTime(time)functionレイヤの分割
AVLayerremapIsOnekey()functionレイヤのタイムリマップを0で静止画状態に
AVLayergetPos()functionPositionプロパティの獲得
AVLayergetAnc()functionAnchor Pointプロパティの獲得
AVLayergetScale()functionScaleプロパティの獲得
AVLayergetRot()functionRotateプロパティの獲得
AVLayergetRotX()functionRotate Xプロパティの獲得
AVLayergetRotY()functionRotate Yプロパティの獲得
AVLayergetRotZ()functionRotate Zプロパティの獲得
AVLayergetOpacity()functionOpacityプロパティの獲得

◎Projectの拡張

元Object名称type内容
FolderItem
Project
folder(name)functionフォルダを作成。指定した同じ名前のフォルダがあったらそれを返す。

◎選択の処理

元Object名称type内容
CompItemselectionPush()functionレイヤの選択状態を記憶
CompItemselectionPop()functionレイヤの選択状態を復帰
CompItemselectionNone()functionレイヤの選択を全て解除
ProjectselectionPush()functionアイテムの選択状態を記憶
ProjectselectionPop()functionアイテムの選択状態を復帰
ProjectselectionNone()functionアイテムの選択を全て解除

◎アイテムの探索

元Object名称type内容
ProjectfindItemByName(name)functionプロジェクト内のアイテムを名前で探す。結果は配列で返る。
FolderItemfindItemByName(name)functionフォルダ内のアイテムを名前で探す。結果は配列で返る。
ObjectisAEItems()functionObjectがAfter Effectsのアイテムかどうか
ArraygetComp()function配列内からCompItemを抽出
ArraygetFootage()function配列内からFootageItemを抽出
ArraygetSolid()function配列内から平面フッテージを抽出

◎FootageItemの拡張

元Object名称type内容
FootageItemuseReplace(item)function使用されているフッテージを使用しているレイヤ全てを指定したフッテージに置き換え
引数はAVLayer replaceSource() methodと同じ

◎アクティブアイテムの獲得

元Object名称type内容
ProjectgetActiveComp()function現在アクティブなコンポを返す
ProjectgetActiveFootage()function現在アクティブなフッテージを返す
ProjectgetSelectedComp()function選択されているコンポを配列で返す。
ProjectgetSelectedFolder()function選択されているフォルダアイテムを配列で返す。
ProjectgetSelectedFootage()function選択されているフォルダを配列で返す。
ProjectselectedProperties()function現在選択されているプロパティを配列で返す。
ProjectselectedLayers()function現在選択されているレイヤを配列で返す。
Project
FolderItem
getComp()functionフォルダーアイテム内のCompItemを獲得
Project
FolderItem
getFootage()functionフォルダーアイテム内のFootageItemを獲得
Project
FolderItem
getFolderItem()functionフォルダーアイテム内のFolderItemを獲得
Project
FolderItem
getSolid()functionフォルダーアイテム内の平面フッテージを獲得

◎Propertyの拡張

元Object名称type内容
PropertyisKeyAtTime(time)function指定された時間にキーフレームがあったらtrue
PropertykeyClear()functionキーフレームを全て削除
PropertykeyFreeze()functionキーフレームを最初の1個のみにする
PropertygetParentLayer()functionこのプロパティのあるLayer objectを返す
PropertykeySelectedAll()function全てのキーフレームを選択。引数にfalseを入れると全ての選択を解除

◎Window objectの拡張

元Object名称type内容
WindowrightTop()functionウィンドウの表示位置を右上に設定

◎デバッグ用の出力コンソール

元Object名称type内容
ApplicationshowDebugConsole()functionデバッグコンソールの表示
ApplicationdbPut(str)functionデバッグコンソールに文字表示
ApplicationdbInsert(str)functionデバッグコンソールの先頭に文字列追加
ApplicationdbWrite(str)functionデバッグコンソールに文字列追加
ApplicationdbWriteLn(str)functionデバッグコンソールに文字列追加。改行付き
ApplicationdbClear()functionデバッグコンソールのクリア
ApplicationdbClose()functionデバッグコンソールの消去


最後に

今回は「1行スクリプト」ってネタでJavaScriptのTips集的な記事にしようと思ってましたが、実際に書いてみると200文字超えがほとんどでで1行って言うのにはちょっと長すぎました。反省。
ですが今回は自作のライブラリをprototypeに直したものになりますが、ネタのつもりがかなり実用的なものになってます。

今回のスクリプトをもっと洗練させれば、JavaScriptで有名なライブラリのprototype.jsのAfterEffects版が作れそうな予感がします。

最後に今回のスクリプトの著作権は僕にありますが、個人・商業での使用はフリーです。



タグ : , , [タグを追加する]


この記事の投稿者について:bryful

フィードバック

1 Star2 Stars3 Stars4 Stars5 Stars
(評価回数:3 , 平均:5.00)
Loading...Loading...

この記事に対する 20 の反応があります


  1. 1 AEUSERS(AEP Project) 10月 28th, 2011 at 14:45

    新着記事 : After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/h8INUy8l

  2. 2 ponytailers 10月 28th, 2011 at 14:45

    新着記事 : After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/h8INUy8l

  3. 3 古橋宏 10月 28th, 2011 at 14:46

    AEPProjectに prototypeUno.jsx 1行スクリプト集の記事を投稿しました。http://t.co/Bzj4NhG7

  4. 4 藤田 枝里 10月 28th, 2011 at 14:50

    新着記事 : After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/h8INUy8l

  5. 5 rlldi 10月 28th, 2011 at 14:50

    新着記事 : After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/h8INUy8l

  6. 6 refinity. 10月 28th, 2011 at 14:54

    これ入門っつーか中級なかんじがするんですが・・・・w情報処理を事前にまなんでいるなら、入門だろうね・・・・・http://t.co/dt0kfN1d

  7. 7 Tanabe Fujio 10月 28th, 2011 at 15:00

    新着記事 : After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/h8INUy8l

  8. 8 たこ 11月 2nd, 2011 at 03:53

    スーパーbryfulライブラリすっげぇ(;´Д`)bryfulさんの投稿でprototypeの意味がモワッとわかったような・・・数行コード書けるかも・・・ http://t.co/tqiRHbNd

  9. 9 30mile 11月 7th, 2011 at 11:37

    After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 http://t.co/X5wJLhDY

  10. 10 小池屋カアラ 11月 24th, 2011 at 04:42

    後で読みます After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集 | AEP Project: http://t.co/ScR4x1Se

  11. 11 Adobe Creative Suite 11月 28th, 2011 at 09:01

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  12. 12 Adobe Creative Suite 11月 28th, 2011 at 09:14

    スクリプトは経験があるけれど他の言語はさわったことがないユーザーを対象に、C#/AEのJavaScriptをメインにプログラム全般を解説する連載の第11回です。今回のテーマは「1行スクリプト」です。http://t.co/U8iKRs9w

  13. 13 古籏一浩 11月 28th, 2011 at 09:15

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  14. 14 cep 11月 28th, 2011 at 09:16

    スクリプトは経験があるけれど他の言語はさわったことがないユーザーを対象に、C#/AEのJavaScriptをメインにプログラム全般を解説する連載の第11回です。今回のテーマは「1行スクリプト」です。http://t.co/U8iKRs9w

  15. 15 犯田コウヘイ 11月 28th, 2011 at 09:44

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  16. 16 ayaka kurita 11月 28th, 2011 at 10:26

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  17. 17 o range 11月 28th, 2011 at 13:52

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  18. 18 藤澤浩 11月 28th, 2011 at 14:34

    「After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ 1行スクリプト集」AEP Project http://t.co/U8iKRs9w #CS5_jp

  1. 1 AfterEffectsユーザーのための、プログラミング入門 その11 prototypeライブラリ1行スクリプト集 | スクリプト - After Effects - 動画編集ソフト - アプリケーション | Jishuu.net Pingback on 4月 10th, 2012 at 04:34
  2. 2 After Effectsユーザーのための、プログラミング入門 その11 prototypeライブラリ1行スクリプト集 | スクリプト - After Effects - 動画編集ソフト - アプリケーション | Jishuu.net Pingback on 10月 3rd, 2012 at 21:10

コメントをどうぞ!




特集