Windows + Adobe CC illustrator / CEP 5 でイラレのカスタム UI を作ってみる (4) 選択した図形の色プロパティをボタンで取得する

## Introduction
Adobe illustrator (イラレ) の仕事では線幅やカラーが厳格に指定されている図形を多用する場合があります。(例えば地図作成や誌面デザイン、手芸の手順書 etc.)
illustrator では既定で直線や円などの描画モードがワンボタンで選べるので、同様に所定の図形をワンボタン化できないか調べてまとめました。

この記事は CC 版 illustrator / Windows 環境が対象です。この章では、ボタンを押すと選択した図形の色などの情報を見られる体制を整えます。

## 今回やりたいことの流れ
今回は、図形を選択した状態でボタンを押すと所定のプロパティを設定するような動きを作ります。例えば以下のような処理です。

* 図形を指定の色で塗りつぶす
* 図形の周辺の線の太さを 1pt の点線にする
* etc.

出版社などからフォーマットを指定されたり変更されたりした場合、illustrator で図形を選んでは色を変え、線を変え、太さを変え…とやっていると非常に面倒です。なので指定の変更をワンボタンにしてしまおう、という発想です。

これを CEP の処理に置き換えると、まず **ボタン** が必要です。これは index.html ですね。
ボタンを押すと **現在選択中の図形を列挙**し、**順々にプロパティを変えていく** ことになります。この辺は hostscript.jsx に書いておいて、main.js で呼びましょう。

ただしいきなりプロパティを変える前に、そもそも adobe CEP で取得する図形のプロパティはどのようなオブジェクトなのか？を理解したほうがリファレンスも読みやすそうです。あくまで処理は設定 (set-) ですが、この章では情報取得 (get-) までを一旦のゴールにします。

## ボタンを作る
※index.html の記述順を入れ替えて、リロードボタンを下に持っていきました。またこんな感じで関係のない文言をコメントアウトしました。本来はデバッグ用のリンクに Reload やらなんやら結びつける想定なんでしょうけど、もう Reload ボタン作ってしまったので。

```html:index.html
    <!-- These are debugging shortcuts.  Class debuglink items only appear in debug mode
    <span class="debuglink" id="reload">Reload</span>
    <span class="debuglink" id="debug">Debug</span>
    <span class="debuglink" id="sources">Sources</span>
    -->
    <div>
        <!--リロード用のボタンを追加-->
        <button id="btn_reloadpageandscript" class="topcoat-button--large hostFontSize">Reload</button>                
    </div>   
```

まずは前回同様、index.html を変更して専用のボタンを作ります。ID は適当に `btn_mySetProperty01` としました。

```html:変更前
        <div>                
            <button id="btn_test" class="topcoat-button--large hostFontSize">Call ExtendScript</button>                
        </div>   
```
```html:変更後
        <div>                
            <button id="btn_test" class="topcoat-button--large hostFontSize">Call ExtendScript</button>                
            <!-- プロパティ設定用ボタン -->
            <button id="btn_mySetProperty01" class="topcoat-button--large hostFontSize">mySetProperty01</button>                
        </div>   
```

一応、CSS も前回同様変えて横長ボタンにしますか。styles.css を変更します。

```css:変更前
#btn_test{
    width: 100%;
}

#btn_reloadpageandscript{
    width: 100%;
}

```

```css:変更後
#btn_test{
    width: 100%;
}

#btn_reloadpageandscript{
    width: 100%;
}

#btn_mySetProperty01{
    width: 100%;
}
```
以上でこんな感じになります。
![SS21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/91419868-6572-675b-eed4-fffa9f2ce19c.png)

## スクリプトのガワを準備する

#### main.js
ボタンクリック時の処理を受けるところを書いておきます。呼び出し関数は適当に `setProperty01()` としておきましょう。

```javascript:main.js
function init() {
<略>
   $("#btn_mySetProperty01").click(function (){
            //プロパティ設定ボタンを押したときに呼ぶ関数
            csInterface.evalScript('setProperty01()');
        });
    }
```

#### hostscript.jsx
とりあえず、setProperty01() を書いておきましょう。既存の sayHello と並列に書きます。

```javascript:hostscript.js
function sayHello(){
    alert("hello from ExtendScript_changed");
}

function setProperty01(){
    //選択中の図形を取り出す
    //取り出した図形のプロパティを設定
}
```

さて、ガワができたので hostscript.jsx の中を作り込んでいきましょう。JSX ファイル
は CEP 登場以前から使われていた歴史のあるスクリプトなので、事例がたくさん見つかります。もちろん、リファレンスも読んだ方がいいです。
https://www.adobe.com/content/dam/acom/en/devnet/illustrator/pdf/Illustrator_Scriptin_Reference_JavaScript_cc.pdf

## スクリプトを煮詰めていく
#### hostscript.jsx - 選択した図形の情報を返す

本来、この関数は set～ なので設定を変更するのがゴールなのですが、初手は図形の取得 (get) から入りましょう。選択図形の取得は `app.activeDocument.selection` でできます。とりあえず変数 `selectedObject` に突っ込んでおきます。

取得できたオブジェクトはどんな構造なんでしょう？こんな時 Powershell なんかは見やすいのですが JavaScript ではどう中身を覗いたものか、難しいものです。また JSX は直接画面側への出力ができないため **直接コンソールに結果を出せない** トラップがあります。
そこで、ひとまず `selectedObject` をそのまま main.js に返り値として返しましょう。以下のように return をつけます。

```javascript:hostscript.jsx
function setProperty01(){
    //選択中の図形を取り出す              
    var selectedObject = app.activeDocument.selection;
    
    //選択した要素の 1 番目を返す
    return selectedObject;
    //取り出した図形のプロパティを設定

}
```
#### main.js - 返り値をコンソールに出力
帰ってきた値をコンソールに出すことで、Cefclient の開発者モードから値を見ることができます。
ただし、setProperty01 の値を一度変数格納して console.log に突っ込むことはできません。代わりに csInterface の evalScript の記法オプションを使います。(以下参考)
http://nakatoji.lolipop.jp/index.php/extendscript/cep/cep-list/321-extendscript

```javascript:変更前
        $("#btn_mySetProperty01").click(function (){
            //プロパティ設定ボタンを押したときに呼ぶ関数
            csInterface.evalScript('setProperty01()');
        });
```
```javascript:変更後
        $("#btn_mySetProperty01").click(function (){
            //プロパティ設定ボタンを押したときに呼ぶ関数
            csInterface.evalScript('setProperty01()',function(x){console.log(x)});
        });
```
csInterface.evalScript に 2 つ引数を渡すと、片方を実行したうえでもう片方 (コールバック の関数に入れてくれる動きと理解しました。多分あってるはず。

ここまで進めて動かしてみましょう。illustator で適当な図形を描いて選択した状態で mySetProperty01 ボタンを押します。

![SS22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/56ac66d2-4c4d-b48a-fcf4-295252fb97a9.png)

なるほど、適当に描いた長方形を選んでみたところ [PathItem ] とだけ出ました。ちなみに何も選ばないと出力は空、2 つ図形を選択すると [PathItem ][PathItem ] となります。配列で取得できるようですね。

恐らく本当は PathItem はオブジェクトであって線幅や色などプロパティを持っているのでしょう。ただ、残念ながらこのコールバックだと文字列しか受け取れないようなので、`console.log(x)` のところを弄っても展開できません。

ここからはリファレンスとの戦いです。PathItem が入っていそうなので、まず対応するページを開くと利用できるプロパティが並んでいます。(以下130p)
https://www.adobe.com/content/dam/acom/en/devnet/illustrator/pdf/Illustrator_Scriptin_Reference_JavaScript_cc.pdf

たとえば、fillcolor というのはおそらく塗りつぶし色でしょうね。これは Color クラスなのでそれを紐解くと (26p) 、RGBColor や CMYKColor など色々定義があるようです。これはある色を RGB で見るのか、CMYK で見るのかの表示の違いです。illustrator のドキュメントのカラーモードに従って CMYK または RGB で取り出せます。筆者の環境では既定は CMYK でした。
![SS24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/d1f9e60f-2191-4722-fe62-556c630da6fc.png)


試しに、取得した図形を CMYK で見た時の K (黒の度合い) を取り出してみましょう。hostscript.jsx の setProperty01() を以下のように書き換えます。
selectedObject は配列の場合があるので、配列が空の場合は null を、それ以外は 1 番目の要素を返すようにしています。

```javascript:hostscript.jsx
function setProperty01(){
    //選択中の図形を取り出す              
    var selectedObject = app.activeDocument.selection;

    //もし図形が選択されていなかったらnullを返す
    if (selectedObject.length ==0){
        return null;
    }
    //図形が 1 つ以上選択されていれば1番目の要素のfillcolorのK要素を返す
    else {
        return selectedObject[0].fillColor.black;
        //取り出した図形のプロパティを設定
    }
}
```
以上の手順の後、適当に黒っぽい図形を選択してコンソールで見てみると…
![SS23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/658cf033-04fe-f18f-d64e-abf84877acb0.png)

値が出ました。この例では K≒30 ですね。

## まとめ

以上、まずはイラレ図形のプロパティ値を取得する流れを書いてみました。
次章ではこのプロパティを変えていく方法を探ります。