awacke1's picture
Update index.html
99c2646 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chord Arpeggio Pad</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #121212;
color: #ffffff;
}
.container {
text-align: center;
}
.arpeggio-pad {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin-bottom: 20px;
}
.pad {
width: 80px;
height: 80px;
font-size: 14px;
border: none;
color: white;
cursor: pointer;
transition: all 0.3s;
border-radius: 8px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.pad:hover {
opacity: 0.8;
}
.pad:active, .pad.active {
transform: scale(0.95);
box-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
}
h1 {
margin-bottom: 20px;
}
#effectsButton {
font-size: 18px;
padding: 10px 20px;
background-color: #4CAF50;
border: none;
color: white;
cursor: pointer;
border-radius: 5px;
transition: background-color 0.3s;
}
#effectsButton:hover {
background-color: #45a049;
}
#effectsButton.active {
background-color: #e91e63;
}
</style>
</head>
<body>
<div class="container">
<h1>Chord Arpeggio Pad</h1>
<div class="arpeggio-pad" id="arpeggiopad"></div>
<button id="effectsButton">Effects: OFF</button>
</div>
<script>
const arpeggiopad = document.getElementById('arpeggiopad');
const effectsButton = document.getElementById('effectsButton');
const synth = new Tone.PolySynth(Tone.Synth).toDestination();
// Effects chain
const distortion = new Tone.Distortion(0.8).toDestination();
const reverb = new Tone.Reverb(2).toDestination();
let effectsOn = false;
const arpeggios = [
// C Major (I)
{ chord: 'C', notes: ['C4', 'E4', 'G4', 'C5'], color: '#FF0000' },
{ chord: 'C', notes: ['E4', 'G4', 'C5', 'E5'], color: '#FF4000' },
{ chord: 'C', notes: ['G4', 'C5', 'E5', 'G5'], color: '#FF8000' },
{ chord: 'C', notes: ['C5', 'E5', 'G5', 'C6'], color: '#FFC000' },
// F Major (IV)
{ chord: 'F', notes: ['F4', 'A4', 'C5', 'F5'], color: '#FFFF00' },
{ chord: 'F', notes: ['A4', 'C5', 'F5', 'A5'], color: '#C0FF00' },
{ chord: 'F', notes: ['C5', 'F5', 'A5', 'C6'], color: '#80FF00' },
{ chord: 'F', notes: ['F5', 'A5', 'C6', 'F6'], color: '#40FF00' },
// G Major (V)
{ chord: 'G', notes: ['G4', 'B4', 'D5', 'G5'], color: '#00FF00' },
{ chord: 'G', notes: ['B4', 'D5', 'G5', 'B5'], color: '#00FF40' },
{ chord: 'G', notes: ['D5', 'G5', 'B5', 'D6'], color: '#00FF80' },
{ chord: 'G', notes: ['G5', 'B5', 'D6', 'G6'], color: '#00FFC0' },
// Am (vi)
{ chord: 'Am', notes: ['A4', 'C5', 'E5', 'A5'], color: '#00FFFF' },
{ chord: 'Am', notes: ['C5', 'E5', 'A5', 'C6'], color: '#00C0FF' },
{ chord: 'Am', notes: ['E5', 'A5', 'C6', 'E6'], color: '#0080FF' },
{ chord: 'Am', notes: ['A5', 'C6', 'E6', 'A6'], color: '#0040FF' }
];
arpeggios.forEach(({ chord, notes, color }, index) => {
const pad = document.createElement('button');
pad.innerHTML = `${chord}<br>${notes[0]}-${notes[3]}`;
pad.className = 'pad';
pad.dataset.notes = JSON.stringify(notes);
pad.style.backgroundColor = color;
arpeggiopad.appendChild(pad);
});
function toggleEffects() {
effectsOn = !effectsOn;
if (effectsOn) {
synth.disconnect();
synth.connect(distortion);
synth.connect(reverb);
effectsButton.textContent = 'Effects: ON';
effectsButton.classList.add('active');
} else {
synth.disconnect();
synth.toDestination();
effectsButton.textContent = 'Effects: OFF';
effectsButton.classList.remove('active');
}
}
function playArpeggio(notes, pad) {
pad.classList.add('active');
const now = Tone.now();
notes.forEach((note, index) => {
synth.triggerAttackRelease(note, "8n", now + index * 0.2);
});
setTimeout(() => pad.classList.remove('active'), notes.length * 200);
}
arpeggiopad.addEventListener('mousedown', (e) => {
if (e.target.classList.contains('pad')) {
const notes = JSON.parse(e.target.dataset.notes);
playArpeggio(notes, e.target);
}
});
effectsButton.addEventListener('click', toggleEffects);
// Start audio context on user interaction
document.addEventListener('click', async () => {
await Tone.start();
console.log('Audio is ready');
}, { once: true });
</script>
</body>
</html>