見出し画像

Figmaのプラグイン作成入門

こんにちは。普段はUIデザイナーとして業務を行っています。
UIデザインの作業ではFigmaを利用しており、便利なプラグインを日々利用させていただいており、自分でもいつか作ってみたいなと思っておりました。

そこで冬休みの目標として、Figmaのプラグインをなにか作ってみることにしました。
その際の手順などをメモとして残しておこうと思っています。


サンプルプラグインを作成

まずはFigmaで用意されているサンプルプラグインを実行できるところまでやってみます。

サンプルプラグインの作成手順

メニュー > Plugins > Development > New plugin..を押します。

「Name」に任意のプラグイン名を入力して「Figma design + Fig jam」を選択してNextボタンを押します。

プラグインの種類の選択画面が出てくるので、内容に合わせて以下をのいずれかを選択します。

  • Default
    プラグインを一から構築できる白紙の状態。

  • Run once
    ユーザーの操作なしで 1 回だけ実行されるプラグインのテンプレートです。プラグインに UI が必要ない場合は、このテンプレートを使用します。

  • Custom UI
    インタラクティブな UI を備えたプラグインを作成する場合、またはブラウザー API を使用するプラグインを作成する場合は、このテンプレートを使用します。

作成したプラグインを保存して、「Done」を押します。

上記の手順で、サンプルプラグインが作成されます。これを雛形に作成していくのが最初は良さそうです。

作成されたファイル構成は以下の通りです。
HTML + Typescripで作成されているので、フロントエンドの知識が少しあればできそうです。

├── README.md
├── code.js ・・・ code.tsから書き出されるファイル
├── code.ts ・・・ mainJSファイル。manifest.jsonで定義する
├── manifest.json ・・・ プラグインのメタ情報を記述する
├── node_modules
├── package-lock.json
├── package.json
├── tsconfig.json
└── ui.html ・・・UIファイル。manifest.jsonで定義する

サンプルプラグインを動かす

次に、作成したサンプルプラグインをFigmaで動かしてみます。
動かすためには、node.jsのインストールが必要です。

npm install
npm install -D @figma/plugin-typings // 型定義ファイルもインストール
npm run build // アプリをビルドする

以下はサンプルプラグインを動かすのとは直接関係ないですが、開発時にtsファイルをjsに書き換える必要がある為、package.jsonに以下を追加します。
開発時にはnpm run dev とか yarn devで変更したファイルが常にjsに書き換えられるようにします。

"scripts": {
  "dev": "tsc -w",
	...
},

プラグインを実行してみる

作成したプラグインをクリックで起動します。

プラグインが起動します。

「Create」でオレンジの四角が5つ作成されます。
これでサンプル用のプラグインの説明はおわりです。

オリジナルプラグインを作るための基礎知識

プラグインを作成する上での基礎知識を学んでいきます。

ファイルの役割について

メインコードとui.htmlの役割について少し説明します。

参照: プラグインの実行方法

セキュリティの観点から、プラグインのメインコード(code.ts)は Figma のメインスレッドのサンドボックス内で実行されます。サンドボックス内は最小限の JavaScript 環境であり、XMLHttpRequest や DOM などのブラウザ API を直接利用できません

メインスレッドで利用可能な JavaScript/ブラウザ API のリストは、console.log(this)をプラグインの最初の行として実行することで確認できます。

UIは<iframe>内で展開されれ、HTML/JavaScript を記述し、ブラウザ API にアクセスすることができます。

簡単にいうと、Figmaのオブジェクトを操作するcode.tsは、FIgmaの操作のみに注力するイメージかもしれません。
その他の、外部のAPIをリクエストしたり、S3の画像にアクセスしたりするのはui.html側(code.ts以外)で行います。

メインコードとui用のhtmlはmanifest.jsonで定義します。

{
  "name": "MyPlugin",
  "id": "1322863451202320448",
  "api": "1.0.0",
  "main": "code.js", // ・・・これ
  "capabilities": [],
  "enableProposedApi": false,
  "editorType": ["figma", "figjam"],
  "ui": "ui.html", // ・・・これ
  "networkAccess": {
    "allowedDomains": [
      "https://picsum.photos"
    ]
  }
}

メインコードとUI側でのデータの受け渡し方法

メインコードとUIの連携にはpostMessage, onMessageを利用する。

UI からメインコードにメッセージを送る

// ui.html

<script>
...
parent.postMessage({ pluginMessage: 'post message' }, '*')
...
</script>
// code.ts

figma.ui.onmessage = (message) => {
  console.log(message)
}

メインコードから UI へのメッセージ送信

// code.ts

figma.ui.postMessage("message")
// ui.html

<script>
...
onmessage = (event) => {
  console.log(event.data.pluginMessage)
}
...
</script>

プラグインのUI(ダイアログ)を操作する

プラグインのUIを操作方法です。

// code.ts

figma.showUI(__html__, {
  visible: true, 
  width: 500,
  height: 500,
  position: { x: 0, y: 0 },
});
  • __html__
    プラグインのUIとして表示されるHTMLまたはJSXコードです。このコードがUIの構造やデザインを定義します。

  • visible
    UIを表示するかどうかを制御するプロパティです。
    デフォルト値はtrueです。

  • width
    UIの幅を指定するプロパティです。
    デフォルト値はundefinedです。プロパティを指定しない場合、UIは横幅を持たず、コンテンツに合わせて自動的にサイズが調整されます。

  • height
    UIの高さを指定するプロパティです。
    デフォルト値はundefinedです。プロパティを指定しない場合、UIは横幅を持たず、コンテンツに合わせて自動的にサイズが調整されます。

  • position
    UIの表示位置を指定するプロパティです

htmlファイルが2つ以上の場合

UIファイルのhtmlが複数ある場合はオブジェクトで指定し、定数は__uiFiles__を利用します。

// manifest.json
{
  "ui": {
			"ui1.html",
			"ui2.html",
	...
}
// code.ts

figma.showUI(__uiFiles__.ui1.html)


外部ドメインのファイルを利用する

UIファイルからS3などの外部ドメインにアクセスするには、manifest.jsonに許可するドメインを指定する必要があります。

この画像を表示する為には、networkAccess > allowedDomainsに許可するドメインを追加します。

{
	...
  "networkAccess": {
    "allowedDomains": [
      "https://picsum.photos/" // ・・・これ
    ]
  }
}

デバックする

Web開発と同じようにconsoleを利用してデバックすることができます。

Plugin > Development > Show/Hide consoleで開発者ツールを表示することができます。

mainコードの基礎知識

mainコード側を触るための基礎知識です。

Figmaのウィンドウの情報を取得

figma.viewportで、プラグインが表示されているFigmaエディタのビューポートに関する情報を提供するオブジェクトです。このオブジェクトには、表示されているエディタ領域に関する様々なプロパティが含まれています。

以下は、figma.viewportの主なプロパティについての簡単な説明です:

  • width
    エディタの幅を示すプロパティです。ピクセル単位で表示されます。

  • height
    エディタの高さを示すプロパティです。ピクセル単位で表示されます。

  • scale
    エディタのズームレベル、つまり表示倍率を示すプロパティです。通常、1.0が100%ズームを表します。

  • scrollX
    エディタの水平方向のスクロール位置を示すプロパティです。ピクセル単位で表示されます。

  • scrollY
    エディタの垂直方向のスクロール位置を示すプロパティです。ピクセル単位で表示されます

  • center.x
    ビューポートの中心の水平座標を示します。ピクセル単位で表されます。

  • center.y
    ビューポートの中心の垂直座標を示します。ピクセル単位で表されます。

例えば、要素を追加するときに、表示しているウィンドウの中央に配置したい場合は以下のような座標を指定します。

// code.ts

node.x = figma.viewport.center.x - {表示する要素の幅} / 2
node.y = figma.viewport.center.y - {表示する要素の高さ} / 2

メインコードで受け取れるイベント

figma.on("run", callback)

プラグインが実行されたときに呼び出されるイベントです。
このイベントは、プラグインが起動されるたびに初期化のための処理を実行するのに便利です。

// code.ts

figma.on("run", () => {
  console.log("プラグインが実行されました");
});

figma.on("drop", callback)

ユーザーがプラグインに対してファイルをドロップ(ファイルの配置)したときに呼び出されるイベントです。
このイベントは、ファイルがドロップされると発生します。 event パラメータには、ドロップされたファイルに関する情報が含まれています。

// code.ts

figma.on("drop", (event) => {
  console.log("ファイルがドロップされました:", event);
});

figma.on("documentchange", callback)

ユーザーがキャンバス上で変更を行ったときに、またはプラグインが変更を行ったときに発生します。

// code.ts

figma.on("documentchange", () => {
  console.log("ドキュメントが変更されました");
});

figma.on("selectionchange", callback)

選択されたノードが変更されたときに呼び出されるイベントです。
選択が変更されるたびに、指定したコールバック関数が実行されます。

// code.ts

figma.on("selectionchange", () => {
  console.log("選択が変更されました");
});

figma.on("currentpagechange", callback)

アクティブなページが変更されたときに呼び出されるイベントです。
ページが切り替わるたびに、指定したコールバック関数が実行されます。

// code.ts

figma.on("currentpagechange", () => {
  console.log("アクティブなページが変更されました");
});

figma.on("close", callback)

プラグインウィンドウが閉じられるときに呼び出されるイベントです。
プラグインが終了するときに実行されるコールバック関数を指定できます。

// code.ts

figma.on("close", () => {
console.log("プラグインウィンドウが閉じられました");
});

JSX API を使用して新しいノードを作成

この API を使用するには、以下の手順を実行する必要があります。

@figma/widget-typingsパッケージをインストールします。

npm install -D @figma/widget-typings

tsconfig.jsonにコンパイラ オプションを追加します。

{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "figma.widget.h",
    "jsxFragmentFactory": "figma.widget.Fragment",
         ...中略
  }
}

最後に当たり前ですが、JSXが利用できるようにコードのファイルの拡張子を.tsxにします

例 ) 画像を追加

// code.ts
  
figma.createNodeFromJSXAsync(
    <figma.widget.Image
      src="https://picsum.photos/200/300"
      width={300}
      height={300}
    />
  );

UIの基礎知識

ui側のコードを触るための基礎知識です。

UIを制御するためのメソッド

FigmaプラグインのUIを制御するためのメソッドです。

figma.ui.onmessage = (message) => { /* メッセージの処理 */ }

プラグインウィンドウがメッセージを受信したときに呼び出されるコールバック関数を設定します。プラグインスクリプトからメッセージを受信した際に、この関数が実行されます。

<script>
// ui.html
...
figma.ui.onmessage = (message) => {
  console.log("メッセージを受信しました:", message);
};
...
</script>

figma.ui.postMessage (message)

プラグインウィンドウとプラグインスクリプト間でメッセージを送信します。これを使用してデータをやり取りすることができます。

<script>
// ui.html
...
figma.ui.postMessage({ type: 'update', data: someData });
...
</script>

figma.ui.close ()

プラグインウィンドウを閉じます。プラグインが終了するときにこの関数を呼び出すことができます。

<script>
// ui.html
...
figma.ui.close();
...
</script>

figma.ui.show ()

プラグインウィンドウを表示します。

<script>
// ui.html
...
figma.ui.show();
...
</script>

figma.ui.hide ()

プラグインウィンドウを非表示にします。

<script>
// ui.html
...
figma.ui.hide();
...
</script>

figma.ui.resize (widht, height)

プラグインウィンドウのサイズを変更します。新しい幅と高さを指定します。

<script>
// ui.html
...
figma.ui.resize(300, 200);
...
</script>

figma.ui.reposition (x, y)

プラグインウィンドウの位置を変更するためのメソッドです。xy パラメータに新しい座標を指定します。

<script>
// ui.html
...
figma.ui.resize(0, 0);
...
</script>


その他

Reactを利用する

こちらのサンプルを参考にするのが良さそうです


プラグインの公開

プラグインを公開するには、Community画面の右上にある「Publish」を押し、作成したプラグインを選択して「Next」を押します。

必要情報と画像を登録してレビューにだします。

レビューに出すとリストに「In review」のタグが表示されます。
1日ほどで、レビューが終わり公開できました。

公開したものはこちら。

アプリ用に複数解像度用の画像を書き出しできるものです。
iOS用には自動でサフィックスを、Android用には解像度ごとにフォルダわけしてかきだされます。

https://www.figma.com/community/plugin/1322863451202320448

参考


この記事が気に入ったらサポートをしてみませんか?