Figmaプラグイン│ノードIDを取得する・選択するツール

レイヤーにはノードIDが割り当てられています。

そのIDを取得したり、選択したりできるプラグインを作りました。

複数レイヤーを一括選択もできます。

目次

Figmaプラグイン│ノードIDを取得する・選択するツール

別のプラグインでノードIDを出力することもあります。

場合によってFigmaのノードIDから選択することもあるので作りました。

コードは以下の通り。

manifest.json

{
  "name": "IDを取得・選択",
  "id": "select-by-id",
  "api": "1.0.0",
  "main": "code.js",
  "ui": "ui.html",
  "editorType": ["figma"]
}

code.js

// UI を表示
figma.showUI(__html__, { width: 350, height: 520 });

/** 余分な空白・末尾 :00 を取り除く(FigmaのIDコピペ差異に耐性) */
function normalizeId(rawId) {
  if (!rawId) return "";
  var id = String(rawId).replace(/\s+/g, ""); // 全空白削除(全角含む)
  id = id.replace(/:00$/, ""); // 末尾 :00 を除去
  return id.trim();
}

/** 生配列 → 正規化 → 空要素除去 → 重複排除 */
function toUniqueNormalizedIds(rawIds) {
  var seen = {};
  var result = [];
  if (!Array.isArray(rawIds)) return result;
  for (var i = 0; i < rawIds.length; i++) {
    var id = normalizeId(rawIds[i]);
    if (id && !seen[id]) {
      seen[id] = true;
      result.push(id);
    }
  }
  return result;
}

/** ID -> Node 変換(存在しないIDは無視) */
function nodesFromIds(ids) {
  var nodes = [];
  for (var i = 0; i < ids.length; i++) {
    var n = figma.getNodeById(ids[i]);
    // getNodeById は DocumentNode を返す可能性があるので SceneNode のみ許可
    if (n && "type" in n && "visible" in n) {
      nodes.push(n);
    }
  }
  return nodes;
}

/** 選択とズーム */
function selectAndReveal(nodes) {
  figma.currentPage.selection = nodes;
  if (nodes.length > 0) {
    try {
      figma.viewport.scrollAndZoomIntoView(nodes);
    } catch (e) {}
  }
}

/** UI からのメッセージ受け取り */
figma.ui.onmessage = function (msg) {
  if (!msg || typeof msg !== "object" || !("type" in msg)) return;

  if (msg.type === "select-by-id") {
    var inputIds = Array.isArray(msg.ids) ? msg.ids : [];
    var ids = toUniqueNormalizedIds(inputIds);
    var nodes = nodesFromIds(ids);

    if (nodes.length > 0) {
      selectAndReveal(nodes);
      figma.notify(nodes.length + "件のレイヤーを選択しました");
    } else {
      figma.currentPage.selection = [];
      figma.notify("有効なレイヤーIDが見つかりませんでした", { error: true });
    }
  }

  if (msg.type === "get-selected-ids") {
    var selected = figma.currentPage.selection;
    var lines = [];
    for (var i = 0; i < selected.length; i++) {
      var node = selected[i];
      lines.push(node.name + "\t" + node.id); // 「名前[TAB]ID」
    }
    figma.ui.postMessage({ type: "selected-ids", ids: lines });
  }
};

/** エディタ側で選択が変わったら UI に反映 */
figma.on("selectionchange", function () {
  var sel = figma.currentPage.selection;
  var lines = [];
  for (var i = 0; i < sel.length; i++) {
    lines.push(sel[i].name + "\t" + sel[i].id);
  }
  figma.ui.postMessage({ type: "selected-ids", ids: lines });
});

ui.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>ノードIDで選択</title>
    <style>
      body {
        font: 13px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Hiragino Sans", "Noto Sans JP", "メイリオ", sans-serif;
        margin: 12px;
      }
      textarea {
        width: 100%;
        height: 110px;
        box-sizing: border-box;
      }
      .row {
        margin: 10px 0;
      }
      .btn {
        padding: 8px 10px;
        border: 1px solid #ccc;
        background: #f7f7f7;
        cursor: pointer;
        border-radius: 6px;
      }
      .btn:active {
        transform: translateY(1px);
      }
      .muted {
        color: #666;
        font-size: 12px;
      }
      .grid {
        display: grid;
        grid-template-columns: 1fr auto;
        gap: 8px;
        align-items: center;
      }
      .stack {
        display: grid;
        gap: 8px;
      }
      hr {
        border: none;
        border-top: 1px solid #e5e5e5;
        margin: 14px 0;
      }
    </style>
  </head>
  <body>
    <div class="stack">
      <div class="row">
        <h3 style="margin: 0 0 8px">レイヤーIDで選択</h3>
        <textarea
          id="idsInput"
          placeholder="複数行にIDを貼り付けてください(例:I123:45)"
        ></textarea>
        <div class="grid">
          <span class="muted">各行を1つのIDとして処理します。</span>
          <button id="selectBtn" class="btn">選択</button>
        </div>
      </div>

      <hr />

      <div class="row">
        <h3 style="margin: 0 0 8px">現在の選択からID取得</h3>
        <div class="grid">
          <span class="muted">「名前 ID」形式で出力します。</span>
        </div>
        <textarea id="output" readonly></textarea>
        <div style="text-align: right">
          <button id="getBtn" class="btn">取得</button>
          <button id="copyBtn" class="btn">コピー</button>
        </div>
      </div>
    </div>

    <script>
      function splitLines(text) {
        return text.split(/\r?\n/);
      }
      function post(type, payload) {
        parent.postMessage(
          { pluginMessage: Object.assign({ type: type }, payload || {}) },
          "*"
        );
      }

      document.getElementById("selectBtn").onclick = function () {
        var raw = document.getElementById("idsInput").value;
        var ids = splitLines(raw);
        post("select-by-id", { ids: ids });
      };

      document.getElementById("getBtn").onclick = function () {
        post("get-selected-ids", {});
      };

      document.getElementById("copyBtn").onclick = function () {
        var text = document.getElementById("output").value;
        if (!text) {
          alert("コピーする内容がありません");
          return;
        }
        // Clipboard API(Figmaデスクトップ/ブラウザ双方で動作)
        navigator.clipboard.writeText(text).then(
          function () {
            alert("コピーしました");
          },
          function () {
            // フォールバック
            var ta = document.getElementById("output");
            ta.focus();
            ta.select();
            try {
              document.execCommand("copy");
              alert("コピーしました");
            } catch (e) {
              alert("コピーに失敗しました");
            }
          }
        );
      };

      // プラグイン本体からのメッセージ受信
      window.onmessage = function (event) {
        var msg =
          event.data && event.data.pluginMessage
            ? event.data.pluginMessage
            : null;
        if (!msg) return;
        if (msg.type === "selected-ids" && msg.ids) {
          document.getElementById("output").value = msg.ids.join("\n");
        }
      };
    </script>
  </body>
</html>

実際に使ってみましょう。

サービス

Service

デザイン制作に関心がありましたら、ぜひ詳細をご覧ください。

  • URLをコピーしました!
目次