Illustratorの段組設定機能をFigmaで再現してみた。

# はじめに
こちらは[FigmaプラグインAdvent Calendar 2019](https://qiita.com/advent-calendar/2019/figma-plugin)の14日目の記事です。

今回はIllustratorなどで利用できる段組機能をFigmaで再現してみました。
なので、それを紹介していきたいと思います。

# 仕様
ワイヤーフレームを作るときに、この段組を使うことがあります。Illustratorにはこれを簡単にできる機能があるのですが、Figmaにはありません。

> 段組（だんぐみ）は、段を組むことを指す言葉で、特に紙などの印刷物やコンピュータ画面などにおいて2列以上の列に分けて文字や図などを配列することである。マルチカラム（もしくはコラム）デザインなどとも呼ばれる。
引用：[ウィキペディア（Wikipedia）](https://ja.wikipedia.org/wiki/%E6%AE%B5%E7%B5%84)

今回は大まかに行に対する数・高さ・間隔と列に対する数・幅・間隔を指定すると、それに応じた四角形を生成してくれるというものを作りました。
本来はもっとリッチな機能があるので、今後追加実装していきたいと思います！

# 今回実装したもの

行列情報を入力して『作成』を押すと、
<img width="890" alt="スクリーンショット 2019-12-14 21.04.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88234/d7d02701-107a-5fde-1d54-d77e9116ce2b.png">

入力した行列情報に沿った段組が作られる。
<img width="893" alt="スクリーンショット 2019-12-14 21.05.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88234/0309c507-2180-2fee-c6fe-a350f313a48b.png">


# コード
```code.ts
figma.showUI(__html__);

figma.ui.onmessage = msg => {
  if (msg.type === 'create-rectangles') {
    const nodes: SceneNode[] = [];
    
    for (let i = 0; i < msg.obj.lineCount; i++) {
      for (let j = 0; j < msg.obj.rowCount; j++) {
        const rect = figma.createRectangle();
        rect.resize(msg.obj.width, msg.obj.height);
        rect.x = j * (msg.obj.width + msg.obj.rowSpacing);
        rect.y = i * (msg.obj.height + msg.obj.lineSpacing);
        rect.fills = [{type: 'SOLID', color: {r: 0.1, g: 0.8, b: 0.7}}];
        figma.currentPage.appendChild(rect);
        nodes.push(rect);
      }
    }
    figma.currentPage.selection = nodes;
    figma.viewport.scrollAndZoomIntoView(nodes);
  }
  figma.closePlugin();
};
```

```ui.html
<h4>段組作成</h4>
<div class="main">
  <div class="container">
    <p>行</p>
    <p>行数: <input id="line-count" type="number" value="1"></p>
    <p>高さ: <input id="height" type="number" value="50"></p>
    <p>間隔: <input id="line-spacing" type="number" value="10"></p>
  </div>
  <div class="container">
    <p>列</p>
    <p>列数: <input id="row-count" type="number" value="1"></p>
    <p>幅: <input id="width" type="number" value="50"></p>
    <p>間隔: <input id="row-spacing" type="number" value="10"></p>
  </div>
</div>
<div class="button">
  <button id="create">作成</button>
  <button id="cancel">キャンセル</button>
</div>

<script>

document.getElementById('create').onclick = () => {
  const obj = {};
  obj.lineCount = parseInt(document.getElementById('line-count').value, 10);
  obj.height = parseInt(document.getElementById('height').value, 10);
  obj.lineSpacing = parseInt(document.getElementById('line-spacing').value, 10);
  obj.rowCount = parseInt(document.getElementById('row-count').value, 10);
  obj.width = parseInt(document.getElementById('width').value, 10);
  obj.rowSpacing = parseInt(document.getElementById('row-spacing').value, 10);
  parent.postMessage({ pluginMessage: { type: 'create-rectangles', obj } }, '*')
}

document.getElementById('cancel').onclick = () => {
  parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*')
}
</script>
<style>
  h4, p {
    margin: 0;
  }
  input {
    width: 50px;
  }
  .main {
    display: flex;
  }
  .container {
    width: 150px;
  }
  .button {
    margin: 20px 0;;
  }
  
</style>
```

# 解説
figma特有のことをしていないので、解説することがないのですが、、
## ui.htmlで取得したオブジェクトをcode.tsに渡す
入力値を受け取って、オブジェクトに詰めてpostMessageに含めることで、code.tsに渡しています。

```js
obj.lineCount = parseInt(document.getElementById('line-count').value, 10);
obj.height = parseInt(document.getElementById('height').value, 10);
obj.lineSpacing = parseInt(document.getElementById('line-spacing').value, 10);
obj.rowCount = parseInt(document.getElementById('row-count').value, 10);
obj.width = parseInt(document.getElementById('width').value, 10);
obj.rowSpacing = parseInt(document.getElementById('row-spacing').value, 10);
parent.postMessage({ pluginMessage: { type: 'create-rectangles', obj } }, '*')
```

## 取得した行列情報から、四角形を生成
取得した行列情報を使って、ループさせます。

```js
for (let i = 0; i < msg.obj.lineCount; i++) {
  for (let j = 0; j < msg.obj.rowCount; j++) {
    // 行列数分ループ
  }
}
```

ループ内で四角形のサイズと配置位置、色等を指定します。

```js
for (let i = 0; i < msg.obj.lineCount; i++) {
  for (let j = 0; j < msg.obj.rowCount; j++) {
    const rect = figma.createRectangle();
    rect.resize(msg.obj.width, msg.obj.height);
    rect.x = j * (msg.obj.width + msg.obj.rowSpacing);
    rect.y = i * (msg.obj.height + msg.obj.lineSpacing);
    rect.fills = [{type: 'SOLID', color: {r: 0.1, g: 0.8, b: 0.7}}];
    figma.currentPage.appendChild(rect);
    nodes.push(rect);
  }
}
```
# 終わりに
今回の実装までは、ほとんどFigmaプラグインの雛形を利用する形で作成することができました。
もう少し機能追加を目指して頑張ろうと思います！では！