2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptAdvent Calendar 2024

Day 11

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

Posted at

はじめに

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

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

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

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

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

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

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

Canvas要素でGridを作ってみる4.gif

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

Canvas要素でGridを作ってみる2_1.gif

Canvas要素でGridを作ってみる2_2.gif

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の場合は、不要です。)

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

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

今回の成果物

ソース

DemoURL

まとめ

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

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

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

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

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?