🦔
Figma Plugin イメージと違う「PostMessage」と「messageイベント」を理解して、処理とUIで情報を橋渡しする
はじめに
FigmaのPluginを作成していく中で、名称と実際の動作イメージ勝ちがう概念がありました。
それが、「PostMessage」と「messageイベント」です。この概念について、簡単にまとめていこうと思います。
用語定義
- 処理 = code.ts
- UI = ui.html etc... 表示用のHTML側のScriptタグ
勘違いしていた点
名称から僕は以下のように、勝手なイメージを持っていました。
勘違いイメージ
「処理からpostMessageでUIに情報を送る」
しかし、実際にPluginを作っていくと、UIから処理に情報を渡したい状況も出てきました。
必要になって初めて自分の勘違いに気づきました。
実際は、以下が概念の理解として正解でした。
正解イメージ
「処理からもUIからも、postMessageで情報を投げることができて、処理もUIもmessageイベントでMessageを取得できる」
実際にMessage周りのコードの書き方
では、処理とUIそれぞれで、Messageを投げる・取得をどのように行うかを紹介します。
処理
メッセージをUIに送る
code.ts
/* figma限定を前提として */
if (figma.editorType === 'figma') {
︙
// postMessageよりも前に、UIを表示していないとErrorがThrowされる
figma.showUi(__html__)
︙
figma.ui.postMessage({type: "testMessage", body: "Hello World!"})
︙
}
メッセージをUIから受け取る
code.ts
/* figma限定を前提として */
if (figma.editorType === 'figma') {
︙
// おすすめは、Switch文
// 今回は1例だが、何個も増えてくると効果大
figma.ui.onmessage = message => {
switch (message.type) {
case 'inputHogeHoge':
console.log(message.body)
break
}
}
︙
}
UI
処理からメッセージを受け取る
ui.html
<main>
<p>My Plugin</p>
</main>
<script>
window.addEventListener("message", (event) => {
const message = event.data.pluginMessage
// こちらもSwitch文おすすめ
switch (message.type) {
case 'submitHogeHoge':
console.log(message.body) // Hello World!
break
}
})
</script>
処理にメッセージを送る
ui.html
<main>
<button onclick="submit()">送信!</button>
</main>
<script>
const submit = () => {
parent.postMessage({pluginMessage: {type: "submitHogeHoge", body: "hogehoge"}}, "*")
}
</script>
ポイント
処理とUIでは、型の共有ができません(UIは純粋なJS)。したがってやり取りするメッセージの形式を型では制御できません。
また、UIから処理へpostMessageする際のオブジェクトは、pluginMessage
というKeyに対してデータを定義する必要がありますが、処理からUIへpostMessageをする際は不要です。
まとめ
処理とUIでの双方向のデータのやりとりが理解できたことで、かなりスムーズに開発をすることができました。
関連記事
Discussion