SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

デザインに貢献できる開発者になろう! Figmaを通じたデザインの始め方

プログラミングでFigmaを操作しよう! —デザインにまつわる仕事を自動化する方法

デザインに貢献できる開発者になろう! Figmaを通じたデザインの始め方 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

プラグインについて

 次にプラグインの作り方を解説していきます。

 せっかくなので最近追加されたVariablesを操作するプラグインを作ってみましょう。

 初めに、ちょっと座学ですが、Figmaプラグインを作る際には「サンドボックススレッド」と「UI スレッド」の2つのコードが走る環境があり、開発していく時にはこれらを使い分けていくことが必要になります。

 UIを使わなくていいプラグインもありますが、UIが必要がなくても「UIスレッドでしか実行できない処理のために非表示で実行する」なんてこともあります。

Figmaプラグインを作る際の環境 引用:https://zenn.dev/ixkaito/articles/how-to-make-a-figma-plugin
Figmaプラグインを作る際の環境

 前者のサンドボックススレッドではFigmaのデータに触ることができます。対してUIスレッドでは、Figmaのデータには直接触れないですが、プラグインのUI(HTML+CSSで作る)の表示や、外部にリクエストを送ったり、ブラウザのAPIを使えたりします。

 それぞれ役割とアクセスできるデータ・APIが違うので、それぞれで必要なものを交換しつつプログラミングしていきます。

サンドボックスからUIへのデータの渡し方

 このように送ります。

figma.ui.postMessage({
    type: "event",
    data: "これを受け取って!",
});

 そしたらUI側ではonmessageという関数で受け取りを検知できます。

<html>
  <body>
    <script>
      onmessage = (event) => {
        if (event.data.pluginMessage.type === 'event') {
	  // これを受け取って! がログ出力
	  console.log(event.data.pluginMessage.data)
        }
      };
    </script>
  </body>
</html>

UIからサンドボックスへのデータの渡し方

 UIからはparent.postMessageという関数を使います。

<script>
  parent.postMessage({ pluginMessage: { type: "hoge", content: "aaaaa" } }, '*');
</script>

 そしてサンドボックスでは figma.ui.onmessage を使って通知を受け取ります。

export type MessageType = 'notify-something';

figma.ui.onmessage = (msg: { type: MessageType, content?: string }) => {
  if (msg.type === 'notify-something') {
    figma.notify('受け取ったぜ!');
    figma.closePlugin();
  }
};

 それぞれで何ができて何ができないのかを理解して適切なコーディングに繋げるのが肝要です!ぜひ覚えておきましょう。

 重要なスレッドたちについて確認したところで、次に実際にプラグインを作成してみましょう。

 プラグインを作り始める手段はいくつかあるのですが、最もベーシックなやり方としてはFigmaの中から作成することです。

 Figmaで何かしらのデザインファイルを開いて右クリックし、「プラグイン>開発>プラグインの新規作成」を選んでいくとミニマルなプロジェクトを作ることができます。

プラグインを作り方
プラグインを作り方

 今回は、最近会社でお手製のスタイルだったものをVariablesに付け替える必要があったので、それを自動化するために作ってみたプラグインを題材に紹介してみます。

 上記のFigmaのスターターは作成しただけだと、パッケージがインストールされていないので、まずはnpm installをしてください。

 またnpm scriptとしてbuildとwatchがあり、watchの方はファイルの変更を検知してリビルドしてくれるため便利なので、開発中はこちらを実行しましょう。

 ビルドしたプラグインはメニューバーのこちらのなんと表現すべきか分からないアイコンをクリックすると実行することができます。

ビルドしたプラグインの表示方法
ビルドしたプラグインの表示方法

 今回はスタイルをVariablesに置き換えたいので、以下の2つの処理を書いてみます。

  • Variables を取得
  • ページ内のnodeを全部見ていってスタイルが適用されていたら同じ名前の Vairable に付け替える

 まずは付け替える先の色のVariableを一通り取得します。

const COLLECTION_NAME = “colors”

const colorCollection = figma.variables.getLocalVariableCollections().find(collection => collection.name === COLLECTION_NAME)
if (!colorCollection) {
  figma.notify(COLLECTION_NAME + "が読み込まれていません", {error: true})
}

const colorVariables = colorCollection?.variableIds.map((variableId) => {
  return figma.variables.getVariableById(variableId)
})
function replaceStyleToVariable(node: SceneNode, style: BaseStyle | null, type: "fills" | "strokes") {
  if (!style || style.type !== "PAINT" || skipStyle(style.name)) return
  
  // Variable とスタイルの名前が同じ前提のコードですが、違う場合は適宜書き換える関数を書きましょう 
  const variable = colorVariables?.find(variable => variable?.name === style.name)
  if (!variable) {
    console.error("matching variable not found, style name: ", style.name)
    return
  }
  
  // 背景色を Variable に付け替えます
  if (type === "fills" && ("fills" in node) && Array.isArray(node.fills)) {
    const fillsCopy = [...node.fills]
    fillsCopy[0] = figma.variables.setBoundVariableForPaint(fillsCopy[0], 'color', variable)
    node.fills = fillsCopy
  }

  // ボーダーの色も Variable に付け替えます
  if (type === "strokes" && ("strokes" in node) && Array.isArray(node.strokes)) {
    const fillsCopy = [...node.strokes]
    fillsCopy[0] = figma.variables.setBoundVariableForPaint(fillsCopy[0], 'color', variable)
    node.strokes = fillsCopy
  }
}

// Figma の node はツリー状になっているため再帰的に呼び出します
function travarseNode(node: SceneNode) {
  if ("fillStyleId" in node && typeof node.fillStyleId === "string") {
    const style = figma.getStyleById(node.fillStyleId) as PaintStyle
    replaceToVariable(node, style, "fills")
  }

  if ("strokeStyleId" in node && typeof node.strokeStyleId === "string") {
    const style = figma.getStyleById(node.strokeStyleId) as PaintStyle
    replaceToVariable(node, style, "strokes")
  }

  if ("children" in node) {
    node.children.forEach(replaceStyleToVariable)
  }
}

// ページ全体のオブジェクトを渡します
replaceStyleToVariable(figam.currentPage)

 これだけのコードで全てのスタイルをVariablesに置き換えることができるようになりました! 人力でポチポチする苦労を考えると大事ですね...。

 今回はとりあえず最近ホットなVariablesを扱うものを書いてみましたが、それ以外にもFigma上に存在するものは大体読めたり、作れたりするのでぜひプラグインのAPIリファレンスも眺めてみてください。

次のページ
ウィジェットについて

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
デザインに貢献できる開発者になろう! Figmaを通じたデザインの始め方連載記事一覧

もっと読む

この記事の著者

seya(セヤ)

 Figma に詳しいフロントエンドエンジニア。NY州立大学 Stony Brook Computer Science 科卒業後、ソフトウェアエンジニアとして働き始める。フロントエンドエンジニアとして働く傍ら、エンジニアにとってもあらゆるメリットを持つ Figma に魅せられ、エンジニア目線でデザインプロセスの改善やデザインからコードへの自動化などを手がける。<Figma 公式グローバルカンファレンス「Figma Config 2022」登壇。Comm...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18364 2023/10/10 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング