ExtendScript/Javascript
AEに関しないもの配列作成とアクセスを同時に行う
["indd", "pdf", "idml", "txt"][i]
atanとatan2の違い
返ってくる範囲が違う
atan-> -π/2<x<π/2
atan2-> -π<x<π
new Date と Dateの違い
new で宣言したときのみDateオブジェクトになる。つけないと文字列。
Folder.removeで消せない?
Folder.remove()はフォルダ内が空っぽじゃないとfalseになる。先に中のファイルを全部消してから実行。
無名関数
(function(a,b){return a+b;})(2,3)
メリット
一度しか使わない関数の名前を付けなくて済む。名前の衝突を考えなくて済む。
関数の引数などに直接渡せる。
正規表現いろいろ
EditTextやpromptに入力した値が正当かチェックする時に使ったりする。一度知ると楽しい正規表現。
■秒+コマ
/^(?:(\d+(?=\+))\+)?(\d+)$/
マッチオブジェクトmの
m[1]=秒数
m[2]=コマ数
(?=\+)が抜けていると総コマ入力だったときにm[1]もm[2]もコマ数を拾っちゃうよ。
■フレームレート
parseFloatでええけど正規表現にするなら
/^\d+(?:\.\d+)?$/
■拡張子
/\.\w+?$/
\wを使わずに.(ピリオド)にして「/\..+?$/」にするとフルパス名にピリオドが含まれる場合、そこから拾っちゃうので注意。ちょっとハマった。
配列の中抜きはsplice
配列にある値が入ってるか調べるのは、Array.indexOf しかしCS6(CCは知らん)には実装されていないので、prototypeつくるしかない。完璧に同じアルゴリズムが公式?公開されているのでそれをつかえば使える。prototypeはfor eachしちゃったときに出てきてしまう。これを想定していない昔のスクリプトがエラーになる可能性があるのであんま使いたくない。
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
}
else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
for each inはつかわない
for in
ファイル数を調べる
Folder.getFiles()でいいんだけれども、ファイル・フォルダ数が多いと遅すぎる。その時はcallSystem使ってcmd.exe経由で調べたほうが早い。少ないときはgetFilesのほうが早い。
getFiles()は引数の関数始める前に一回全ファイルを取得してからフィルタリングしてるっぽい?フィルタリング関数の実行前に結構時間が空く。ファイル数が多いとそこに時間がかかってる。各ファイルに対してのフィルタリング処理に関しては高速。
getFiles()は隠しファイルも拾うからファイルのhiddenを調べて拾わないとダメね。
dir のオプション(一部)
/a 属性の指定
d : ディレクトリ
h : 隠しファイル
- : 以外
/b ファイル名のみ
(function(){
var f = Folder(path)
//cmd.exeで拾うタイプ
$.hiresTimer
var a = system.callSystem('cmd.exe /c "cd /d '+f.fsName.replace(/\\/,"\\\\")+' && dir /a-d-h /b "');
//$.writeln(a);
var len = a.match(/\n/g).length;
$.writeln("callSystem : ("+len+")"+$.hiresTimer/1000+"msec");
//getFiles()で拾うタイプ
$.hiresTimer
var len = f.getFiles(function(a){
return a instanceof Folder || (a instanceof File && !a.hidden)
}).length;
$.writeln("getFiles : ("+len+")"+$.hiresTimer/1000+"msec");
})();
$.evalFileで実行した時の$.fileName
$.evalFile( "ファイルパス" )
を使うと、あるスクリプトから、別のスクリプトファイルを実行することができる。
例えば、今までに細々したスクリプトをたくさん作っていたがスクリプト作成のスキルが上がってきた頃、それらバラバラのファイルを毎回指定して実行するのではなく、それらを統括するスクリプトを作成してボタンクリックで呼び出せるようにしたい、といったような時。
または、細々した各スクリプトはAEのショートカットキーを充ててそれ単体でスピーディーに呼び出せるようにする一方で、別のスクリプトの中でも何かしらの処理をしている流れの中でその機能を使用したい。またはボタンクリックからも呼び出すこともできるようにしたい、という時。
今まで作ったスクリプトを新しいスクリプトの中にコピペして1ファイルとしてまとめてもいいのだが、元のスクリプトを修正した時に同じ修正を複数のファイルに対して行わないといけないのはめんどくさい。普通しない。
そこで$.evalFileを使用すると便利なのだが、統括スクリプトのフォルダ内にファイル自体をコピーしてしまうと、結局修正の手間としては同じになってしまう。ショートカットを使うと原本は一つにできるので、そこだけを修正すれば、それを参照している全てのスクリプトでも同様の修正が反映される。
しかし、元のスクリプトの中で$.fileNameを使用している時、少々戸惑うことがある。
$.evalFileに対してショートカットのファイルを与えた場合、きちんとショートカット先の元のスクリプトの実行はされるが、そのスクリプト内での$.fileNameの返り値が、ショートカットのファイル名になる。
本来、元のスクリプトの中ではそのファイルパスが返ってくる体で記述していると思う。だが、ショートカットから呼び出した時、その値がショートカットファイル自体のファイルパスが入ってしまうので、そうなると想定した挙動にならないことになる。
これを解決するには
File.resolve()
を使用する。
これはショートカットファイルのファイルオブジェクトの参照しているファイル本体のファイルオブジェクトを返してくれる。
大本のファイルオブジェクトを取得してこれを$.evalFile()に渡すことで、そのスクリプト内の$.fileNameの戻り値が本来想定していたファイルパスになり、想定通りの挙動をするようになる。
存在しないドライブ内のフォルダを作成した場合
FolderObj.create()
でフォルダを作成できる。フォルダ作成に成功したかどうかがTRUE/FALSEで返ってくる。
ここで、存在しないドライブ内のフォルダを指定した場合どうなるか。
やってみると、エラーにもならない。戻り地はtrue。作成成功したということ。
勝手にドライブ作成されてる?さすがにそんなことは無い。
実際はCドライブ直下に、ドライブ文字のフォルダが作成される。
例えば、Zドライブの登録は無い状態で、
/z/aaaaa/bbbbb/ccccc
というフォルダで作成した場合、
/c/z/aaaaa/bbbbb/ccccc
が作成される。