Figmaプラグインの作り方
ちょっと手でやるのは面倒な作業があったのでFigmaプラグインの作り方を調べてみました。ドキュメントも結構ちゃんとしているのでJavascriptが書ける人なら簡単だと思います。とはいえ英語しかないので日本語でメモしておけば誰かの役に立つかもしれないとも思い簡単なメモ。Macでしか試していないので他の環境のことは知りません。すみません。たぶんだいたい一緒です。
前提
前提(Prerequisites)としてJavascriptが書ける必要があります。いくつか入門サイトへのリンクが挙げられています。日本語だとドットインストールとかでしょうか。サンプルなどはJavascriptに型指定がついたTypescriptで書かれているのでそちらも理解しておいた方が良いですが必要に応じて。WebpackとReactも挙げられていますが、これらは知らなければ無視しても大丈夫です。
準備
実際にはデスクトップ版のFigmaとテキストエディタがあれば作れるのですが、チュートリアルはnode.jsとVisual Studio Codeを使う手順になっているのでそれに従います。サンプルをコンパイルするにはnode.jsが必要になるのでここは素直に。nodeについての知識はゼロで大丈夫です。
VS Codeはここからダウンロードします。Node.jsのインストーラはここから。Node.jsを入れたらターミナルで下記のコマンドを実行してTypescriptをインストールします。
npm install -g typescript
Figmaは親切なので新しいプラグインを作るたびにリマインドしてくれますが一度やっておけば大丈夫。
テンプレートを作成
デスクトップ版のFigmaから、Go to Menu > Plugins > Development > New Plugin... でプラグインのテンプレートが作成できます。empty(空っぽ)、run once(一度だけ実行)、With UI and browser APIs(UIとブラウザAPI付き)の三種類から選べます。後の2つはサンプルコードが付いてくるので参考になります。まずはチュートリアル通りに With UI and browser APIs を選択。選んだ場所にフォルダといくつかのファイルが作られます。
コンパイルと実行
作成したフォルダをVS Codeで開きます。
⌘⇧B (WindowsではCtrl-Shift-B for)を押すとコマンドパレットが開くので tsc: watch - tsconfig.json を選んでください。
作成したテンプレートは code.ts というファイルにTypescriptでコードを書いて code.js という実行用のファイルにコンパイルするようになっています。tsc: watch を実行すると、このコンパイル作業を自動で行ってくれるようになるので便利です。Typescriptを使いたくない場合はcode.jsを直接編集してもokです。
コンパイルできたらFigmaに戻ってテンプレートのコードを実行してみましょう。Menu > Plugins > Development > の下に新しく作ったプラグインの名前があるので選択します。ダイアログが開いて入力した数の分だけ正方形のノードが作られます。
ちなみに Run Once を選んだ場合はダイアログなしで正方形を5個作るコードがテンプレートになっています。
コードを書き換えて実行
これでプラグインが動くようになったので code.ts を書き換えて色々試してみましょう。Menu > Plugins > "Run Last Plugin" 、または ⌥⌘P(Mac)、 Ctrl+Alt+P(Windows)で同じプラグインがもう一度実行できます。
最初に作ったサンプル
async function inspect(selection) {
console.log(selection);
}
Promise.all(figma.currentPage.selection.map(selected => inspect(selected)))
.then(() => {
//figma.closePlugin()
})
最初に作ったのはこれです。Figmaで選択中のノード(フレームとか図形、テキストとか)をコンソールに表示するだけですが、Figmaのノードがjavascriptのオブジェクトとしてどのように表現されているのかを確認するのに便利です。
実行する前に Menu > Plugins > Development > Open Console でコンソールを開いておきましょう。Chromeのデバッグコンソールと同じものが開きます。プラグインを走らせると Running ... | Cancel という表示が表示されるのでCancelを押せば実行終了できます。
figma.closePlugin() はプラグインの実行を終了するコマンドです。プラグインの実行が終わってしまうとコンソールではオブジェクトの中身が見れなくなってしまうのでコメントアウトしてあります。
UIの作り方
プラグインの実行時にダイアログのUIを表示したい場合は With UI and browser APIs のテンプレートを選ぶか manifest.jsonに下記の1行を追加します。
"ui": "ui.html"
メインのスレッド(code.js)から
figma.showUI(__html__)
を呼び出すとこのhtmlファイルが開かれるようになります。htmlの中の記述は自由にしてok。メインのスレッドにメッセージを送るには下記のようにします。
parent.postMessage({ pluginMessage: { type: 'type-string', value } }, '*')
詳しくは Creating a User Interface のページ参照。
基本のAPI
ノードの種類とAPIは API Reference にまとまっています。ここから先は本家のドキュメントに道を譲りたいのですがいくつか最初に役に立つコードだけ上げておきます。
Figmaのドキュメントはノードのツリーとして表されます。figme.rootの下に複数のpageがあって、その下にはフレームやシェイプ、テキストなどの階層があります。figma.currentPage.selection を使うと現在選択中のノードのリストが得られます。ドキュメントのノードを一通り調べたい場合は figma.root から初めてその children を再帰的に調べていきます。
for (const node of figma.currentPage.selection) { ... }
function traverse(node) {
if ("children" in node) {
// do something
if (node.type !== "INSTANCE") {
for (const child of node.children) {
traverse(child)
}
}
}
}
traverse(figma.root)
特定の条件でノードを探したい場合は node.findOne か node.findAll が使えます。node部分は調べたいノードのオブジェクトです。これらの関数には引数として検索条件を表す関数を渡します。findOneは最初に見つかった一個だけ、findAllは見つかったノード全部のリストを返します。
const node = node.findOne(node => node.type === "TEXT" && node.characters.length > 100)
// Finds all empty frame nodes
const nodes = node.findAll(node => node.type === "FRAME" && node.children.length === 0)
新しいノードを作るには
figma.createRectangle();
のように figma オブジェクトの関数を使います。
ノードのプロパティを変更する場合、プロパティの値が数値や文字列であれば直接書き換えられますがオブジェクトの場合は一手間必要です。中身をそのまま操作するのではなく、一旦オブジェクトごと複製して変更した後、渡し直す必要があります。
// Example: Changing the red channel of the first fill
const fills = clone(rect.fills)
fills[0].color.r = 0.5
rect.fills = fills
詳しくはこちら。
公開
作ったプラグインを公開するにはMenu > Plugins > Manage Plugins でプラグインの管理画面を開き、画面右端の Development から Publish New Release します。アイコンや画像、解説などをつけてpublishすれば完了。コーポレートアカウントであれば自分の組織だけに公開するオプションもあります。
まとめ
以上です。結局詳しいところは英語のドキュメント任せなのですが、最初の一歩さえ踏み出せれば後はだいぶ楽だと思います。Webの経験があれば割と素直に理解できる仕様になっていると思いました。Figmaはプラグインの配布も簡単なのでチームみんなで同じ環境にするのもスムーズです。みんなで楽をしましょう。