プラグインを書いて、Adobe XD plugins developer になろう。

Swap Fill and Border というAdobe XDのプラグインを制作しました。

見えますかね?一番上のプラグインの制作者が、 Naruhito Kubota となっております。

これで私も Adobe XD plugins developer (言いたいだけ)になったのですが、実は内容としてはとてもかんたんなものです。そのお話をします。

線と塗りの色を一発で置き換えたい

この機能はAdobe Illustratorなどではデフォルトである機能です。
User Voiceにも挙がっており、前々よりVoteしていますがなかなか実装されていませんでした。

Swap border and fill colors | Adobe XD: Feature Requests

これと同等な機能はSketchではプラグインによって実現されているため、Adobe XDでも同様にプラグインで実現しようと思ったのがはじまりです。

実現までの道のりをトレースしてみる

さて、まず方法は以下のように考えていました。

  • オブジェクトが選択されている
    • いない場合はアラートを出す
  • 選択されているオブジェクトの線の色と塗りの色を変数として持つ
  • オブジェクトの線と塗りの色をあらたに代入する

雛形をつくってコンソールログで中身を見てみる

まずはプラグインの基本設定をして、オブジェクトがの値の持ち方を知るために中身を見てみたところからです。
今回はmanifest.jsonについては、はじめにコードだけ載せてあとは深く書きませんので、ご興味のある方は次の記事を参考にどうぞ。

manifest.json の書き方

main.js

1
2
3
4
5
6
7
8
9
10
function swapFillAndBorder(selection) {
let items = selection.items;
console.log(selection.items);
}

module.exports = {
commands: {
myPluginCommand: swapFillAndBorder
}
};

manifest.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"name" : "Swap Fill and Border",
"host" : {
"app" : "XD",
"minVersion" : "13.0.0"
},
"description" : "Swap Fill and Border is a plugin that allows you to switch fill and border colors in a moment. You can save your time and let you focus on the UI that really matters",
"id" : ,
"icons" : [ {
"path" : "images/icon.png",
"width" : 96,
"height" : 96
} ],
"uiEntryPoints" : [ {
"label": "Swap Fill and Border",
"type": "menu",
"commandId": "myPluginCommand",
"shortcut": {
"mac": "Cmd+Shift+x",
"win": "Ctrl+Shift+x"
}
} ],
"version" : "1.0.4"
}

この状態でオブジェクトを選択して、Swap Fill and Borderを動かすと、選択されているアイテムの情報が見れます。

以下に返ってくる内容の例をあげます。

1
2
3
4
5
6
7
[ Ellipse ('Ellipse 1') {
width: 120, height: 120
global X,Y: 137, 21
parent: Artboard ('iPhone 6/7/8 – 1')
stroke: ff825ca9
fill: ff6daad6
} ]

selection.itemsはひとつの四角形で、レイヤー名は’Ellipse 1’で、持っている各値が中に書かれています。
今回のプラグインでは、strokefillを利用するわけですね。
ちなみに、中に入っている値は、rgbaの16進数表記のようですね。

JavaScriptで入れ替える処理を実装してみよう

※ ここからの処理は module.exportsの記述を省略します。

1
2
3
4
5
6
7
8
9
function swapFillAndBorder(selection) {
let item = selection.items[0];
let border = item.stroke; // borderという変数に線の色を保持
let fill = item.fill; // fillという変数に線の色を保持

// 以下、交互に代入
item.stroke = fill;
item.fill = border;
}

これで、選択されたオブジェクトの線の塗とを入れ替えられます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function swapFillAndBorder(selection) {
let itemsNum = selection.items.length;
for (let i = 0; i < itemsNum; i++) {
let border = selection.items[i].stroke;
let fill = selection.items[i].fill;
selection.items[i].fill = border;
selection.items[i].stroke = fill;
}
}

module.exports = {
commands: {
myPluginCommand: swapFillAndBorder
}
};

動作確認&問題点の認識

  • 複数のオブジェクトに対応していない
    − リピートグリッドやグループの子要素の入れ替えに対応していない
    − アートボードを選択時にプラグインを動かすとコンソールにエラーが出る

という点を認識しました。

複数オブジェクトはクリティカルですね。
グループやRGは中のオブジェクトを選択すれば動作する点から後から対応と判断。
エラー処理は、選択されているitemsの種類で処理しないとかとも考えましたが、選択されているitemsがFillかStrokeのどちらかで値を持っていなかったら何もしなければよいと考えるとかなりラクに処理できそうです。

JavaScriptでの実装アップデート版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function swapFillAndBorder(selection) {

let itemsNum = selection.items.length; // 選択しているオブジェクトの個数を取得

// 上記個数分、入れ替える処理をfor文で実装
for (let i = 0; i < itemsNum; i++) {
let border = selection.items[i].stroke;
let fill = selection.items[i].fill;

// if文は、borderとfillの値が両方あるならの処理。(エラー対策)
if(border && fill) {
selection.items[i].fill = border;
selection.items[i].stroke = fill;
}
}
}

かんたんだた。

リジェクトされたその1

理由 - オブジェクト選択していないときに何もおきないのなんとかして。

正直、みんな知ってそうな機能だし、むしろアラート出すのが迷惑かなと思って省いてたけど、プラグイン開発のガイドライン上やっぱり必要らしい。
ここで、dialogs.jsをrequireする決意。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const { alert, error } = require("./lib/dialogs.js");

function swapFillAndBorder(selection) {

let itemsNum = selection.items.length;

if(!itemsNum) {
error("Ooops!", "You need to select at least one layer.");
return;
}

for (let i = 0; i < itemsNum; i++) {
let border = selection.items[i].stroke;
let fill = selection.items[i].fill;
if(border && fill) {
selection.items[i].fill = border;
selection.items[i].stroke = fill;
}
}
}

module.exports = {
commands: {
myPluginCommand: swapFillAndBorder
}
};

選択されたオブジェクトがない場合の処理のreturnを早めにしたかったので、そういう処理。
これが最終版です。
何も選択していないと、”Ooops! You need to select at least one layer.” と煽ってくるのでぜひご覧あれ。

リジェクトされたその2

理由 - プラグインの説明、短すぎ

はい。

“Swap fill and border in a moment”

しか最初書いていなかったので、情報追加しました。

そして、リリースにこぎつけました。

制作までの時間的なものを振り返る

会社のメンバーともくもく会をやった1時間でリジェクト前までのJavaScript側の処理は書けて、提出用の処理などでプラス1時間ちょっととかです。後者ははじめてだったので、なれてくれば時間は減るでしょう。
その後リジェクトの連絡来て都度対応したのがトータル1時間くらいですかね。

作りたいものの定義がきちんとしてさえいれは、数時間で Adobe XD plugins developer になれます。

いっしょに学ぼう

はじめてのAdobe XDプラグイン開発 が東京市ヶ谷で12/13に開催されます。(この記事を書いている日ですね)

イベント中継「はじめてのAdobe XDプラグイン開発」 | Creative Cloud 道場でのライブ配信、アーカイブ配信も予定しています。
ぜひ皆さん、いっしょにプラグイン開発者への一歩を踏み出しましょう!

共有 コメント