面倒なときに四角形に戻してしまうスクリプト(Ai)
えーと、相方さんが勢い良すぎて埋もれてしまいそうなので危機感を感じていますが、9月からこちら連日残業という感じでほとんど休めていないかんじのTenです。
まだまだ此処も工事が続いていて何やってんだろう……と思われる方も多いかと存じますが、生暖かく見守っていただけたらと思う次第です。
さて、先日CEPコマンドリファレンスをリリースしましたが、あちらの電書は制作に3年以上費やしている代物です。特にVulcanInterfaceの解説は殆ど書かれていないものですので色々とぶっ飛んだ処理を作る際には必須だと思いますのでうまくご利用いただけたらと思います。
さて、今回のスクリプトは角丸に展開された四角形とか一部引っ張っちゃって四角形じゃなくなったパスアイテムを強制的に四角形に戻してしまうやつです。
選択したオブジェクトをダイレクトに操作しますので重なり順とかのドキュメント構成を棄損しない仕様になっています。
では、全体像から……
(function(){
var tg = app.selection[0];
var bd = tg.geometricBounds;
if (tg.pathPoints.length<4) while (tg.pathPoints.length<4) tg.pathPoints.add();
tg.pathPoints[0].anchor = [bd[0], bd[1]];
removeHandle(tg.pathPoints[0]);
tg.pathPoints[1].anchor = [bd[2], bd[1]];
removeHandle(tg.pathPoints[1]);
tg.pathPoints[2].anchor = [bd[2], bd[3]];
removeHandle(tg.pathPoints[2]);
tg.pathPoints[3].anchor = [bd[0], bd[3]];
removeHandle(tg.pathPoints[3]);
while(tg.pathPoints.length>4) tg.pathPoints[tg.pathPoints.length-1].remove();
if (!tg.closed) tg.closed = true;
function removeHandle(pt){
pt.leftDirection = pt.anchor;
pt.rightDirection = pt.anchor;
}
}
)();
構成としては即時実行関数として作られています。内部にひとつremoveHandleという関数を持ちますが、これは与えられたpathPointのディレクション(ハンドル)をpathPointのanchorにそろえるためのものです。手作業でやる場合左右のハンドルを縮めてアンカーポイントにくっつけてしまう処理が該当します。
頭にもどってコードを読み解いていきます。
var tg = app.selection[0];
まず変数tgに現在の選択範囲の最初の物を取り込みます。いくつ選択していても処理対象は最前面にあるものです。
var bd = tg.geometricBounds;
続いて、そのオブジェクトのgeometricBoundを得ます。角丸長方形のようなものならその外形とジオメトリ範囲は一致しますが、このスクリプトはその他の形状、例えば三角形であってもそのジオメトリ範囲を取得し強制的に四角形に変換します。
ちなみに、変換時にオフセットなどの機能が欲しい場合、このgeometricBoundsを基にして計算してしまえばOKです。
if (tg.pathPoints.length<4) while (tg.pathPoints.length<4) tg.pathPoints.add();
四角形に変換しますからアンカーポイントの数は4個になります。三角形や直線等でアンカーポイントの数が足りない場合は数を合わせてあげる必要があります。それを続くif節で引っ掛けてwhile文で4個になるようにループ処理します。
tg.pathPoints[0].anchor = [bd[0], bd[1]];
removeHandle(tg.pathPoints[0]);
tg.pathPoints[1].anchor = [bd[2], bd[1]];
removeHandle(tg.pathPoints[1]);
tg.pathPoints[2].anchor = [bd[2], bd[3]];
removeHandle(tg.pathPoints[2]);
tg.pathPoints[3].anchor = [bd[0], bd[3]];
removeHandle(tg.pathPoints[3]);
さて、続くpathPoints操作はストレートにanchorの数値を左上・右上・右下・左下と時計回りで設定しています。4個と決まっていますからループ処理をやれなくもないのですが、やっちゃうと何をどう処理しているのかがぼやけてしまいます。ですから今回は位置をセットしてremoveHandle呼び出しを連続で並べています。こういう冗長な構成の方がコードの見通し自体は良い場合も多々ありますので気を付けたいところです。
while(tg.pathPoints.length>4) tg.pathPoints[tg.pathPoints.length-1].remove();
その後、アンカーポイント数が余った場合は、それを削除します。
if (!tg.closed) tg.closed = true;
最後にclosedプロパティをtrueとしていますが、このスクリプトは直線も四角形にしてしまいますからオープンパスのままになってしまう可能性がありますので、ここで明示的に閉じてしまいます。
とても短いスクリプトですから、初心者の方でも一行ずつ読み解いていただければ理解できるかと思います。