Skip to content

Commit 585b209

Browse files
Initial commit
0 parents  commit 585b209

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

index.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>Midi Piano</title>
5+
<script src="script.js" defer></script>
6+
<link rel="stylesheet" href="style.css">
7+
</head>
8+
<body>
9+
<h1>Midi Piano</h1>
10+
<div class="piano">
11+
<div data-note="C" class="key white"></div>
12+
<div data-note="Db" class="key black"></div>
13+
<div data-note="D" class="key white"></div>
14+
<div data-note="Eb" class="key black"></div>
15+
<div data-note="E" class="key white"></div>
16+
<div data-note="F" class="key white"></div>
17+
<div data-note="Gb" class="key black"></div>
18+
<div data-note="G" class="key white"></div>
19+
<div data-note="Ab" class="key black"></div>
20+
<div data-note="A" class="key white"></div>
21+
<div data-note="Bb" class="key black"></div>
22+
<div data-note="B" class="key white"></div>
23+
</div>
24+
</body>
25+
</html>

script.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const audioContext = new AudioContext()
2+
3+
const NOTE_DETAILS = [
4+
{ note: "C", key: "Z", frequency: 261.626, active: false },
5+
{ note: "Db", key: "S", frequency: 277.183, active: false },
6+
{ note: "D", key: "X", frequency: 293.665, active: false },
7+
{ note: "Eb", key: "D", frequency: 311.127, active: false },
8+
{ note: "E", key: "C", frequency: 329.628, active: false },
9+
{ note: "F", key: "V", frequency: 349.228, active: false },
10+
{ note: "Gb", key: "G", frequency: 369.994, active: false },
11+
{ note: "G", key: "B", frequency: 391.995, active: false },
12+
{ note: "Ab", key: "H", frequency: 415.305, active: false },
13+
{ note: "A", key: "N", frequency: 440, active: false },
14+
{ note: "Bb", key: "J", frequency: 466.164, active: false },
15+
{ note: "B", key: "M", frequency: 493.883, active: false },
16+
]
17+
18+
document.addEventListener("keydown", (e) => {
19+
if (e.repeat) return
20+
let keyPressed = e.code
21+
let nodesDetail = getNodeDetails(keyPressed)
22+
23+
if (nodesDetail == null) return
24+
nodesDetail.active = true
25+
26+
playNode()
27+
})
28+
29+
document.addEventListener("keyup", (e) => {
30+
let keyPressed = e.code
31+
let nodesDetail = getNodeDetails(keyPressed)
32+
if (nodesDetail == null) return
33+
nodesDetail.active = false
34+
playNode() //we run this function here to remove the class, we added on pressing keydown
35+
})
36+
37+
function getNodeDetails(keyboardKey) {
38+
return NOTE_DETAILS.find((n) => `Key${n.key}` === keyboardKey)
39+
}
40+
function playNode() {
41+
NOTE_DETAILS.forEach((n) => {
42+
let noteDiv = document.querySelector(`[data-note=${n.note}]`)
43+
noteDiv.classList.toggle("active", n.active) //if n.active become true then only set the class active --> this is what toggle does
44+
if (n.oscillator != null) {
45+
n.oscillator.stop()
46+
n.oscillator.disconnect()
47+
}
48+
})
49+
50+
const activeNode = NOTE_DETAILS.filter((n) => n.active)
51+
const gainValue = 1 / activeNode.length
52+
activeNode.forEach((n) => {
53+
startNode(n, gainValue)
54+
})
55+
}
56+
//From here we are going to introduce some function that doesn't mean anything
57+
//Check your understanding of everything we learn uptill here
58+
function startNode(activeNoteDetail, gain) {
59+
const gainNode = audioContext.createGain()
60+
gainNode.gain.value = gain
61+
62+
const oscillator = audioContext.createOscillator()
63+
oscillator.frequency.value = activeNoteDetail.frequency
64+
oscillator.type = "sine"
65+
oscillator.connect(gainNode).connect(audioContext.destination)
66+
oscillator.start()
67+
activeNoteDetail.oscillator = oscillator
68+
}

style.css

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
*, *::before, *::after {
2+
box-sizing: border-box;
3+
}
4+
5+
body {
6+
background-color: #143F6B;
7+
margin: 0;
8+
min-height: 100vh;
9+
display: flex;
10+
justify-content: center;
11+
align-items: center;
12+
flex-direction: column;
13+
}
14+
h1{
15+
font-family: Verdana, Geneva, Tahoma, sans-serif;
16+
font-size: 2.5rem;
17+
color: rgb(197, 181, 38);
18+
}
19+
.piano {
20+
display: flex;
21+
}
22+
23+
.key {
24+
height: calc(var(--width) * 4);
25+
width: var(--width);
26+
}
27+
28+
.white {
29+
--width: 100px;
30+
background-color: white;
31+
border: 1px solid #333;
32+
}
33+
34+
.white.active {
35+
background-color: #CCC;
36+
}
37+
38+
.black {
39+
--width: 60px;
40+
background-color: black;
41+
margin-left: calc(var(--width) / -2);
42+
margin-right: calc(var(--width) / -2);
43+
z-index: 2;
44+
}
45+
46+
.black.active {
47+
background-color: rgb(94, 94, 94);
48+
}

0 commit comments

Comments
 (0)