Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 23fcd50

Browse files
Added hip-hop auto drum notes
1 parent fd9c719 commit 23fcd50

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>JS Drum Kit</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
10+
<body>
11+
12+
13+
<div class="keys">
14+
<div data-key="65" class="key">
15+
<kbd>A</kbd>
16+
<span class="sound">clap</span>
17+
</div>
18+
<div data-key="83" class="key">
19+
<kbd>S</kbd>
20+
<span class="sound">hihat</span>
21+
</div>
22+
<div data-key="68" class="key">
23+
<kbd>D</kbd>
24+
<span class="sound">kick</span>
25+
</div>
26+
<div data-key="70" class="key">
27+
<kbd>F</kbd>
28+
<span class="sound">openhat</span>
29+
</div>
30+
<div data-key="71" class="key">
31+
<kbd>G</kbd>
32+
<span class="sound">boom</span>
33+
</div>
34+
<div data-key="72" class="key">
35+
<kbd>H</kbd>
36+
<span class="sound">ride</span>
37+
</div>
38+
<div data-key="74" class="key">
39+
<kbd>J</kbd>
40+
<span class="sound">snare</span>
41+
</div>
42+
<div data-key="75" class="key">
43+
<kbd>K</kbd>
44+
<span class="sound">tom</span>
45+
</div>
46+
<div data-key="76" class="key">
47+
<kbd>L</kbd>
48+
<span class="sound">tink</span>
49+
</div>
50+
</div>
51+
52+
<input type="button" value="Press Space Key"></input>
53+
54+
<audio data-key="65" src="sounds/clap.wav"></audio>
55+
<audio data-key="83" src="sounds/closedhat.wav"></audio>
56+
<audio data-key="68" src="sounds/kick.wav"></audio>
57+
<audio data-key="70" src="sounds/openhat.wav"></audio>
58+
<audio data-key="71" src="sounds/boom.wav"></audio>
59+
<audio data-key="72" src="sounds/ride.wav"></audio>
60+
<audio data-key="74" src="sounds/snare.wav"></audio>
61+
<audio data-key="75" src="sounds/tom.wav"></audio>
62+
<audio data-key="76" src="sounds/tinkbell.wav"></audio>
63+
64+
<script>
65+
66+
/************************************************************************************************
67+
GOAL: When a user opens this page and presses a key that corresponds with
68+
one of our div elements, we should play the audio clip associated with
69+
the keypress, add a class to the specific element that matches with the keypress,
70+
and then remove that class in order to reset the element to it's original state.
71+
**************************************************************************************************/
72+
73+
function removeTransition(e) {
74+
// Skip if it's not a transform event
75+
if (e.propertyName !== 'transform') return;
76+
e.target.classList.remove('playing');
77+
}
78+
79+
function playSound(e) {
80+
81+
// If space key is pressed then start the auto drum notes
82+
if (e.code === 'Space') {
83+
play();
84+
return;
85+
}
86+
87+
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
88+
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
89+
90+
// Stop function from running if key pressed doesn't match up with our elements data-key value
91+
if (!audio) return;
92+
key.classList.add('playing');
93+
94+
// Play sound clip from start every time a corresponding key is pressed
95+
audio.currentTime = 0;
96+
audio.play();
97+
}
98+
99+
// Find all elements in the document with a class 'key'
100+
const keys = Array.from(document.querySelectorAll('.key'));
101+
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
102+
window.addEventListener('keydown', playSound);
103+
104+
105+
/************************************************************************************************
106+
Play some auto drum notes
107+
************************************************************************************************/
108+
let playing = false;
109+
let interval;
110+
const totalSteps = 16;
111+
let currentStep = 1;
112+
let fullSteps = Array.from({ length: 16 }, () => []);
113+
const kick = 68;
114+
const hihat = 83;
115+
const snare = 74;
116+
const tink = 76;
117+
const openhat = 70;
118+
let bpm = 11; // increase or decrease this param to see change in beats per minute
119+
let count = 0;
120+
121+
// Toggle the play button and start/stop the audio based on current state
122+
function play(e) {
123+
if (playing) {
124+
stopAudio();
125+
} else {
126+
startAudio();
127+
}
128+
playing = !playing;
129+
}
130+
131+
// Play the instrument that is set for current step
132+
function playStep(step) {
133+
return Array.from(fullSteps[step]).map((keyCode) => playSound({ keyCode }));
134+
}
135+
136+
// Start the audio, if play button is clicked
137+
function startAudio() {
138+
interval = setInterval(() => {
139+
140+
// Add hihat after 2nd round
141+
if (++count === 16) {
142+
fullSteps = Array.from({ length: 16 }, () => []);
143+
createNotes(hihat, [1, 3, 5, 7, 9, 11, 13, 15]);
144+
createNotes(snare, [5, 10, 13]);
145+
createNotes(kick, [1, 11]);
146+
}
147+
if (count === 16 * 2) {
148+
fullSteps = Array.from({ length: 16 }, () => []);
149+
createNotes(hihat, [1, 3, 5, 7, 9, 11, 13, 15]);
150+
createNotes(snare, [5, 7, 13]);
151+
createNotes(kick, [1, 11]);
152+
}
153+
if (count === 16 * 3) {
154+
fullSteps = Array.from({ length: 16 }, () => []);
155+
createNotes(hihat, [1, 3, 5, 7, 9, 15]);
156+
createNotes(snare, [5, 10, 13]);
157+
createNotes(kick, [1, 11]);
158+
createNotes(tink, [11]);
159+
}
160+
if (count === 16 * 4) {
161+
currentStep = 1;
162+
count = 0;
163+
fullSteps = Array.from({ length: 16 }, () => []);
164+
createFullNotes();
165+
keys.forEach(key => key.classList.remove('playing'));
166+
}
167+
168+
playStep(currentStep - 1);
169+
currentStep = (currentStep < totalSteps) ? currentStep + 1 : 1;
170+
if (!playing) stopAudio();
171+
}, ~~(1500 / bpm));
172+
}
173+
174+
// Stop the audio, if stop button is clicked
175+
function stopAudio() {
176+
clearInterval(interval);
177+
currentStep = 1;
178+
count = 0;
179+
fullSteps = Array.from({ length: 16 }, () => []);
180+
createFullNotes();
181+
keys.forEach(key => key.classList.remove('playing'));
182+
}
183+
184+
// Create setup for what instrument needs to be played at what step
185+
function createNotes(instrument, steps) {
186+
return Array.from(steps).map((step) => {
187+
if (!Array.isArray(fullSteps[step - 1])) {
188+
fullSteps[step - 1] = [];
189+
}
190+
fullSteps[step - 1].push(instrument)
191+
});
192+
}
193+
194+
// Create all the notes needed to play the initial audio
195+
function createFullNotes() {
196+
createNotes(hihat, [1, 3, 5, 7, 9, 11, 13, 15]);
197+
createNotes(snare, [5, 7, 13]);
198+
createNotes(kick, [1, 11]);
199+
}
200+
201+
// Initialize the initial audio notes
202+
createFullNotes();
203+
</script>
204+
205+
206+
</body>
207+
208+
</html>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /