Skip to content

Instantly share code, notes, and snippets.

@thusmiley
Created July 17, 2021 00:27
Show Gist options
  • Save thusmiley/64c4fbd09461912f114c2cf2149a7b48 to your computer and use it in GitHub Desktop.
Save thusmiley/64c4fbd09461912f114c2cf2149a7b48 to your computer and use it in GitHub Desktop.
Drum Machine - freeCodeCamp (Solution)
//https://codepen.io/thudang211/full/ZEKLKOo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="style.css" />
<title>Drum Machine</title>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="./index.js"></script>
</body>
</html>
const clips = [
{
keyCode: 81,
keyTrigger: "Q",
id: "Heater-1",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3",
},
{
keyCode: 87,
keyTrigger: "W",
id: "Heater-2",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3",
},
{
keyCode: 69,
keyTrigger: "E",
id: "Heater-3",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3",
},
{
keyCode: 65,
keyTrigger: "A",
id: "Heater-4",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3",
},
{
keyCode: 83,
keyTrigger: "S",
id: "Clap",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
},
{
keyCode: 68,
keyTrigger: "D",
id: "Open-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3",
},
{
keyCode: 90,
keyTrigger: "Z",
id: "Kick-n'-Hat",
url: "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3",
},
{
keyCode: 88,
keyTrigger: "X",
id: "Kick",
url: "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3",
},
{
keyCode: 67,
keyTrigger: "C",
id: "Closed-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3",
},
];
function App() {
const [volume, setVolume] = React.useState(0.5);
const [display, setDisplay] = React.useState("");
const playRecording = () => {
let index = 0;
let recordArray = display.split(" ");
const interval = setInterval(() => {
const audio = document.getElementById(recordArray[index]);
audio.volume = volume;
audio.currentTime = 0;
audio.play();
index++;
}, 400);
};
return (
<div id="drum-machine">
<div id="display">
<h1>Drum Machine</h1>
{clips.map((clip) => (
<Pad
key={clip.id}
clip={clip}
volume={volume}
setDisplay={setDisplay}
/>
))}
<h1>{display}</h1>
</div>
<div className="record">
{display && (
<>
<button className="btn play" onClick={playRecording}>
Play
</button>
<button className="btn clear" onClick={() => setDisplay("")}>
Clear
</button>
</>
)}
</div>
<input
type="range"
step="0.01"
value={volume}
max="1"
min="0"
onChange={(e) => setVolume(e.target.value)}
className="vol form-range"
/>
<p>Volume: {Math.round(volume * 100)}</p>
</div>
);
}
function Pad({ clip, volume, setDisplay }) {
React.useEffect(() => {
document.addEventListener("keydown", handleKeyPress);
return () => {
document.removeEventListener("keydown", handleKeyPress);
};
}, []);
const handleKeyPress = (e) => {
if (e.keyCode === clip.keyCode) {
playSound();
}
};
const playSound = () => {
const audio = document.getElementById(clip.keyTrigger);
audio.currentTime = 0;
audio.volume = volume;
audio.play();
setDisplay((prev) => prev + clip.keyTrigger + " ");
};
return (
<div className="btn btn-secondary drum-pad" onClick={playSound}>
<audio id={clip.keyTrigger} src={clip.url} className="clip" />
{clip.keyTrigger}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("app"));
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500&display=swap')
$orange: #ff7f11
$yellow: #f4ff52
$purple: #c04cfd
$black: #262626
$green: #53ff45
*
margin: 0
padding: 0
box-sizing: border-box
body
background-color: $black
font-family: 'Montserrat', sans-serif
font-weight: bold
position: relative
h1
color: $orange
padding: 30px
font-size: 2em
p
color: $orange
font-size: 1em
.record > .play, .record > .clear
color: $black
background-color: $orange
padding: 3px 10px
font-size: 1em
margin: 0px 5px
min-width: 60px
#drum-machine
text-align: center
justify-content: center
align-items: center
position: relative
height: 100vh
width: 350px
margin-left: auto
margin-right: auto
.drum-pad
font-size: 3em
background-color: $purple
color: $black
border: none
margin: 2px
width: 100px
height: 80px
display: inline-block
cursor: pointer
.drum-pad:hover
background-color: $green
color: $orange
.vol
margin-top: 20px
cursor: pointer
width: 40%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment