9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptでキーボードを作る(Tone.js)

Posted at

Tone.jsというJavaScriptのライブラリがあることを知り、使ってみることにしました。
これを使うことで、ブラウザ上で音声の処理をするWeb Audio APIを簡単に活用できるようになるらしいです。

めちゃくちゃ簡単にですが、キーボードのようなものをブラウザで描画するところまで書きます。

ソースコード

とりあえず以下のようなコードを書いてみました。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Tone.js</title>
  <link rel="stylesheet" href="./index.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
  <script src="./index.js"></script>
</head>
<body>
  <p>キーボード</p>
  <!-- 鍵盤表示エリア -->
  <div id="keyboard" class="keyboard"></div>
</body>
</html>
index.css
.keyboard div {
  position: relative;
  width: 40px;
  height: 200px;
  float: left;
}

.keyboard button {
  position: absolute;
}

.white {
  background-color: #ffffff;
  border: 1px solid #c0c0c0;
  width: 40px;
  height:200px;
}

.black {
  background-color: #000000;
  border: 1px solid #c0c0c0;
  width: 30px;
  height: 120px;
  left: 25px;
  z-index: 1;
}
index.js
const synth = new Tone.Synth().toDestination();

window.onload = () => {
  drawKeyboard();
};

// 鍵盤の描画メソッド
const drawKeyboard = () => {
  // 鍵盤の生成(音階を表す文字列を配列に入れておきます)
  const musicalScaleArray = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
  let baseKey;
  // 1つ1つ鍵盤を作っていく作業
  for (let i = 0; i < 25; i++) {
    // 鍵盤をボタンとして作成する
    const key = document.createElement("button");
    // idに音階の情報を付与(スタートはC3になるようにしています)
    key.id = `key_${musicalScaleArray[i % musicalScaleArray.length]}${Math.floor(i / 12) + 3}`;

    // クリックしている間に音が出るという仕様にする
    key.onmousedown = play;
    key.onmouseup = stop;
    key.onmouseleave = stop;

    // 黒鍵が白鍵かによってデザインを変えるので、そのためのclassをそれぞれ付与
    if (musicalScaleArray[i % 12].indexOf("#") > -1) {
      // 黒鍵(#がついている)
      key.classList.add("black");
    } else {
      // 白鍵
      key.classList.add("white");
      baseKey = document.createElement("div");
    }
    baseKey.appendChild(key);
    document.getElementById("keyboard").appendChild(baseKey);
  }
};

// 音の再生
const play = async (e) => {
  await Tone.start();
  // 鍵盤のidから音階を取得
  const scale = e.target.id.split("_")[1];
  // 指定した音を再生する
  synth.triggerAttack(scale);
};

// 音の停止
const stop = async (e) => {
  synth.triggerRelease();
};

できた画面はこんな感じ

スクリーンショット 2023-04-15 094140.jpg

上で書いたコードについて簡単に解説していきます。

読み込み

CDNを利用してTone.jsを読み込んでいます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>

音源の作成

Synthを使って音源に接続します。

const synth = new Tone.Synth().toDestination();

音の再生・停止

作成したsynthについて、triggerAttackで音の再生の処理を、triggerReleaseで音の停止の処理を表すことができます。
(triggerReleaseは「停止」というよりは音の振幅を0にするようなイメージみたいですね。)

// C4など音階を指定してあげます
synth.triggerAttack("C4");
synth.triggerRelease();

今回は鍵盤をクリックすることでtriggerAttackを呼び出し音を再生、クリック終了時にtriggerReleaseが呼ばれて音が停止…というようにしています。

おわり

以上、Tone.jsを使ってみる記事でした。
実際に音の出ているところを動画にしてアップ…はできなかったので(Twitterを使用しなきゃいけないとかなんとか)、本当に音が出るか気になる方は今回のコードを参考に作ってみてください。
音は出るんです。本当です。

9
7
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
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?