XDで色をランダムに選んでくれるプラグインを作る

# XDのプラグイン
ワイヤーフレームを書くのに超便利なAdobe XDさまは有志が作成したプラグインを入れる機能があり、超便利をもっと超便利にできます:ok_woman_tone1:
### でも
XDのプラグインストアは大変探しにくい（私がサーチ下手）な上、XDのおすすめプラグインを日本語で探しても同じプラグインばかり出てきて:no_good_tone1:理想のプラグインを探すに探せない日々を長く送ってきました。

ちょっと配色に迷ってるんだよな〜ただ色を変えるだけのプラグインが欲しいな〜でも探してもシンプルな機能なやつはストアで埋もれちゃって出てきにくいんだよな〜そもそも無いんじゃ？となっていたある日、XDのプラグインがjsで書かれてると知りました。無いなら作っちゃえばいいんですね〜:raising_hand_tone1:

# 下準備
## テスト用XDファイル
適当なアートボードに適当なオブジェクトを配置します。
<img width="357" alt="スクリーンショット 2019-12-08 18.55.07.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/9605a98b-0211-4370-525d-160e65d096b8.jpeg">

## プラグインフォルダーの作成
まずXDのメニューから『プラグイン』>『開発版』>『開発フォルダーを表示』を選択して開発フォルダーを表示します。
<img width="549" alt="スクリーンショット 2019-12-05 19.51.36.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/f233a1a0-e9eb-477e-3479-5fc729218f12.jpeg">
開かれた『develop』フォルダの中にプラグイン用のフォルダを新しく作り中身を入れていきます。
今回作りたいのは色をランダムに選ぶプラグインなので、フォルダの名称は『random-color』としました。
<img width="843" alt="スクリーンショット 2019-12-05 19.52.59.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/b6f6cb95-cb1a-1e7c-4db3-4dca30232a1b.jpeg">
# 必要なファイルを作成
XDのプラグインを作る上で最低限必要なファイルは以下の２点のみです。実にシンプル:ok_woman_tone1:

- manifest.json
- main.js

manifest.jsonはプラグインの概要など基本情報を書き込むjsonファイルで
main.jsはプラグインの処理を書き込むjsファイルです。

## manifest.json
プラグインの基本的な情報を書き込むjsonファイル『manifest.json』を作成します。

```manifest.json
{
  "id": "RANDOM_COLORS",
  "name": "Random Colors",
  "description": "色をランダムに選ぶプラグインです。",
  "version": "1.0.0",
  "host": {
    "app": "XD",
    "minVersion": "13.0.0"
  },
  "uiEntryPoints": [
      {
        "type": "menu",
        "label": "random-colors",
        "commandId": "randomCommand"
      }
   ]
}
```
|項目|説明|
|:-----------------|:------------------|
|id|プラグインのID|
|name|ストアでリリースした際に表示される名称|
|description|ストアでリリースした際に表示される説明文|
|version|プラグインを更新していく時に変更する項目|
|host|XDのプラグインということを示す項目（基本的に変更はしない）|
|uiEntryPoints|labelはXD内メニューに表示される名称　commandIDはmain.jsのどの関数を呼ぶか紐付ける時に使う識別子|
idはストアでリリースするときは[I/O Console](https://console.adobe.io/plugins)で発行されるユニークなIDを使用しますが、今回はリリースの予定はないので適当に入れました。
uiEntryPointsのlabelはuiEntryPointsの要素が複数あるときに表示されます。（uiEntryPointsの要素が1つしかない場合は表示されません。）

## main.js
こちらはプラグインの中身を書くjsファイルです。
### オブジェクトの情報を取得
とりあえずXDでオブジェクトを選択している時に何の情報が返っているかをコンソールに吐き出してみます。

```main.js
function randomHandlerFunction(selection) {
  let selectItems = selection.items;
  console.log(selection.items);
}

module.exports = {
  commands: {
    randomCommand: randomHandlerFunction
  }
};
```
上のfunction部分にプラグインの中身を書き、下のmodule.exports部分でファンクション名と先ほどmanifest.jsonで入力した識別子を紐付けします。

XDのコンソールは『プラグイン』>『開発版』>『Developer Console』から表示します。
<img width="512" alt="スクリーンショット 2019-12-08 18.51.26.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/407504d1-d444-0615-ff46-1b91b6af2811.jpeg">


```DeveloperConsole.
[ Rectangle ('長方形 1182') {
    width: 300, height: 450
    global X,Y: 1278, 765
    parent: Artboard ('random')
    stroke: ff000000
    fill: ff84e8c6
  } ]
```

長方形オブジェクトを選択した状態で実行したらこのようなデータが返ってきました。
現在選択しているオブジェクトはRectangle（長方形）で、レイヤー名は’長方形 1182’で、その中に諸々のデータが書かれています。

|項目|説明|
|:-----------------|:------------------|
|width|オブジェクトの幅|
|height|オブジェクトの高さ|
|global X,Y|X座標、Y座標|
|parent|親オブジェクト|
|stroke|線の色|
|fill|塗りの色|

### 塗りの色を上書き
とりあえずベタ書きで色が変更できるか試します。

```main.js
const {Color} = require("scenegraph"); // XD拡張APIのクラスをインポート

function randomHandlerFunction(selection) {
  let selectItems = selection.items[0];
  selectItems.fill = new Color("#FF0000"); // 塗りの色を赤に
  console.log(selection.items);
}

module.exports = {
  commands: {
    randomCommand: randomHandlerFunction
  }
};
```

functionの前にcolorクラスを使用するために拡張APIをインポートしています。
### 実行
<img width="299" alt="スクリーンショット 2019-12-08 20.15.37.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/2366571e-b05a-1056-3561-f7d9b33c0181.jpeg">
見事選択している長方形オブジェクトが赤色になってくれました:confetti_ball:

```DeveloperConsole.
[ Rectangle ('長方形 1182') {
    width: 300, height: 450
    global X,Y: 1278, 765
    parent: Artboard ('random')
    stroke: ff000000
    fill: ffff0000
  } ]
```

ちゃんとコンソールのfill部分も赤色(rgbaの16進数表記)に変わってます:tada:

### ランダム色を生成して上書き
ベタ打ちで色が変えられることがわかったのであとは色をランダムにします。

```main.js
const {Color} = require("scenegraph"); // XD拡張APIのクラスをインポート

function randomHandlerFunction(selection) {
  let selectItems = selection.items[0];

  // ランダムなカラーコードを生成
  var randomColor = "#";
  for(var i = 0; i < 6; i++) {
    randomColor += (16 * Math.random() | 0).toString(16);
  }

  selectItems.fill = new Color(randomColor);
  console.log(selection.items);
}


module.exports = {
  commands: {
    randomCommand: randomHandlerFunction
  }
};
```
ランダムな16進数のカラーコードの生成はこちらの記事を参考にさせていただきました。
[6ケタのカラーコードをランダムで生成する色々な方法](https://q-az.net/random-color-code/)

### 実行
![gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/132da401-4020-e91c-237c-9b86e49f4e03.gif)

ワオ:tada::tada::tada:
ランダムな色を選択してくれるようになりました:confetti_ball:
（PCが重くてちょっとラグがありますがサクサクPCならパッパッと変わります）

### ショートカット
いちいちプラグインメニューから実行するのは面倒なのでショートカットキーを登録します。

```manifest.json
{
  "id": "RANDOM_COLORS",
  "name": "Random Colors",
  "description": "色をランダムに選ぶプラグインです。",
  "version": "1.0.0",
  "host": {
    "app": "XD",
    "minVersion": "13.0.0"
  },
  "uiEntryPoints": [
      {
        "type": "menu",
        "label": "random-colors",
        "commandId": "randomCommand",
        "shortcut": { "mac": "Cmd+alt+c", "win": "Ctrl+alt+c" }
      }
   ]
}
```
"uiEntryPoints"の中に"shortcut"の記述を追加しました。
macではcommand + alt + cキー
WindowsではCtrl + alt + cキーでパパッと色が変えられます:v::v_tone1::v_tone2::v_tone3::v_tone4::v_tone5:

## 使用例
![gif02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340174/5abb8eaa-4a57-9c86-3b9f-f98316acae9b.gif)
使用画像が用意されている上でメインカラーをランダムで決めるということはまあ…あまりあり得る状況では無いですが、ワイヤー全体を見ながらショートカット一つで色がパパパっと変わるのでカラーパターンを出しやすくなりますね:ok_hand:

メインカラーをランダムで決めることは少なくても、指定がないけど付けなくちゃいけない色、例えばリストのアイコンなどは色々試してみて決めることが多いので活用できそうだなと（個人的には）思いました:ok_woman_tone1: