Canvas要素でGridを作ってみる#2


# はじめに

#2で(下記)、TaskのCreateの関数を実装した続きから行う。(全2記事を予定)

https://qiita.com/shisojuice/items/24a0ddeb2617d56102d4

# プロジェクトの作成(#1の続きから)

引き続き、Grid内のイベントを解説していく。

detailCellBlur関数ではFocusInputをBlurし、破棄する。

このとき、FocusInputのTextをCanvas内の該当Cellに反映させる。

```javascript:main.js

/**
 * Detail部のCellをBlurする関数です。
 */
const detailCellBlur = () => {
  last_focus_lbl = `col${focus_input.dataset.my_col}row${focus_input.dataset.my_row}`;
  const targetcontainer = app.stage.getChildByLabel(last_focus_lbl);
  if (targetcontainer) {
    targetcontainer.destroy({ children: true, texture: true, textureSource: true, context: true });
  }
  const container = createDetailCellContainer(focus_input.dataset.my_col, focus_input.dataset.my_row, focus_input.value);
  app.stage.addChild(container);
  focus_input.blur();
  focus_input.remove();
}

focus_input.addEventListener('blur', () => { detailCellBlur(); });

```

* Tabをおしたら＝＞方向にFocus移動、Tab＋Shiftで＜＝方向にFocus移動

![Canvas要素でGridを作ってみる3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/5fc96d41-3071-3a6c-74ed-2140d3e147c0.gif)

* 矢印キーの方向に応じてFocus移動

![Canvas要素でGridを作ってみる4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/55b71e9a-352a-5939-8dd4-0cc22ef7c05c.gif)

* 行or列の末端まで行ったらその行or列の反対側の末端にFocusを移動させる。

![Canvas要素でGridを作ってみる2_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/bfe6d4ec-e40f-3dbd-1155-10d42d7f63bc.gif)

![Canvas要素でGridを作ってみる2_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/ce4ba280-1e6c-adf5-cf3c-3ec96a433675.gif)

```javascript:main.js
focus_input.addEventListener('keydown', (e) => {
  const rowix = Number(e.target.dataset.my_row);
  const colix = Number(e.target.dataset.my_col);
  if (e.key == 'Tab' && e.shiftKey == false) {
    e.preventDefault();
    const next_rowix = Number(rowix + 1);
    const next_colix = Number(colix + 1);
    if (next_colix < colCount) {
      detailCellFocus(next_colix, rowix);
    } else {
      if (next_rowix < rowCount) {
        detailCellFocus(0, next_rowix);
      }
      else {
        detailCellFocus(0, 0);
      }
    }
  }
  if (e.key == 'Tab' && e.shiftKey == true) {
    e.preventDefault();
    const next_rowix = Number(rowix - 1);
    const next_colix = Number(colix - 1);
    if (next_colix >= 0) {
      detailCellFocus(next_colix, rowix);
    } else {
      if (next_rowix >= 0) {
        detailCellFocus(Number(colCount - 1), next_rowix);
      }
      else {
        detailCellFocus(Number(colCount - 1), Number(rowCount - 1));
      }
    }
  }
  if (e.key == 'ArrowLeft') {
    e.preventDefault();
    const next_colix = Number(colix - 1);
    if (next_colix >= 0) {
      detailCellFocus(next_colix, rowix);
    } else {
      detailCellFocus(Number(colCount - 1), rowix);
    }
  }
  if (e.key == 'ArrowRight') {
    e.preventDefault();
    const next_colix = Number(colix + 1);
    if (next_colix < colCount) {
      detailCellFocus(next_colix, rowix);
    } else {
      detailCellFocus(0, rowix);
    }
  }
  if (e.key == 'ArrowUp') {
    e.preventDefault();
    const next_rowix = Number(rowix - 1);
    if (next_rowix >= 0) {
      detailCellFocus(colix, next_rowix);
    }
    else {
      detailCellFocus(colix, Number(rowCount - 1));
    }
  }
  if (e.key == 'ArrowDown') {
    e.preventDefault();
    const next_rowix = Number(rowix + 1);
    if (next_rowix < rowCount) {
      detailCellFocus(colix, next_rowix);
    }
    else {
      detailCellFocus(colix, 0);
    }
  }
});

```

Canvas上でScrollしている際に、Focusが追従するようにイベントを付与する

(今回FocsuInputのcssがposition:fixedのため、absoluteの場合は、不要です。)

```javascript:main.js
/**
 * Detail部のCellFocusを追従する関数です。
 */
document.getElementById(canvas_id).addEventListener('scroll', (e) => {
  if (document.getElementById(canvas_id).contains(focus_input)) {
    requestAnimationFrame(() => {
      detailCellFocus(focus_input.dataset.my_col, focus_input.dataset.my_row);
    });
  }
});
```

![Canvas要素でGridを作ってみる2_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/c9f75d17-2be6-7245-ef76-3d61c3b43eee.gif)

まだまだ、微妙なところはありますが、完成！💪

# 今回の成果物

ソース

https://github.com/shisojuice/canvas_grid

DemoURL

https://shisojuice.github.io/canvas_grid/

# まとめ

全2記事でGridをPixiJSで実装してみた。

今回は100*100で行ったが、それ以上のCell数になる場合は、

処理が重たいので仮想スクロールなども必要になりそう😑、、、

時間があれば上記に引き続き仮想スクロールの実装もやってみたい💪