figmaを使用したデザインプロセスの自動化
重要になってくる機能
- デフォルトの機能
- コンポーネント Component= Atomic Design的な思想。
- ライブラリ = コンポーネントをまとめて配布する
- バリアンツ Variants = Component Setとも。複数あるコンポーネントを一つにまとめ、プロパティを付与できるようにしたもの
- 拡張のために提供されている機能
- ウィジェット Widget
- プラグイン Plugin
- API
Variantsの基本操作
WidgetとPluginの違い
参考になりそう(この手の先駆者)
色変換について
RGB -> HSB
-
色相を求める
- R・G・Bのうち、最も大きな値をMAX、最も小さな値をMINとして
- Rが最大値の場合色の相 H = 60 × ((G - B) ÷ (MAX - MIN))
- Gが最大値の場合色の相 H = 60 × ((B - R) ÷ (MAX - MIN)) +120
- Bが最大値の場合色の相 H = 60 × ((R - G) ÷ (MAX - MIN)) +240
- R・G・Bが同じ値の場合の色相 H = 0
-
彩度を求める
- R・G・Bのうち、最も大きな値をMAX、最も小さな値をMINとして
- 彩度 S = (MAX - MIN) ÷ MAX
-
明度を求める
- R・G・Bのうち、最も大きな値をMAXとして
- 明度 V = MAX
-
RGB -> CMYK
K = 1 - MAX(R・G・Bのうち、最も大きな値をMAXとして)
C = (1-R-K) ÷ (1- k)
M = (1-G-K) ÷ (1- k)
Y = (1-B-K) ÷ (1- k) -
RGB -> Pantone
- Pantone Connectなどの有料サービスを使用する形でしかその対応表にはアクセスできなくなってしまった。古いイラストレーターにはその情報が組み込まれていたらしいが、使用の可否についてはグレーなところ。
- Pantone APIも存在するが、組織単位で使用を申請し、有償で定期購買する形でしか使用できない。
-
RGB -> DIC ???
書いてみた:
上記の設定はRGB, CMYKの各値の範囲が0~1だったので、RGBは0~255, CMYKは0~100の範囲になるように修正している。
参考文献
技術選定の理由
figmaが他のデザインツールと比べてどう優れているのか
- Illustratorと比較して、特に「コンポーネント」の概念が強力である。マスターコンポーネントを複製した後、そのマスターコンポーネントに変更を加えると、他のコンポーネントも一括で見た目が変わる。ただし、child componentに特有の変更を加えていた場合、その変更が加えられたプロパティは上書きされない。そのため、たとえば吹き出しのようなものをマスターコンポーネントとして登録して、内側のテキストをそれぞれ固有に流し込んだ後で、そもそもの吹き出しのデザインを変えたくなった場合、Illustrator上では再度全部を複製しなおしてテキストを流し込む修正が必要であったが、Figma上ではマスターコンポーネントのみを修正すれば解決するようになっている。
- また、figmaで作成したUIデータは直ちにCSSやiOS、Android用のネイティブアプリに実装するためのコードに変換可能な機能がある。自分はこれまでデータ構造を度外視したスタイリングが実装されることにはならないかと懸念していたが、どうやらボタンやヒーロービューなど、コンテナ単位でコードを生成できる印象。最適化のためにコードレビューは必要だが、グラフィカルなインターフェースを設計し、実装することが容易くなった印象。
- さらに、figmaは基本的にオンラインで使用するため、人為的なファイルのコンフリクトが発生しない。最新バージョンではない気づかず編集し続けてしまったとか、最新バージョンを誰が持っているかわからない、といった事態を避けられるようになっている点が強力。
拡張機能
- プラグイン、ウィジェットといった拡張機能が充実している。このあたりを使ってあげるとあらゆるデザイン作業をジェネラティブに解決したり、高速化することができる。
- そしてwebフロントエンドのエンジニアにとって嬉しいのが、こうしたプラグインやウィジェットの作成機能が、html, CSS, js(ts, tsx)で記述されていること。
プラグイン作成ことはじめ
公式ドキュメントは通読したい
ウィジェット作成ことはじめ
これも読むと最強になれる
先行事例
LINEのデザインシステムであるLDSG準拠のデザインを簡単に生成することができるfigmaプラグイン。
▼ Guidance over governance - Jen Yee, Luca Orio (Schema 2021)
Widget作成のフロー
下準備
- エディタとして、VSCodeを使用。
- node.jsをインストール。
- ブラウザではWidget作成できないので、figmaのデスクトップ版をダウンロード。
Widget作成から実行まで
-
画面左上のfigmaアイコン > Widgets > Developments > New widget...を選択。
-
Figjam+Figma, またはFigma DesignのみのWidgetを作成するかを聞かれるので、いずれかを選択。ここではFigma Designを選択してNext.
-
高度なWidget設計をしたいなら一番右。iFrameを必要としない、widgetのインターフェースのみで動作が完結するようなものなら真ん中。フルスクラッチでやりたいなら一番左。ここでは右を選択。適当な名前をつけて、Save as.任意の場所に保存。
-
ターミナルで作成したWidgetのあるディレクトリへ移動。そこで
yarn install
を実行。 -
VSCodeでこのディレクトリを開き、Shift + Command + BもしくはRun > Run Build Task...を選択。
-
出てきたメニューから、「npm watch」を実行。
-
figmaに戻って、右クリック > Widgets > Development > 作成したWidgetを選択。ここまででWidgetの実行ができる。
UI設計
UI設計にこれを使おう
UIを作ったら、Plugins > Widget Code Generator を実行。
ただし、「cannot convert symbol to number」と表示されてWidget Code Generatorが実行できない状況がある。現在確認されているのは、Stroke設定である辺にのみStrokeを出力するような設定にした時にコードが生成できない、といったケース。
今後対応があるかもしれないが、取り急ぎ今はこういうデータを避けて、1px幅のRectangleなどを作って対処する。
ファイル分割
- widget-srcディレクトリの中にコンポーネントを定義する。
function ComponentName () {
/* something to do...*/
return (<></>);
}
export default ComponentName;
import ComponentName from 'pathToComponent';
...
よく叩きたくなるもの
- Widget UIの中にコンポーネントを追加する
- 繰り返し同じコンポーネントをリスト形式で出力したい、ということなら、コンポーネントを追加するという発想ではなく、それぞれのコンポーネントに持たせたいstateを増やしてあげて、それぞれのstateに対してコンポーネントを描画するようなmap処理で対処。
https://www.figma.com/widget-docs/working-with-lists
- 繰り返し同じコンポーネントをリスト形式で出力したい、ということなら、コンポーネントを追加するという発想ではなく、それぞれのコンポーネントに持たせたいstateを増やしてあげて、それぞれのstateに対してコンポーネントを描画するようなmap処理で対処。
- Widgetの座標を取得したい
- ベストプラクティスかわからないが、現在操作しているWidgetに付与されているIdを取得して、そのIdでカンバス内のNodeに検索をかけることでカンバス内におけるWidgetを取得する。
function Widget () {
...
const widgetId = widget.useWidgetId();
...
return (
...
const currentWidget = figma.getNodeById(widgetId) as WidgetNode;
console.log(currentWidget.x);
console.log(currentWidget.y);
...
);
}
- テキストボックスの中身を書き換える
- Inputコンポーネントを使う。Inputコンポーネントには、ユーザがテキストの編集を終えたタイミングで発火する
onTextEditEnd
コールバック関数が用意されているので、これでuseSyncedState
などを叩いてあげる。
https://www.figma.com/widget-docs/text-editing
- Inputコンポーネントを使う。Inputコンポーネントには、ユーザがテキストの編集を終えたタイミングで発火する
- iframeのサブウインドウはWidgetのUIを組むみたいに、GUIベースで骨格を作れないのかえ?
Widgetの中身をカンバス内のオブジェクトで更新したい
やってみたこと
- useSyncedStateを用いて更新したい部分を次のように定義し、FrameNodeの中身にボタンが押されたタイミングでAppendChildを実行して、Nodeを追加する。が、エラー。
const [logo, setLogo] = useSyncedState<FrameNode>("logo", <AutoLayout></AutoLayout>);
公開について
主な公開方法としては3パターンあって、
- 組織内で使用するプライベートプラグイン / ウィジェットを登録(有料)
- githubなどにプロジェクトをまるっと公開して、各々がそれをダウンロードしてくる形で使用
- 一般公開してしまう
ビジネスプラン以上だと、プライベートプラグイン / ウィジェット公開機能があるので公式推奨のやり方で言えばそれが一番手軽。ただし結構お高めなのでそこだけがネック。
githubで公開する形式は、各々がダウンロードしてマニュフェストファイルのパスを通してあげれば実行可能なので、フローさえ明確に示してしまえばセットアップはそれほど煩雑ではない。ただし、デフォルトでtsファイルがビルドされたものが格納されているdistディレクトリは、gitの監視下から外されているので、gitignoreから/dist
とcode.js
をコメントアウトする必要がある。
一般公開はそうした煩雑さもなく、秘匿にする必要もないプラグイン/ウィジェットなら一般公開でもいいのだけれど、そのためには審査を通す必要があるので、用途があまりに限定的だったりすると審査落ちする可能性がある。
Widget謎仕様、widgetのUIは編集ができない(色を変えたり、大きさを変えたり、書体を変えたりできない)