「Tone.js」で88鍵ピアノ(HTML5 JavaScript Piano)を作ってみる
前回
1オクターブ+1鍵の13鍵ピアノを「Tone.js」で作ってみましたが、
これから模擬的にブログで音を鳴らすのに、1オクターブでは音域が狭いので、「Tone.js」を使い、88鍵のフルピアノ(HTML5 JavaScript Piano)を作ってみました。
こんな感じ。ブログのレイアウト上+鍵盤を1行で表示するには記事内のエリアだけでは幅が狭すぎるので、88鍵の鍵盤が自動改行されてますがご容赦を。
上の鍵盤は、以下のHTML + JavaScript + CSS からなっています。
<div> <ul id="piano"> </ul> </div> <style type="text/css"> <!-- ul { width: 100%; margin: 0 auto; padding: 0 0; position: relative; text-align: center; } li { display: inline-block; border: 1px solid black; height: 80px; } .whitekey { background: white; } .blackkey { background: black; position: absolute; margin: 0px 0 0px -10px; border-left: 2px solid white; border-bot: 2px solid white; } .whitekey:hover { background-color: #ddd; } .blackkey:hover { background-color: #555; } --> </style> <script src="http://chamu.org/tonejs/Tone.min.js"></script> <script> var synth; // ページ読み込み時pianoを生成 document.addEventListener("DOMContentLoaded", (e) => { // シンセサイザーを生成 synth = new Tone.Synth({ // 発振器の設定 oscillator:{ type:"triangle8" }, // エンベロープ(包絡線)の設定 envelope:{ attack:0.005, // 最大音量アタック・レベル(Attack Level)に達する時間 decay:0.1, // 一定音量まで減衰(Decay)する時間 sustain:0.4, // 一定振幅(Sustain Level)が続く時間 release:2 // 音が消えるまでの時間 } }).toMaster(); // 鍵盤を表示 const totalWidth = window.innerWidth; const height = 140; const allNotes = [ "A0", "A#0", "B0", "C1", "C#1", "D1", "D#1", "E1", "F1", "F#1", "G1", "G#1", "A1", "A#1", "B1", "C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2", "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5", "C6", "C#6", "D6", "D#6", "E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6", "C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7", "G#7", "A7", "A#7", "B7", "C8" ]; const sizePerNote = (totalWidth / allNotes.length)*1.5; const piano = document.getElementById('piano'); for (let i = 0; i < allNotes.length ; i++) { var currentNote = allNotes[i]; var node = document.createElement("li"); node.className = 'whitekey'; node.style.height = height + "px"; node.style.width = sizePerNote + "px"; if (~currentNote.indexOf("#")) { node.className = 'blackkey'; node.style.width = sizePerNote/1.6 + "px"; node.style.height = height/1.6 + "px"; } node.setAttribute('data-key', currentNote); piano.appendChild(node); } }); // 鍵盤でマウスが押されたら音を鳴らす document.querySelector('#piano').addEventListener('mousedown', e => { key = e.target.dataset.key synth.triggerAttackRelease(key); }) // 鍵盤で押されたマウスが離されたら音を消す document.querySelector('#piano').addEventListener('mouseup', e => { key = e.target.dataset.key synth.triggerRelease(); }) </script>