LoginSignup
3
2

はじめに

FigmaのPluginを開発する際、Figma Pluginsでイベントを取得したいと思ったことはありますか?
この記事では、Figma Pluginsからイベントを取得する方法を解説します。

イベントを取得する構文

イベントを取得するには、以下のようにfigma.on() を使うことで、イベントを取得することができます。

figma.on(type: Type, callback:(event) => void)

/* 例 */
figma.on('drop', (event) => { /* イベントを取得した時に実行する処理 */ })

イベントを削除するには、figma.off() を使うことで、イベントを削除することができます。

figma.off(type: Type, callback:(event) => void)

/* 例 */
const fn = () => { /* イベントを取得した時に実行する処理 */ }
figma.on('drop', fn)
figma.off('drop', fn)

利用可能なイベント

利用できるイベントは以下の通りです。

  • figma.currentPage の値が変わった時
  • 現在のページで選択している要素が変更された時
  • ドキュメントが変更された時
  • テキストノードに入力しているときに定期的に発火する
  • Figma外のオブジェクトがキャンバスにドロップされた時
  • プラグインが閉じた時
  • プラグインが開始した時
  • スタイルが変更された時
  • タイマーが開始した時 (Figjamのみ)
  • タイマーが一時停止した時 (Figjamのみ)
  • タイマーが停止した時 (Figjamのみ)
  • タイマーが終了した時 (Figjamのみ)
  • タイマーが再開した時 (Figjamのみ)
  • タイマーの合計時間が変化した時 (Figjamのみ)

⚪︎ figma.currentPage の値が変わった時

figma.currentPage の値が変わった時に処理を行いたい時は、typeに 'currentpagechange' を指定します。

figma.on('currentpagechange', () => { /* 処理 */ })

⚪︎ 現在のページで選択している要素が変更された時

現在のページで選択している要素が変更された時に処理を行いたい時は、typeに 'selectionchange' を指定します。

figma.on('selectionchange', () => { /* 処理 */ })

⚪︎ ドキュメントが変更された時

ドキュメントが変更された時に処理を行いたい時は、typeに 'documentchange' を指定します。

figma.on('documentchange', (event) => { /* 処理 */ })

コールバックには、以下のようなインターフェースの DocumentChangeEvent が渡されます。

interface DocumentChangeEvent {
  documentChanges: DocumentChange[]
}

DocumentChangeEvent には、DocumentChangeの配列を持っており、DocumentChangeには、6種類あります。

  1. 'CREATE':ドキュメントにノードが作成された時
  2. 'DELETE':ドキュメントからノードが削除された時
  3. 'PROPERTY_CHANGE':ノードのプロパティが変更された時
  4. 'STYLE_CREATE':ドキュメントにスタイルが追加された時
  5. 'STYLE_DELETE':ドキュメントにスタイルが削除された時
  6. 'STYLE_PROPERTY_CHANGE':スタイルのプロパティが追加された時

以下のタイミングの時には、イベントが発火しないので、注意が必要です。

  • documentchange のコールバック内で、変更が行なった時
  • ❌ インスタンスが更新された時
  • ❌ スタイル変更によって、ノードが更新された時
sample.ts
/* 例 */
figma.on('documentchange', (event) => {
  for (const change of event.documentChanges) {
    switch (change.type) {
      case 'CREATE': /* 処理 */; break;
      case 'DELETE': /* 処理 */; break;
      ...
    }
  }
})

⚪︎ テキストノードに入力しているときに定期的に発火する

テキストノードに入力しているときに定期的に発火させたい時は、typeに'textreview' を指定します。

figma.on('textreview', (event) => {
    return new Promise((textReview) => {
      /* 処理 */ 
    })
  })

コールバックには、以下のようなインターフェースの TextReviewEvent が渡されます。
TextReviewEventtext はノードに入力したテキストです。

interface TextReviewEvent {
  text: string
}

また、'textreview'では、TextReviewRange の配列を解決する非同期処理を返す必要があります。
TextReviewRange は、以下のようなインターフェースで、エラーまたは提案としてマークされるテキストを表します。

type TextReviewRange = {
  start: number
  end: number
  suggestions: string[]
  color?: 'RED' | 'GREEN' | 'BLUE'
}
  • start:範囲内の最初の文字のインデックス
  • end:範囲の最後の文字のインデックス
  • suggestions:範囲の候補を表す文字列の配列
  • color:下線の色
sample.ts
figma.on('textreview', (event) => {
  return new Promise((textReview) => {

  const type: TextReviewRange = {
    start: 8,
    end: 9,
    suggestions: ["hoge", "huga"],
    color: 'RED'
  }

  textReview([type])
})

⚪︎ Figma外のオブジェクトがキャンバスにドロップされた時

Figma外のオブジェクトがキャンバスにドロップされた時、処理を行いたい時は、typeに 'drop' を指定します。

figma.on('drop', (event) => { /* 処理 */ })

コールバックには、以下のようなインターフェースの DropEvent が渡されます。

interface DropEvent {
  node: BaseNode | SceneNode
  x: number
  y: number
  absoluteX: number
  absoluteY: number
  items: DropItem[]
  files: DropFile[]
  dropMetadata?: any
}
  • node:着地したノード
    • キャンバス内のどこにも着地しなかった場合、ノードがロックされている場合、別のノードの親になれない場合は、PageNodeになる
  • xy:着地したノードの相対座標
  • absoluteXabsoluteY:着地したノードの絶対座標
  • DropItem:ドロップしたアイテムの非ファイルデータ型
    • text/html・text/uri-list など
  • DropFile:ドロップしたアイテムのファイルデータ型
    • image/pngなど

DropEventのitemsの DropItemDropFileは以下のようなインターフェースです。

interface DropItem {
  type: string // ドロップしたアイテムのファイルタイプ
  data: string
}

interface DropFile {
  name: string // ドロップしたアイテムのファイルネーム
  type: string // ドロップしたアイテムのファイルタイプ
  getBytesAsync(): Promise<Uint8Array> // ドロップしたアイテムのファイルサイズ
  getTextAsync(): Promise<string> // ドロップしたアイテムのUTF8エンコードされたテキスト
}

⚪︎ プラグインが閉じた時

プラグインが閉じた時に処理を行いたい場合は、typeに'close' を指定します。

このイベントは、figma.closePlugin() 関数によって、プラグインが閉じられる直前に発火します。
そのため、本当に必要な場合にのみ使用し、処理部分を最小のコードで実行する必要があります。

figma.on('close', () => { /* 処理 */ })

⚪︎ プラグインが開始した時

プラグインが開始した時に処理を行いたい場合は、typeに'run' を指定します。

figma.on('run', (event) => { /* 処理 */ })

コールバックには、以下のようなインターフェースの RunEvent が渡されます。

interface RunEvent {
  parameters?: ParameterValues
  command: string
}
  • parameters: 各パラメータに入力された値
  • commandfigma.command と同じだが、便宜上ここでも提供する

⚪︎ スタイルが変更された時

スタイルが変更された時に処理を行いたい時は、typeに'stylechange'を指定します。

figma.on('stylechange', (event) => { /* 処理 */ })

コールバックには、以下のようなインターフェースの StyleChangeEvent が渡されます。

interface StyleChangeEvent {
  styleChanges: StyleChange[]
}

StyleChangeEvent には、StyleChange の配列を持っており、StyleChange には3種類あります。

  1. 'STYLE_CREATE':ドキュメントにスタイルが追加された時
  2. 'STYLE_DELETE':ドキュメントからスタイルが削除された時
  3. 'STYLE_PROPERTY_CHANGE':スタイルのプロパティが変更された時

⚪︎ タイマーが開始した時 (Figjamのみ)

タイマーが開始した時に処理を行いたい場合、typeに'timerstart'を指定します。
このイベントは、ドキュメント内で誰かがタイマーを開始したときに実行されます。

figma.on('timerstart', () => { /* 処理 */ })

⚪︎ タイマーが一時停止した時 (Figjamのみ)

タイマーが一時停止した時に処理を行いたい場合、typeに'timerpause'を指定します。
このイベントは、実行中のタイマーが一時停止されたときに実行されます。

figma.on('timerpause', () => { /* 処理 */ })

⚪︎ タイマーが停止した時 (Figjamのみ)

タイマーが停止した時に処理を行いたい場合、typeに'timerstop'を指定します。
このイベントは、ドキュメント内で誰かがタイマーを開始したときに実行されます。

figma.on('timerstop', () => { /* 処理 */ })

⚪︎ 'timerdone':タイマーが終了した時 (Figjamのみ)

タイマーが終了した時に処理を行いたい場合、typeに'timerdone'を指定します。
このイベントは、タイマーが実行中で残り時間が 0 になると実行されます。

figma.on('timerdone', () => { /* 処理 */ })

⚪︎ タイマーが再開した時 (Figjamのみ)

タイマーが再開した時に処理を行いたい場合、typeに'timerresume'を指定します。
このイベントは、一時停止されたタイマーが再開されたときに実行されます。

figma.on('timerresume', () => { /* 処理 */ })

⚪︎ タイマーの合計時間が変化した時 (Figjamのみ)

タイマーの合計時間が変化した時に処理を行いたい場合、typeに'timeradjust'を指定します。
このイベントは、タイマーの合計時間が変化したときに実行されます。

figma.on('timeradjust', () => { /* 処理 */ })

まとめ

この記事では、Figma Pluginsからイベントを取得する方法を解説しました。

ぜひこの記事を参考にFigma Pluginsからイベントを取得してみてください。


最後まで読んでくださってありがとうございます!

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2