<?xml version="1.0" encoding="UTF-8" ?>
<feed xml:lang="ja" xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0">
  <title type="text">ぼんぷろぐ</title>
  <subtitle type="html">InDesignとかイラレとかのスクリプトよもやま話</subtitle>
  <link rel="self" type="application/atom+xml" href="http://sysys.blog.shinobi.jp/atom"/>
  <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/"/>
  <updated>2014-04-17T00:57:11+09:00</updated>
  <author><name>kawamoto_α</name></author>
  <generator uri="//www.ninja.co.jp/blog/" version="0.9">忍者ブログ</generator>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" />
  <entry>
    <id>sysys.blog.shinobi.jp://entry/133</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/133/" />
    <published>2021-02-17T18:21:08+09:00</published> 
    <updated>2021-02-17T18:21:08+09:00</updated> 
    <category term="Photoshop" label="Photoshop" />
    <title>Sppyのフォトショ版（ベータ）</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<p>ご要望があったので、Sppyのフォトショ版を作ってみました。</p>
<br />

<p>Sppyは、ExtendScriptで書かれたスクリプト（.jsx）をすばやく実行するためのツールです。AutoHotkeyで開発しています。イラレ版は<a href="https://sysys.zouri.jp/sppy/" title="">こちら</a>。</p>
<br />

<p>しかし私自身はフォトショでスクリプトはほぼ使っておらず、皆さんがどんなスクリプトをどんなふうに使ってるのか、全く知りません。<br />
ただ、イラレ版Sppyのソースコード内の'illustrator'を'photoshop'に変えるだけでできそうなので、せっかくだからやってみた、というものです。<br />
そういうわけなので、これはベータ版（テスト版）ですが、何事もなければこのまま開発終了となります。</p>
<br />

<h3>ダウンロード</h3>
<br />
[<a href="//sysys.blog.shinobi.jp/File/SppyPs.zip" title="">Sppy for Photoshop ver0.1</a>]<br />
<br />
<hr /><br />

<h3>Sppyの使い方</h3>
<ol>
<li>SppyPs.exeを実行します。初回起動時にはフォルダ選択ダイアログが出るので、スクリプトが入ったフォルダを選択します。</li>
<li>Sppyはタスクトレイに常駐します。タスクトレイアイコン<img src="//sysys.blog.shinobi.jp/File/sppypsicon.png" alt="" /> をダブルクリックするとパネルが開きます。</li>
<li>パネルにはフォルダ内のスクリプト（*.jsx , *.js）がツリー表示されます。ダブルクリックでスクリプトが実行できます。</li>
<li>終了するには、タスクトレイアイコンを右クリックして『終了』を選択します。</li>
</ol><hr />
<h3 id="キーボードショートカットの設定">キーボードショートカットの設定</h3>
<p>キーボードショートカットの設定は２つの方法があります。</p>
<h4>方法１：</h4>
<ol class="example">
<li>スクリプトを選択して、『キー取得』ボタンを押します。</li>
<li>キー入力欄にカーソルを置いてキーを入力します。このとき、Ctrl、Shift、Altキーを組み合わせることができます。</li>
<li>『その他の修飾キー』として、無変換キー、Winキーを設定することできます。たとえばキー入力欄に『A』、その他の修飾キーに『無変換』を選ぶと、『無変換 + A』のキーボードショートカットが実現できます。<br />
※無変換キーはCtrl、Shift、Altと組み合わせることができません。Winキーはできます。<br />
※無変換キーを使う場合、IMEで無変換キーに割り当てられた機能があれば事前にオフにしておきましょう。</li>
<li>キー設定ダイアログでOKを押すと<b>キー取得ボタンの右に変な文字列</b>が表示されますが、気にせず『適用』を押します。</li>
<li>対象のスクリプトが<strong>太字になったら設定完了</strong>です。Photoshop上でキーを入力してみましょう。</li>
</ol>
<h4>方法２：</h4>
<p>先ほどの『キー取得ボタンの右の変な文字列』は、AutoHotkeyスクリプトにおいてキーを指定するための文字列です。<br />
ここでは、<br />
Ctrlが『^』<br />
Shiftが『+』<br />
Altが『!』<br />
無変換が『vk1D』<br />
などと表記されます。</p>
<p>ここに直接キー文字列を入力して、『適用』を押してやるというのが２つ目の方法になります。<br />
先ほどのキー取得ダイアログでは使えなかったキー（Esc、Tabなど）のほか、マウスの拡張ボタン、ジョイスティックなども登録できるはず。</p>
キーの書き方はこちらを参照ください。<br />
<a href="http://ahkwiki.net/Hotkeys">ホットキー - AutoHotkey Wiki</a><br />
<a href="http://ahkwiki.net/KeyList">キーリスト - AutoHotkey Wiki</a><br />
<br />
<hr />
<h3>謝辞</h3>
フォトショのProgIDを教えてくれた<a href="https://twitter.com/CS5_omachi" title="">お～まちさん</a>、ありがとうございました。]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/132</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/132/" />
    <published>2021-01-12T00:26:26+09:00</published> 
    <updated>2021-01-12T00:26:26+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>上端からの距離に比例した移動量で下に動かすスクリプト</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[ご要望があったので、<a href="https://sysys.blog.shinobi.jp/Entry/96/" title="">左端からの距離に比例した移動量で右に動かすスクリプト</a>の「上から下」版を作りました。実は「左から右」版作ったときにこっちもほぼ完成してたんですが。<br />
<br />
使い方は「左から右」版の方を見てくださーい<br />
<br />

<h3>ダウンロード</h3>
<br />
［<a href="//sysys.blog.shinobi.jp/File/0ddb9db5.zip" title="">ver1.0 - 2021/01/12</a>］<br />
<br />

<h3>動いてるところ</h3>
<blockquote class="twitter-tweet">
<p dir="ltr" lang="ja">ブログ更新しました / ［イラレ］上端からの距離に比例した移動量で下に動かすスクリプト: <a href="https://t.co/07dWJGXDaH">https://t.co/07dWJGXDaH</a> <a href="https://t.co/YrlnmV1uOM">pic.twitter.com/YrlnmV1uOM</a></p>
&mdash; あるふぁ（仮） (@peprintenpa) <a href="https://twitter.com/peprintenpa/status/1348653306378293253?ref_src=twsrc%5Etfw">January 11, 2021</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8" type="text/javascript"></script>]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/131</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/131/" />
    <published>2021-01-06T19:18:57+09:00</published> 
    <updated>2021-01-06T19:18:57+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>「Bridgeで参照」を使い物にする　イラレ編</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[ファイルメニューの「Bridgeで参照」、Bridgeが起動するだけで何も参照してくれないんだけど、せめて今開いてるドキュメントくらい参照してくれるようにならんかなー<br />
<br />
っていう思いで前回、<a href="https://sysys.blog.shinobi.jp/Entry/130/" title="">InDesignの「Bridgeで参照」を改造する話</a>をやったんですが、今回はそのイラレ編です。<br />
<br />
しかしメニューコマンドの処理をスクリプトで書き換えるなんて大それたことをさせてくれるのはInDesignくらいのもので、イラレやフォトショのスクリプトではそこまでの自由度はありません。どうしよう。<br />
<br />
<hr /><br />
ExtendScriptにはBridgeTalkという、Adobeアプリ間でスクリプトを送り合えるしくみがあるんですが、イラレのファイルメニューの『Bridgeで参照』にはBridgeTalkが使われています。<br />
<br />
具体的には、『Bridgeで参照』を実行すると、次のコードがBridgeにBridgeTalkを介して送られています。<br />
<br />

<pre><code>app.bringToFront();
if (app.documents.length == 0) app.browseTo();
else app.document.thumbnail = new Thumbnail();</code></pre>
<br />
これを<strong>コードＡ</strong>と呼ぶことにしましょう。<br />
<br />
ちなみにこのコード、ESTKからBridgeを対象に実行すると、なんとエラーが出ます。<br />
3行目の new Thumbnail() が引数なしを許容してないんですね。<br />
BridgeTalkから実行した場合もエラーになるんですが、「BridgeTalk内のエラーはアラートも何も表示されず、ただそこでスクリプトの実行が終わるだけ」という仕様と、１行目の app.bringToFront(); だけでBridgeを最前面に表示するという仕事が完了していることにより、これまで誰にもばれずにエラーを出し続けてきたんだと思われます。<br />
<br />
それはともかくとして、『Bridgeで参照』を実行したときの通常の処理はこんなんです。<br />
<br />
イラレで『Bridgeで参照』を実行<br />
&darr;<br />
BridgeTalkでコードＡがイラレからBridgeに送信される<br />
&darr;<br />
Bridge上のBridgeTalk.onReceive関数がコードＡを受け取る<br />
&darr;<br />
onReceive関数内でコードＡがevalされる<br />
&darr;<br />
app.bringToFront();が実行された後、エラーが出て終わり<br />
<br />
重要なのは、BridgeTalkで送られたコードというのは無条件で実行されるわけではなくて、BridgeTalk.onReceiveによって処理されるという点です。<br />
んでBridgeTalk.onReceiveってどんな関数なのって言うと、ESTKからBridgeを対象に BridgeTalk.onReceive.toSource() してみると分かるんですが、次のようなコードです。<br />
<br />

<pre><code>(function( msg ) {
 	app.lastSender = msg.sender;
 	app.displayDialogs = 'all';
 	var retval = eval( '$.level = 0; app.synchronousMode = false;\n' + msg.body );
 	app.displayDialogs = 'all';
 	app.synchronousMode = false;
 	return retval;
})</code></pre>
<br />
送られてきたコードを実行しているのは4行目のevalです。msg.bodyにコードが入っています。<br />
<br />
他の行も見てみると、2行目はBridgeTalkを送りつけてきたアプリの名前をapp.lastSenderに代入しています。これによりファイルメニューの「〇〇に戻る」の〇〇がそのアプリになります。<br />
イラレから「Bridgeで参照」した直後は「Illustratorに戻る」、フォトショから「Bridgeで参照」した直後は「PhotoShopに戻る」に変化するのはこういう仕組みだったんですね。<br />
<br />
<br />
でー、このBridgeTalk.onReceiveなんですが、実は書き換え可です。<br />
たとえば、送られてきたコードがコードＡに完全に一致する場合のみ特別な処理を行い、それ以外の場合はデフォルトのBridgeTalk.onReceiveと同じ処理をする、ということもできちゃうわけです。<br />
ここまでの説明は、「BridgeのBridgeTalk.onReceiveを書き換えることで、イラレの『Bridgeで参照』の挙動を変えてやろう」という企みを分かっていただくためのものだったのでした。<br />
<br />
<hr /><br />
<br />
てことで、イラレの「Bridgeで参照」を、現在のドキュメントを参照するようにするBridge用スタートアップスクリプトです。<br />
<br />

<pre><code>//    イラレの「Bridgeで参照」を、現在のドキュメントを参照するようにするBridge用スタートアップスクリプト
var aiBridgeDeSansho1="app.bringToFront();if%20(app.documents.length%20==%200)%20%20%20%20app.browseTo();else%20%20%20%20app.document.thumbnail%20=%20new%20Thumbnail();";
var aiBridgeDeSansho2="app.document.thumbnail%20=%20new%20Thumbnail();";//Bridgeが起動してないときはこっちになるっぽい

var btOnReceive2=(function(msg) {
    var body2=encodeURI(msg.body);
    if(msg.sender.slice(0,11)=="illustrator" &amp;&amp; (body2==aiBridgeDeSansho1 || body2==aiBridgeDeSansho2)){
        app.bringToFront();
        app.lastSender = msg.sender;
        var bt=new BridgeTalk;
        bt.target=msg.sender;
        bt.body="app.documents.length==0?0:app.activeDocument.fullName";
        bt.onResult=function(res){
            if(res.body=="" || res.body=="0")return;
            app.document.thumbnail=new Thumbnail(File(res.body));
        }
        bt.send();
        return;
    }
    app.lastSender = msg.sender;
    app.displayDialogs = 'all';
    var retval = eval('$.level = 0; app.synchronousMode = false;\n' + msg.body);
    app.displayDialogs = 'all';
    app.synchronousMode = false;
    return retval;
});

BridgeTalk.onReceive=btOnReceive2;
BridgeTalk.watch("onReceive",function(){return btOnReceive2});//スタートアップスクリプトの後にonReceiveが初期化されるのを防ぐ</code></pre>
<h3>インストール方法</h3>
①Bridgeを開いて、環境設定からスタートアップスクリプトの『マイスタートアップスクリプトを表示』をクリック<br />
②Startup Scriptsフォルダが開くので、ここに上記スクリプトを拡張子.jsxで保存したものを置きます<br />
③Bridgeを再起動すると「新しい機能を有効にしますか？」みたいなダイアログが出るのでOKを押します<br />
<br />
これでイラレから「Bridgeで参照」したとき、現在の（最前面の）ドキュメントがBridge上で選択されるようになってるはずです。（ダメだったら教えてください）<br />
<br />
<hr />
<h3>関連記事</h3>
イラレ＆Bridgeの昔書いたネタ（超便利だと思うんだけど特に褒められなった&hellip;）<br />
<a href="http://sysys.blog.shinobi.jp/Entry/81/" title="">イラレの画像再リンクをBridgeから行うためのスクリプトをつくったー</a>]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/130</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/130/" />
    <published>2020-12-24T23:45:33+09:00</published> 
    <updated>2020-12-24T23:45:33+09:00</updated> 
    <category term="InDesign" label="InDesign" />
    <title>「Bridgeで参照」を使い物にする　InDesign編</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<blockquote class="twitter-tweet">
<p dir="ltr" lang="ja">本日は、事前登録時にいただいたコメントから【InDesignのスキな機能】をご紹介します。<br />
<br />
「正規表現がばっちり決まった時が快感です」<br />
「ルビが楽！」<br />
「スクリプトで、いかようにも染められるトコロ」<br />
<br />
InDesignへの愛を感じられるコメント、ありがとうございます！<a href="https://twitter.com/hashtag/InDesign20%E5%91%A8%E5%B9%B4?src=hash&amp;ref_src=twsrc%5Etfw">#InDesign20周年</a></p>
&mdash; InDesign 20周年記念オンラインイベント (@indesign20th) <a href="https://twitter.com/indesign20th/status/1341171518265430016?ref_src=twsrc%5Etfw">December 21, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8" type="text/javascript"></script>
<br />
InDesignが近々20周年を迎えるそうで、おめでとうございます。その記念イベントのアカウントから流れてきたツイートに「スクリプトで、いかようにも染められる」ってなことが書いてあったんですが、これは本当にそうで、InDesignは「ほんとにここまでできちゃっていいの？」って思うようなことまでスクリプトでできてしまいます。<br />
<br />
たとえば、あるメニューコマンドが呼び出されたとき、その実行をキャンセルして別の処理をさせる、なんてこともできます。<br />
<br />
ということで、ファイルメニューの良い位置を占めておきながらほとんど使い道のない『Bridgeで参照』を、現在開いているドキュメントをBridgeで参照する機能に変えるスクリプトです。<br />
<br />

<pre><code>#targetengine session
app.menuActions.item("$ID/FileForBrowse").addEventListener("beforeInvoke", function(ev) {
    ev.preventDefault();
    var d = app.documents[0];
    with(new BridgeTalk) target = "bridge", body = "app.bringToFront();" + (d.isValid &amp;&amp; d.saved &gt; 0 ? "app.document.thumbnail=new Thumbnail(File('" + d.fullName + "'))" : ""), send();
});</code></pre>
<br />
<br />
これはスタートアップスクリプト用のスクリプトです。<br />
所定のフォルダに置いといて起動時に自動実行されるようにするのですが、その所定のフォルダを開く手っ取り早い方法は、InDesignでスクリプトパネルを開いて「ユーザー」フォルダの上で右クリックし、エクスプローラーで開く（MacはFinderで開く？）を選びます。<br />
そこに「Startup Scripts」があればその中、なければ「Scripts Panel」と同じ階層に「Startup Scripts」というフォルダを作成して、上記スクリプトを拡張子jsxで保存したものを入れます。<br />
<br />
あとは普通にInDesignを起動すれば、「Bridgeで参照」が現在のドキュメントを参照するようになってるはずです。<br />
<br />
<hr /><br />
<br />
コードの解説もちょっと<br />
<br />
１行目 #targetengine session<br />
イベントリスナー登録する系のスクリプトは関数が保持されないといけないのでターゲットエンジンの指定が必要です。エンジン名はなんでもいいです。<br />
<br />
２行目 app.menuActions.item("$ID/FileForBrowse")...<br />
"$ID/FileForBrowse"は"Bridgeで参照"のkey stringです。Bridgeって言葉が入ってないのが意外ですけど。<br />
<br />
３行目 ev.preventDefault();<br />
本来のコマンド実行をキャンセルするおまじないです。evはEventオブジェクトです。<br />
<br />
５行目 with(new BridgeTalk)...<br />
BridgeにBridgeTalkを送ってます。<br />
<br />
ｵﾜﾘ]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/129</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/129/" />
    <published>2020-12-03T17:02:39+09:00</published> 
    <updated>2020-12-03T17:02:39+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>Illustrator Script: Move to the right in proportion to the distance from the left end.</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[ご要望があったので、<a href="http://sysys.blog.shinobi.jp/Entry/96/" title="">昔公開したスクリプト</a>を１つ英訳しました。<br />
<br />
<br />
You can run this script when multiple items or one group are selected <span class="VIiyi" lang="en"><span class="JLqJ4b ChMk0b" data-language-for-alternatives="en" data-language-to-translate-into="ja" data-phrase-index="0"><span>in Illustrator CS6 or later</span></span></span>.<br />
<br />
Move the slider to move each selected item to the right by a distance proportional to the distance from the left end of the selected items.<br />
<br />
[<a href="//sysys.blog.shinobi.jp/File/0725c559.zip" title="">Download</a>]<br />

<h3>About dialog</h3>
<img src="//sysys.blog.shinobi.jp/File/a62b3535.png" alt="" /> <br />
<br />
Distance : Moving distance (Original distance from the left end = 100)<br />
Width : Overall width of selected items<br />
Right end : X coordinate of the right end<br />
<br />

<h3>Movie</h3>
<blockquote class="twitter-tweet" data-lang="ja">
<p dir="ltr" lang="ja">左端からの距離に比例した移動量で動かすやつ（イラレスクリプト） <a href="https://t.co/A1l6YRhbV8">pic.twitter.com/A1l6YRhbV8</a></p>
&mdash; あるふぁ（仮） (@peprintenpa) <a href="https://twitter.com/peprintenpa/status/1060590501340971008?ref_src=twsrc%5Etfw">2018年11月8日</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8" type="text/javascript"></script>]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/128</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/128/" />
    <published>2020-10-08T21:17:58+09:00</published> 
    <updated>2020-10-08T21:17:58+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>イラレスクリプトで特定の座標を中心にした回転</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[イラレスクリプトの座標系は、右がx軸の+方向、上がy軸の+方向で、原点はアートボードを特に動かしてなければ１つ目のアートボード左上になります。単位はpt。<br />
<br />
なので座標 (100,100) はこのあたり。<br />
<img src="//sysys.blog.shinobi.jp/File/f3d42761.png" alt="" /> <br />
<br />
で、今回はこの (100,100) を中心に選択アイテムを30&deg;回転するというスクリプトを書いてみようという話です。<br />
<br />
<br />
ページアイテムを回転するメソッドといえば rotate ですが、これは6番目の引数で回転の中心を指定できます。選べるのは以下の10個。<br />
<br />
Transformation.DOCUMENTORIGIN<br />
Transformation.TOPLEFT<br />
Transformation.LEFT<br />
Transformation.BOTTOMLEFT<br />
Transformation.TOP<br />
Transformation.CENTER<br />
Transformation.BOTTOM<br />
Transformation.TOPRIGHT<br />
Transformation.RIGHT<br />
Transformation.BOTTOMRIGHT<br />
<br />
残念ながら中心の座標を数値で指定する選択肢はありません。<br />
しかしDOCUMENTORIGIN、つまり座標でいえば (0,0) なら選ぶことができます。<br />
<br />
そこでこう考えます。<br />
<br />
(-100,-100) ほど移動<br />
&darr;<br />
(0,0) を中心に30&deg;回転<br />
&darr;<br />
(+100,+100) ほど移動<br />
<br />
をすれば、点 (100,100) を中心に30&deg;回転したのと同じじゃん！と。<br />
<br />
移動のメソッドtranslateと回転のメソッドrotateを使えば次のように書くことができます。<br />
<br />

<pre><code>var sel=app.activeDocument.selection;
for(var i=0;i&lt;sel.length;i++){
    sel[i].translate(-100,-100);
    sel[i].rotate(30,true,true,true,true,Transformation.DOCUMENTORIGIN);
    sel[i].translate(100,100);
}</code></pre>
<br />
これでできあがり、でもいいんですが、<br />
なんかアイテム１つにつき移動&rarr;回転&rarr;移動と３つもメソッド使ってると、大量のアイテムを処理するとき重くなるかもしれないし、なんかもうちょっと良い書き方はないかしら、と考えてみます。<br />
<br />
<hr /><br />
イラレのPageItemには transform というメソッドがあります。<br />
これはTransformationMatrix（変形行列、２次元アフィン行列）という、次式のような６つの変数を持つ行列を使って変形を行うものです。<br />
<img src="//sysys.blog.shinobi.jp/File/759c7c66.png" alt="" /> <br />
ここでいう変形とは、回転、移動、拡大縮小（縦横比を保持しないものも含む）、シアー、およびそれらの組み合わせです。<br />
たとえば「原点を中心に&theta;回転」の変形行列は<br />
<img src="//sysys.blog.shinobi.jp/File/05bc2939.png" alt="" /> <br />
となります。<br />
ある点（x,y）を「原点を中心に&theta;回転」した点（x',y'）は、行列とベクトルの掛け算を使って、<br />
<img src="//sysys.blog.shinobi.jp/File/2ed60060.png" alt="" /> <br />
<br />
で求めることができます。<br />
<br />
しかし、こんな式は覚えなくても大丈夫です。<br />
Illustratorスクリプトには便利な組み込み関数があって、<br />
getRotationMatrix で回転の変形行列<br />
getTranslationMatrix で移動の変形行列<br />
を得ることができます。getRotationMatrixの引数は普通の角度でOKです。ラジアンを使う必要もありません。<br />
<br />
これらを使って上記スクリプトを書き換えると&hellip;<br />
<br />

<pre><code>var matA = getTranslationMatrix(-100, -100);
var matB = getRotationMatrix(30);
var matC = getTranslationMatrix(100, 100);
var sel = app.activeDocument.selection;
for (var i = 0; i &amp; lt; sel.length; i++) {
    sel[i].transform(matA, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
    sel[i].transform(matB, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
    sel[i].transform(matC, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
}</code></pre>
<br />
うーん、これでは何も改善してませんね。<br />
<br />
<hr /><br />
点（x,y）を表すベクトルをrとして、<br />
(-100,-100)移動の変形行列をA、原点を中心に30&deg;回転の変形行列をB、(+100,+100)移動の変形行列をCとしたとき、<br />
<br />
rを(-100,-100)移動した点は<br />
Ar<br />
<br />
rを(-100,-100)移動して、原点を中心に30&deg;回転した点は<br />
B(Ar)<br />
<br />
rを(-100,-100)移動して、原点を中心に30&deg;回転して、さらに(+100,+100)移動した点は<br />
C(B(Ar))<br />
<br />
で表せます。<br />
<br />
そして、行列の掛け算はなんと、<a href="https://ja.wikipedia.org/wiki/%E7%B5%90%E5%90%88%E6%B3%95%E5%89%87" title="">結合則</a>が使えるのです！<br />
すなわち、<br />
<br />
C(B(Ar)) = (CBA)r<br />
<br />
これは事前にCとBとAを掛け算した変形行列を求めておけば、変形１回で「(-100,-100)移動して、原点を中心に30&deg;回転して、さらに(+100,+100)移動」したのと同じ状態にできる、ということです。<br />
<br />
んで、イラレはその変形行列の掛け算にも関数を用意してくれています。concatenateMatrixというやつです。<br />
<br />

<pre><code>var matA = getTranslationMatrix(-100, -100);
var matB = getRotationMatrix(30);
var matC = getTranslationMatrix(100, 100);
var matABC = concatenateMatrix(concatenateMatrix(matA, matB), matC);
var sel = app.activeDocument.selection;
for (var i = 0; i &lt; sel.length; i++) {
    sel[i].transform(matABC, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
}</code></pre>
<br />
なんか上はごちゃごちゃしましたけど、forループがシンプルになったので今度こそできあがりでーす。<br />
<br />
ちなみにconcatenateTranslationMatrixとかconcatenateRotationMatrixとか使うともう少し短く書くこともできます。詳しくはOMビューワとか<a href="http://jongware.mit.edu/iljscs6html/iljscs6/pc_Application.html#concatenateMatrix" title="">ここ</a>とか見てください。<br />
<br />
<br />
おしﾓｱｲ]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/127</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/127/" />
    <published>2020-10-06T18:39:36+09:00</published> 
    <updated>2020-10-06T18:39:36+09:00</updated> 
    <category term="ExtendScript" label="ExtendScript" />
    <title>ExtendScriptで使ってはいけないグローバル変数名</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[JavaScriptしっかり書くならグローバル変数は極力なくして、どうしてもグローバル変数が必要なときはできるだけ独特な名前を、となるのでしょうけど、まぁInDesignやイラレでちょっとしたスクリプト書くときに、いちいちそんなこと気にしたくありません。適当な変数名で、グローバルスコープにベタ書きしてしまいがちです。<br />
<br />
しかしそういうとき、適当につけた変数名が思わぬバグを引き起こすことがあります。たとえばファイルパスの変数名に<span style="color: #ff0000;"><strong>path</strong></span>とか、何かを反転する関数名に<span style="color: #ff0000;"><strong>reflect</strong></span>とか、つい使ってしまいそうですけど、これらはバグの元です。（関数の中のローカル変数で使うのは問題ありません）<br />
<br />
この手のバグ、知識として知っとかないと原因の特定がすごく難しいので、この際まとめておきます。<br />
<br />
<hr /><br />
ExtendScriptはJavaScriptの亜種なので、JavaScriptでグローバル変数名に使っちゃダメなもの、たとえばeval、alert等の組み込み関数の名前や予約語等は、もちろんExtendScriptでもダメです。<br />
<br />
ここでは「普通のJavaScriptならOKだけどExtendScriptではダメなもの」を紹介します。<br />
ただし、ExtendScript全体で共通のものと、InDesign・イラレ独自のものだけです。フォトショやAEにも独自のものがあると思いますが詳しくないので触れません。<br />
<br />

<h3>１．アプリケーションオブジェクト</h3>
<ul>
<li>app</li>
</ul>
のことですね。当たり前ですが一応挙げておきます。<br />

<h3>２．ExtendScript独自の組み込み関数名</h3>
ExtendScript共通のものとしてはXML絡みの<br />

<ul>
<li>isXMLName</li>
<li>setDefaultXMLNamespace</li>
</ul>
くらいしかないです。<br />
アプリケーション独自のものには<br />

<ul>
<li>exit（InDesignのみ）</li>
<li>resolve（InDesignのみ）</li>
</ul>
などがあります。<br />

<h3>３．各種コンストラクタ名</h3>
ExtendScript共通のものはUnitValue、Reflection、BridgeTalkなど、<br />
アプリケーション独自のものはDocument、PageItem、TextFrameなど膨大にありますが、<br />
最初が大文字の変数名を避ければいいので、ここでは列挙しないことにします。<br />

<h3>４．Object.prototypeのプロパティ名</h3>
Object.prototypeのプロパティというのは、すべてのオブジェクトが共通して持っているプロパティのことです。<br />
すべてのオブジェクトが持つということは、グローバルオブジェクトも持っています。<br />
そしてグローバル変数というのはグローバルオブジェクトのプロパティでもあります。<br />
したがって、グローバル変数で「Object.prototypeのプロパティ名」を使おうとすると、グローバルオブジェクトがもともと持っているプロパティと競合してしまうので使ってはいけません。<br />
<br />
ExtendScriptにあり、今のJavaScriptにはないものとして <br />

<ul>
<li>reflect</li>
<li>watch</li>
<li>unwatch</li>
</ul>
が挙げられます。<br />
（watch、unwatchは昔のJavaScriptにはあったらしい）<br />

<h3>５．appのプロパティ名（イラレ、フォトショのみ）</h3>
イラレスクリプトでは、なぜかapp.が省略できます。<br />
スクリプトの書き出しは、<br />

<pre><code>var doc=app.activeDocument;</code></pre>
<br />
みたいなので始まることが多いですが、これを
<pre><code>var doc=activeDocument;</code></pre>
<br />
と書いても動くのです。 <br />
この謎仕様により、イラレスクリプトではappの持つプロパティ名をグローバル変数名に使えません。<br />
appのプロパティ一覧（CS6）はこちら<a href="http://jongware.mit.edu/iljscs6html/iljscs6/pc_Application.html" title="">http://jongware.mit.edu/iljscs6html/iljscs6/pc_Application.html</a><br />
うっかり使ってしまいそうなものとしては、<br />

<ul>
<li>name</li>
<li>path</li>
<li>version</li>
</ul>
などがあります。<br />
<br />
※Photoshopでも同じ問題があるようです。（<a href="https://twitter.com/CS5_omachi" title="">お～まちさん</a>に教えていただきました）<br />
<br />
（ちなみに似たような謎仕様として、textRange.characterAttributes の characterAttributes も省略できます）<br />
<br />
ｵﾜﾘ]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/126</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/126/" />
    <published>2020-09-07T10:41:53+09:00</published> 
    <updated>2020-09-07T10:41:53+09:00</updated> 
    <category term="ExtendScript" label="ExtendScript" />
    <title>比較演算がなんかおかしいExtendScript</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[ExtendScriptでは<br />
<br />

<pre><code>false==null;</code></pre>
<br />
がtrueになるけど、変数を使って<br />
<br />

<pre><code>x=false;
x==null;</code></pre>
<br />
とするとfalseになる（JavaScript的に正しいのはfalse）<br />
<br />
っていう話をだいぶ前に書いたんですが（<a href="http://sysys.blog.shinobi.jp/Entry/85/" title="">これ</a>の8番目）<br />
他にもnullと==で比較した結果がおかしいものを見つけました。<br />
<strong>0, "0", ""</strong> です。（"0"はfalsyですらないのに&hellip;）<br />
<br />
<img src="//sysys.blog.shinobi.jp/File/EUlrYh6UwAMM675.png" alt="" /> <br />
<br />
<br />
<br />
似たような現象はこんなのでも起きます。<br />
<br />
<img src="//sysys.blog.shinobi.jp/File/143d5cb6.png" alt="" /> <br />
<br />
<br />
数値と文字列の比較では文字列側をNumberに変換するので、"!"はNaNになって、「NaNは比較演算子で何と比較してもfalseを返す」という性質があるので false になるはずなのですが、変数に入れずに直接比較すると true になってしまいます。変数がある場合は正しいです。<br />
<br />
<br />
<br />
でー、変数があるかないかでなんでこんな違いが発生するのかなんですけど、<br />
JSXBIN化を使ってみるとヒントめいたものが見えてきます。<br />
<br />
これは「null==false;」をJSXBIN化した文字列<br />
@JSXBIN@ES@2.0@MyBbyBn0ABJAnAFct0DzABByB<br />
<br />
そしてこれは「true;」をJSXBIN化した文字列です。<br />
@JSXBIN@ES@2.0@MyBbyBn0ABJAnAFct0DzABByB<br />
<br />
完全に一致です。<br />
これは比較演算だけでなく、「1+1」と「2」とかでも同じになります。<br />
つまりはJSXBIN化（コンパイル）した時点で既に演算されてるのです。<br />
<br />
変数のある演算は、実際にプログラムが動いてその行に行きつくまで結果がわからないけど、1+1とか0==nullみたいなプリミティブ値のリテラル同士の演算は最初から結果がわかってるので、高速化のためにもコンパイル時に演算しておこう、ということなんだと思います。<br />
で、その演算が間違ってると。<br />
<br />
<hr /><br />
<br />
ここまでは「値を直接演算するとおかしいけど、変数があれば正しい」というもので、実際のスクリプトで出てくるのはほぼ変数ありの演算でしょうから、まあ罠ではあるけどそんなに深刻なバグではありません。<br />
<br />
次のは変数があろうとなかろうと、常におかしいやつです。<br />
<br />
<strong>undefined &lt; 任意の数</strong><br />
<br />
は、JavaScript的にはfalseになるのが正しいですが、<strong>ExtendScriptではtrue</strong>になります。<br />
<br />
たとえばこんなコードでうっかり引数を入れ忘れて実行したらtrueが返ってきてしまいます。<br />
<br />

<pre><code>function f(x){
    return x&lt;0;
}
f();</code></pre>
<br />
ちなみに任意の数ってのは0とか100だけでなく、Infinityや-Infinityも含まれます。<br />
「undefinedはマイナス無限大よりも小さい」ということになってしまうのです。<br />
<br />
<img src="//sysys.blog.shinobi.jp/File/EUbQhNjU4AciN4s.png" alt="" /><br />
<br />
ｵﾜﾘ]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/124</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/124/" />
    <published>2020-08-04T20:31:47+09:00</published> 
    <updated>2020-08-04T20:31:47+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>立体ぽくするスクリプトを公開しました</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<img src="//sysys.blog.shinobi.jp/File/pokusuru4.png" alt="" /> <br />
<img src="//sysys.blog.shinobi.jp/File/dialog.png" alt="" /> <br />
<br />
イラレのパスを、斜めに押し出したような立体ぽくするスクリプトです。<br />
文字に対して使う場合、パスのアウトライン化が必要です。<br />
<br />
アピアランスの３Ｄ効果をはじめ、似たような表現ができるいろいろなアピアランス技・ブレンド技がありますが、主な特徴は<br />
・構造がシンプルなパスになってる<br />
・陰影がグラデーションを使っていてなめらか<br />
・角から斜めの線が引かれる<br />
などです。<br />
<br />
BOOTHで７００円で販売しています。<br />
詳しくは<a href="http://sysys.zouri.jp/rittaipoku/" title="">こちら</a>へ。]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
  <entry>
    <id>sysys.blog.shinobi.jp://entry/123</id>
    <link rel="alternate" type="text/html" href="http://sysys.blog.shinobi.jp/Entry/123/" />
    <published>2020-06-24T10:41:44+09:00</published> 
    <updated>2020-06-24T10:41:44+09:00</updated> 
    <category term="イラレ" label="イラレ" />
    <title>イラレでサインカーブの描き方</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[サインカーブ、正弦波などと呼ばれる、三角関数sinのグラフをIllustratorで簡単に描く方法です。<br />
<br />
使う機能はアピアランスの『ジグザグ』とブレンドで、どちらもかなり昔のバージョンからあると思うので、古いイラレでも使えます。<br />
<br />
①同じ長さの直線を２本用意します<br />
<br />
②直線にジグザグの効果をかけます<br />
「大きさ」は適当に。<br />
「折返し」も適当でいいんですが、サインカーブの１周期分を作るなら3以上が必要です。<br />
2本の直線のうち一方は「直線的に」もう一方は「滑らかに」にします。<br />
<br />
③アピアランスを分割<br />
<br />
④ブレンドを作成し、ブレンドオプションでステップ数を10にします<br />
<br />
⑤ブレンドを拡張し、グループ解除します。<br />
<br />
⑥滑らかな方から4番目がサインカーブ（近似）になります<br />
<br />
<img src="//sysys.blog.shinobi.jp/File/ET9DGB_UEAMf-xb.png" alt="" /> <br />
※「オブジェクト＞パス＞アンカーポイントの追加」をやっておくと、sin(x)=0のところにポイントができて扱いやすくなります。<br />
<br />
<br />
<br />
アンカーポイント少ないし、かなり大雑把に作ってるようですが、<br />
これ、意外なほど精度の高い近似になっているのです。<br />
<br />
ためしに、１周期分を縦２：横２&pi;の比率に変形して、<br />
スクリプトでsin関数を厳密にプロットしたものと比較してみましょう。<br />
<img src="//sysys.blog.shinobi.jp/File/0f5c0158.png" alt="" /> <br />
このサイズのスクショでは全く違いが見えないレベルで一致しています。<br />
<a href="//sysys.blog.shinobi.jp/File/1c7ce967.pdf" title="">pdfで拡大</a>してもごくわずかに青がはみ出してるのが見える程度です。<br />
実用上は十分すぎる精度じゃないでしょうか。<br />
<br />
ｵﾜﾘ<br />
<br />
<hr />
<h3>関数の描き方シリーズ</h3>
・<a href="http://sysys.blog.shinobi.jp/Entry/120/" title="">双曲線（反比例のグラフ）の描き方</a><br />
・<a href="http://sysys.blog.shinobi.jp/Entry/91/" title="">放物線の描き方</a><br />
<br />
]]> 
    </content>
    <author>
            <name>kawamoto_α</name>
        </author>
  </entry>
</feed>