DTPab

印刷やデザイン、アドビ製アプリやスクリプトなど、雑多な技術ブログ

Illustratorのスクリプト勉強中③

前回までのあらすじ

紆余曲折を経て、選択しているオブジェクトをなんとか整列させるところまでできました。オブジェクトの移動だけならObject.positionプロパティに配列を渡すだけでいいんですね。
また、geometricBounds、controlBounds、visibleBoundsの違いについても調べました。

前回のコード

var myDoc = app.activeDocument;
var mySels = myDoc.selection;

var targetY = mySels[0].visibleBounds[1]; //0番目のオブジェクトの天のY座標

for (var i=1; i<mySels.length; i++){
    mySels[i].position = [mySels[i].visibleBounds[0], targetY];
}

このコードに肉付けしていきます。

今日の目標

選択したオブジェクトを同じ高さにリサイズしたいと思います。
前回、リファレンスでPageItem.resizeというメソッドを見つけているので、それを使おうと考えています。

0番目のオブジェクトの高さに揃えてリサイズする

オブジェクトの高さを調べる

0番目のオブジェクトmySels[0]の高さを調べます。IllustratorのxxxBoundsで取得できる座標値(4要素の配列)は、画像のような順番で値が格納されています*1

f:id:uske_S:20180510144312p:plain

なので、知りたい「オブジェクトの高さ」は、以下のように書くことで求められます。ちなみに、前回つまづいた(?)とおり、得られる値はpointです。

var myDoc = app.activeDocument;
var mySels = myDoc.selection; //ここまでは前回と同じ

var tgHeight = mySels[0].visibleBounds[3] - mySels[0].visibleBounds[1];

このスクリプトを実行してみます。

f:id:uske_S:20180510144327p:plain

値は合っているのですが、正負が逆転していますね…。下手に正負の調整するより、絶対値に変換しちゃったほうがいいかな?
ということでMath.absメソッドで値を絶対値にしてみます。

var myDoc = app.activeDocument;
var mySels = myDoc.selection; //ここまでは前回と同じ

var tgHeight = Math.abs(mySels[0].visibleBounds[3] - mySels[0].visibleBounds[1]);

実行結果はこちら。

f:id:uske_S:20180510144343p:plain

これで正負を気にせず「長さとしての値」を取得できました。

PageItem.resizeメソッドを使う

前回痛い目を見たので、オブジェクトモデルビューワから引数を確認してみます。

f:id:uske_S:20180510144355p:plain

わー、なんかめっちゃ引数ある! ただ(optional)という引数は省略できるので、2つの引数を渡せば最低限動作するようです。読んだ感じでは、scaleXとscaleYを百分率で渡せばいいようですね。まずは適当に30%くらいに縮小してみますか。

var myDoc = app.activeDocument;
var mySels = myDoc.selection; //ここまでは前回と同じ

mySels[0].resize(30,30);

f:id:uske_S:20180510144408g:plain

おお、なった、なった。オブジェクトの中心基準でリサイズされるということは覚えておこう。

オブジェクトの高さを揃える

ということは、基準とするオブジェクトの高さと、変倍するオブジェクトの高さの比を百分率で計算できればresizeできるということになりますね。
というわけでざっくり書いてこんな感じにしました。

var myDoc = app.activeDocument;
var mySels = myDoc.selection; //ここまでは前回と同じ

//0番目のオブジェクトの天のY座標
var targetY = mySels[0].visibleBounds[1];
//基準とするオブジェクトの高さ
var tgHeight = Math.abs(mySels[0].visibleBounds[3] - mySels[0].visibleBounds[1]);

for (var i=1; i<mySels.length; i++){
    //変倍するオブジェクトの高さ
    var h = Math.abs(mySels[i].visibleBounds[3] - mySels[i].visibleBounds[1]);
    //比率計算(百分率)
    var p = (tgHeight / h) * 100;
    //リサイズ
    mySels[i].resize(p, p);
    //基準とするオブジェクトの天にあわせて整列
    mySels[i].position = [mySels[i].visibleBounds[0], targetY];
}

ん〜、高さを求める計算は関数にまとめてしまったほうがスマートですかね。

今日のコード

var myDoc = app.activeDocument;
var mySels = myDoc.selection; //ここまでは前回と同じ

//0番目のオブジェクトの天のY座標
var targetY = mySels[0].visibleBounds[1];
//オブジェクトの高さを求める関数
var getHeight = function (obj){
    return Math.abs(obj.visibleBounds[3] - obj.visibleBounds[1]);
}
//基準とするオブジェクトの高さ
var tgHeight = getHeight(mySels[0]);

for (var i=1; i<mySels.length; i++){
    //変倍するオブジェクトの高さ
    var h = getHeight(mySels[i]);
    //比率計算(百分率)
    var p = (tgHeight / h) * 100;
    //リサイズ
    mySels[i].resize(p, p);
    //基準とするオブジェクトの天にあわせて整列
    mySels[i].position = [mySels[i].visibleBounds[0], targetY];
}

f:id:uske_S:20180510144439g:plain

という形になりました。今日はすんなりでしたね。

続きます!

*1:ところがどっこい、InDesignと格納されている順序が違う! 紛らわしい! InDesignでは[0]が左上のY座標、[1]が左上のX座標、[2]が右下のY座標、[3]が右下のX座標。InDesignスクリプトに慣れていると非常に混乱します。