💎

デザイナーがFigmaプラグインを作った話 (Assign Color Value to Textの紹介)

2022/02/06に公開

TL;DR

Assign Color Value to TextというFigmaプラグインを作りました。

https://www.figma.com/community/plugin/1040245744043159776/Assign-Color-Value-to-Text

選択中のフレームの色名をテキストに自動的に入れてくれるプラグインです。
コードはこちらです。
https://github.com/Qs-F/figma-assign-color-value-to-text

Figmaだと、デザイナーがコードを書けるならあと一歩足りない部分にすぐ手が届くので大変便利で良いですね ✨

プラグイン自体の紹介

こんにちは、たふみです 🙌
デザインをしていると、

こういう色の一覧的なものを作りたくなるときがあります。
FigmaだとColor Styleとして定義できるので必要ないといえば必要ないのですが、メモを付けたり、一覧性を高めたり、なんやかんやで持っているチームも多いことと思います。

そして、このスクリーンショットのようなブロックは、実は意外と作るのが面倒です。
色を決めたら、その色の Hex 値や HSL の値をコピーしてきて、テキストにポチポチ貼らなければなりません。
Figmaではコマンドキーを押しながらクリックするとネストされたテキストノードをクリックしやすいことを覚えれば多少は楽になりますが、これが結構辛い単純作業で、特にカラーパレットを作る時のように数が多くなると大変です。

これをどうにか作りやすく改善できないかと考え、私が作ったのが上記のFigmaプラグイン「Assign Color Value to Text」です。

https://www.figma.com/community/plugin/1040245744043159776/Assign-Color-Value-to-Text

上の画像に示したように、使うにはテキストノードに$hex$rgb などといった特殊な名前をつけることが必要です。

使い方は、

  1. 代入したい色でfillされたフレームを用意する
  2. その中に $hex$rgb などの名前のついたテキストノードを入れる
  3. フレームを選択した状態で、プラグインを走らせる
  4. テキストノードの値が指定した表記での選択したフレームの色名になる

ネストされていてもきちんと動きます。
またフレームを複数選択した状態でもきちんとそれぞれについて動きます。

ただし代入されるのは選択中のフレームの色なので、そこは気をつけてください。

コードの説明

コードはこちらに公開してあります。

https://github.com/Qs-F/figma-assign-color-value-to-text

ビルドには全面的に流行りのViteを採用しました。
全面的に、というのは、FigmaはUI部分とプラグインのロジックでコードを分割する必要があり、Viteのconfigも2つ作り、それぞれで実行しています。。
詳しくは ここ に書いてありますが、そもそもUIとロジックは実行されるスレッドが異なります。
そのためUIとプラグインのロジックで値をやり取りするにはpostMessageを介して通信する必要があります。

(UIにはJavaScriptももちろん使えるので、ReactでプラグインのUIを構築することも可能です。今回はUIが結果的に必要なかったので使っていませんが、実際使えるように用意してあるので興味がある方は覗いてみてください。)

私の場合、 src/code.ts にはプラグインのロジックのエントリーポイントを、 src/index.html にはUIのエントリーポイントをおいています。それぞれでViteを走らせています。

それぞれ成果物は1ファイルにbundleされいる必要があるので、Viteではプラグインを使ってこれを果たしています。

TypeScriptの導入について、figma/plugin-typings には

{
    "compilerOptions": {
        "typeRoots": [
            "./node_modules/@types",
            "./node_modules/@figma"
        ]
    }
}

と書いてあるのですが、typeRoots が動かないためか動かなかった記憶がある (別の問題だったかもしれません) ので、

{
    "types": [
      "@figma/plugin-typings/index"
    ]
}

こうしておくのがおすすめです。対象コードはここにあります。

あとは特別難しいことは無いと思いますが、今回のプラグインでは選択中のフレームの色を取得したあと、DFSで対象のテキストノードを探索し、見つかったらテキストに代入しています。
この代入する時にFigmaでは対象ノードで使っているすべてのフォントが読み込まれている必要があり、そこが少し引っかかりポイントです。
私はこんな感じに解消しています。

const apply = async (node: TextNode, text: string): Promise<boolean> => {
  await Promise.all(
    node.getRangeAllFontNames(0, node.characters.length).map(async (font) => {
      await figma.loadFontAsync(font)
    })
  )
  node.characters = text
  return true
}

裏話として、最初は一番近い親で色を持っているフレームの色を代入しようと思ったのですが、一番上にあったようなカラーブロックで、テキストを白色のフレームの中に置くことで白系の色を示すときもテキストの色を買えずに見やすくするパターンなどもあり、どうするのが一番ベストかやってみた結果、今の選択中のフレームの色を代入する方法に落ち着きました。

ぜひ使ってみてください。感想、いいね、コメント、PR、機能リクエストお待ちしています。

おわり

Discussion