簡易ピアノ(ソース)提出
<!DOCTYPE html>
<html lang=”ja”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>ピアノ鍵盤</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
#piano {
display: flex;
position: relative;
width: 700px;
margin: 20px auto;
}
.white-key {
position: relative;
display: inline-block;
width: 60px;
height: 200px;
background: white;
border: 1px solid black;
z-index: 1;
}
.white-key.active {
background: lightblue;
}
.black-key {
position: absolute;
width: 40px;
height: 120px;
background: black;
border: 1px solid black;
z-index: 2;
}
.black-key.active {
background: darkblue;
}
/* 黒鍵の位置を調整 */
.black-key[data-position=”1″] { left: 45px; }
.black-key[data-position=”2″] { left: 105px; }
.black-key[data-position=”4″] { left: 225px; }
.black-key[data-position=”5″] { left: 285px; }
.black-key[data-position=”6″] { left: 345px; }
</style>
</head>
<body>
<h1>ピアノ鍵盤</h1>
<p>キーボード:A,S,D,F,G,H,J,K(白健),W,E,T,Y,U(黒鍵)</p>
<p>矢印キーでオクターブ変更</p>
<div id=”piano”>
<!– 白鍵 –>
<div class=”white-key” data-key=”a” data-note=”261.63″>A</div>
<div class=”white-key” data-key=”s” data-note=”293.66″>S</div>
<div class=”white-key” data-key=”d” data-note=”329.63″>D</div>
<div class=”white-key” data-key=”f” data-note=”349.23″>F</div>
<div class=”white-key” data-key=”g” data-note=”392.00″>G</div>
<div class=”white-key” data-key=”h” data-note=”440.00″>H</div>
<div class=”white-key” data-key=”j” data-note=”493.88″>J</div>
<div class=”white-key” data-key=”k” data-note=”523.25″>K</div>
<!– 黒鍵 –>
<div class=”black-key” data-key=”w” data-note=”277.18″ data-position=”1″>W</div>
<div class=”black-key” data-key=”e” data-note=”311.13″ data-position=”2″>E</div>
<div class=”black-key” data-key=”t” data-note=”369.99″ data-position=”4″>T</div>
<div class=”black-key” data-key=”y” data-note=”415.30″ data-position=”5″>Y</div>
<div class=”black-key” data-key=”u” data-note=”466.16″ data-position=”6″>U</div>
</div>
<script>
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const keys = document.querySelectorAll(‘.white-key, .black-key’);
let octave = 0;
let recording = false;
let recordedNotes = [];
// 音を再生する関数
function playSound(frequency) {
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.type = ‘square’; // ここを ‘square’, ‘sawtooth’, ‘triangle’ などに変更
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.start();
gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.5);
oscillator.stop(audioContext.currentTime + 0.5);
}
// 鍵盤のハイライト
function highlightKey(keyElement) {
keyElement.classList.add(‘active’);
setTimeout(() => keyElement.classList.remove(‘active’), 200);
}
// 鍵盤クリックイベント
keys.forEach(key => {
key.addEventListener(‘click’, () => {
const frequency = parseFloat(key.dataset.note) * Math.pow(2, octave);
playSound(frequency);
highlightKey(key);
if (recording) {
recordedNotes.push({ frequency, time: audioContext.currentTime });
}
});
});
// キーボード入力イベント
document.addEventListener(‘keydown’, (event) => {
const key = event.key.toLowerCase();
const keyElement = document.querySelector(`[data-key=”${key}”]`);
if (keyElement) {
const frequency = parseFloat(keyElement.dataset.note) * Math.pow(2, octave);
playSound(frequency);
highlightKey(keyElement);
if (recording) {
recordedNotes.push({ frequency, time: audioContext.currentTime });
}
}
// オクターブ変更
if (key === ‘arrowup’) {
octave = Math.min(octave + 1, 3);
} else if (key === ‘arrowdown’) {
octave = Math.max(octave – 1, -2);
}
});
</script>
</body>
</html>