😗

[React] keyboardイベントを追加する

2021/12/09に公開

[React] keyboardイベントを追加する

概要

YouTubeなどで音量を調節したり、動画を検索したりするときに、keyboardを用いて情報を入力することが多くある。
なので、keyboardイベントを理解して、そのような実装に対応できるようにメモを残しておく。

例として、「オブジェクトの移動」をキーボードで行ってみる。

  • 「矢印」を入力したときに、対象のオブジェクトが現在の位置から5px動くように設計。
  • 「スペースキー」を入力したときに、対象のオブジェクトの色をランダムに変更するように設計。

screenshot

keyboardイベントの種類

  1. onKeyDown: キーが押されたときに発動。
  2. onKeyUp: キーを話したときに発動。
  3. onKeyPress: 文字や数字を入力するキーボードを押したときに発動。これはデバイス依存があり、廃止されたものなので、現在は使用を推奨されていない。

source code

// App.tsx
import React, { useState } from 'react';
import './App.css';

function App() {
  const [top, setTop] = useState(0);
  const [left, setLeft] = useState(0);
  const [backgroundColor, setBackgroundColor] = useState('#ffffff')

  const keyDownHandler = (e: React.KeyboardEvent<HTMLDivElement>) => {
    const key = e.code;

    if (key === 'ArrowUp') {
      setTop((top) => top - 10);
    }

    if (key === 'ArrowDown') {
      setTop((top) => top + 10);
    }

    if (key === 'ArrowLeft') {
      setLeft((left) => left - 10);
    }

    if (key === 'ArrowRight') {
      setLeft((left) => left + 10);
    }

    if (key === 'Space') {
      let color = Math.floor(Math.random() * 0xFFFFFF).toString(16);
      for(let count = color.length; count < 6; count++) {
        color = '0' + color;                     
      }
      setBackgroundColor('#' + color);
    }
  }

  return (
    <div
      className="container"
      tabIndex={0}
      onKeyDown={keyDownHandler}
    >
      <div
        className="box"
        style={{ 
          top: top,
          left: left,
          backgroundColor: backgroundColor,
        }}></div>
    </div>
  );
}

export default App;
.container {
  height: 100vh;
  width: 100vw;
}

.box {
  border: 1px solid black;
  height: 100px;
  position: fixed;
  width: 100px;
}

実装ポイント

  • オブジェクトの移動には、top, leftの座標位置で調整する。
  • 色の変更には、backgroundColorの変更で調整する。
  • 矢印キーを押すことで、その方向に移動するための値がセットされる。
  • spaceキーを押すことで、colorのhex6桁をランダムに生成し、colorを作成する。この際、単純にランダム生成すると、0が考慮されずに6桁にならない場合がある(例:#004455の場合、上2桁の00が省略されてしまう)。そうならないようにfor分を追加。
  • state管理はuseStateを使用。座標位置とcolorとを管理。
let color = Math.floor(Math.random() * 0xFFFFFF).toString(16);
for(let count = color.length; count < 6; count++) {
  color = '0' + color;                     
}
setBackgroundColor('#' + color);

reference

GitHubで編集を提案

Discussion