Figmaでテキスト情報を取得するプラグインを作成する

以前に投稿したFigmaのプラグインを作成する記事の内容を踏まえて、Figmaのページ内のテキスト情報を取得するプラグインを作成してみます。

サンプルコード

Figmaプラグインの作成方法自体は、以前投稿したFigmaのプラグインを作成する記事をご確認ください。
今回はプラグイン起動時に一回だけ実行されるようにします。

code.tsの内容を以下のように変更します。

// 使用しているフォント情報の保存先
const fontUsageMap = new Map<
  string,
  {
    styles: Set<string>;
    sizes: Set<number>
  }
>();
// フォントの読み込み状況管理用
const loadedFonts = new Set<string>();

/**
 * 指定したノードツリーの中からすべてのテキストノードを取得
 */
function collectAllTextNodes(node: SceneNode): TextNode[] {
  const results: TextNode[] = [];

  // ノードの種類がテキストノードの場合は取得
  if (node.type === 'TEXT') {
    results.push(node);
  }

  // 対象のノードに下層がある場合同様に取得
  if ('children' in node) {
    for (const child of node.children) {
      results.push(...collectAllTextNodes(child));
    }
  }

  return results;
}

(async () => {
  try {
    // 対象のテキストノードの格納先
    const allTextNodes: TextNode[] = [];
    // 現在のページ取得
    const currentPage = figma.currentPage;

    // 現在のページ内すべてのノードを対象にテキストノードを取得
    for (const node of currentPage.children) {
      allTextNodes.push(...collectAllTextNodes(node));
    }

    // 取得した各テキストノードのフォント情報の調査
    for (const textNode of allTextNodes) {
      // フォントが見つからない場合 または テキストノード内にテキストがない場合はスキップ
      if (textNode.hasMissingFont || !textNode.characters) continue;

      // 現在のテキストノードのテキストを1文字ずつ調査
      for (let i = 0; i < textNode.characters.length; i++) {
        let fontName: FontName;
        let fontSize: number;

        try {
          // 対象の1文字のフォント情報と文字サイズを取得
          fontName = textNode.getRangeFontName(i, i + 1) as FontName;
          fontSize = textNode.getRangeFontSize(i, i + 1) as number;
        } catch {
          continue;
        }

        const fontKey = `${fontName.family}-${fontName.style}`;
        // まだ読み込まれていないフォントの場合はロード
        if (!loadedFonts.has(fontKey)) {
          try {
            await figma.loadFontAsync(fontName);
            loadedFonts.add(fontKey);
          } catch {
            continue;
          }
        }

        // 対象の1文字のフォントファミリーとウェイトを取得
        const family = fontName.family;
        const style = fontName.style;

        // 管理用のMapオブジェクトにまだ追加していないフォントファミリーの場合、要素を追加
        if (!fontUsageMap.has(family)) {
          fontUsageMap.set(family, {
            styles: new Set<string>(),
            sizes: new Set<number>(),
          });
        }

        // 該当のフォントファミリーにウェイトとフォントサイズを追加
        const entry = fontUsageMap.get(family)!;
        entry.styles.add(style);
        entry.sizes.add(fontSize);
      }
    }

    // Mapオブジェクトを連想配列形式に変換
    const result = Array.from(fontUsageMap.entries()).map(
      ([family, { styles, sizes }]) => ({
        family,
        weight: Array.from(styles),
        size: Array.from(sizes).sort((a, b) => a - b),
      })
    );
    // 結果の出力
    console.log("フォント使用データ:", result);

    // 処理終了の通知とプラグインの終了
    figma.notify("フォント使用情報を収集しました(コンソールを確認)");
    figma.closePlugin();

  } catch (error) {
    console.error("エラー:", error);
    figma.notify("エラーが発生しました。コンソールをご確認ください。");
    figma.closePlugin();
  }
})();

基本的にはコメントに書いている通りですが、テキスト情報を取得する際の注意が3点あります。

1点目が1つのテキストノード内に複数のフォントや文字サイズが使われている可能性がある(混合スタイルの考慮)点です。
そのため上記コードでは、テキストノード内の1文字ずつに対してフォントや文字サイズのチェックを行っています。(50行目~)

2点目がフォントの読み込みで、フォント情報を取得する際、取得する前にフォントの読み込みを行う必要があります。
フォントの読み込みはloadFontAsync()で行います。(67行目)

3点目がフォントがあるかどうかの確認で、フォントを読み込む前にtext.hasMissingFontでフォントがあるかを確認する必要があります。(48行目)

これで現在のページ内で使用されているフォントと文字サイズを取得する処理が実装できました。
今回は最終的な出力をconsoleにしましたが、UIを用意した上でそこに出力するなどでもよいかもしれません。

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

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年11月
 1
2345678
9101112131415
16171819202122
23242526272829
30