Just lay out your beat and press "Q, W, E or R" for live sample playback!
by [Jacob Kucera & Jon Solomon] on CodePen.
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Drum Sequencer</title> | |
<link rel="stylesheet" href="./style.css"> | |
<link rel="icon" type="image/png" href="./favicon.png"> | |
</head> | |
<body> | |
<div class="container"> | |
<div id="p0"> | |
<p class="drum-name">KICK</p> | |
<p class="drum-name">CLAP</p> | |
<p class="drum-name">HIHAT</p> | |
<p class="drum-name">RIM</p> | |
</div> | |
<div id="controls"> | |
<div id="controls-left-side"> | |
<div class="sampler" id="sampler1">Q</div> | |
<div class="sampler" id="sampler2">W</div> | |
<div class="sampler" id="sampler3">E</div> | |
<div class="sampler" id="sampler4">R</div> | |
</div> | |
<div id="controls-right-side"> | |
<p id="bpm">130 BPM</p> | |
<input type="range" min="30" max="200" value="130" id="bpm-slider"> | |
<p id="clear-track">CLEAR</p> | |
</div> | |
</div> | |
<div class="sequencer"> | |
<div class="d1"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d2"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d3"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d4" id="d-split"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d5"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d6"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d7"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d8" id="d-split"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d9"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d10"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d11"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d12" id="d-split"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d13"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d14"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d15"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
<div class="d16"> | |
<div class="sample" data-sample="kick.wav"></div> | |
<div class="sample" data-sample="clap.wav"></div> | |
<div class="sample" data-sample="hihat.wav"></div> | |
<div class="sample" data-sample="rim.wav"></div> | |
</div> | |
</div> | |
</div> | |
<script src="./app.js"></script> | |
</body> | |
</html> |
const rows = document.querySelector(".sequencer").children; | |
const kick = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/kick.mp3"), | |
clap = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/clap.mp3"), | |
hihat = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/hihat.mp3"), | |
rim = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/rim.mp3"), | |
Q = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/Q.mp3"), | |
W = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/W.mp3"), | |
E = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/E.mp3"), | |
R = new Audio("https://raw.githubusercontent.com/kucerajacob/DRUM-SEQUENCER/master/audio/R.mp3"); | |
const item = document.querySelectorAll(".sample"); | |
// Checkbox toggle functionality | |
item.forEach(function (el) { | |
el.onclick = function () { | |
if (el.classList.contains("item-selected")) { | |
el.classList.remove("item-selected"); | |
} else { | |
el.classList.add("item-selected"); | |
} | |
} | |
}); | |
// Clear button functionality | |
document.getElementById("clear-track").onclick = function () { | |
[].forEach.call(item, function (el) { | |
el.classList.remove("item-selected"); | |
}); | |
} | |
// Sample pad key press functionality | |
document.onkeydown = function (e) { | |
e = e || window.event; | |
switch (e.key) { | |
case "q": | |
Q.load(); | |
Q.play(); | |
document.getElementById("sampler1").classList.add("pressed"); | |
break; | |
case "w": | |
W.load(); | |
W.play(); | |
document.getElementById("sampler2").classList.add("pressed"); | |
break; | |
case "e": | |
E.load(); | |
E.play(); | |
document.getElementById("sampler3").classList.add("pressed"); | |
break; | |
case "r": | |
R.load(); | |
R.play(); | |
document.getElementById("sampler4").classList.add("pressed"); | |
break; | |
} | |
} | |
document.onkeyup = function (e) { | |
e = e || window.event; | |
switch (e.key) { | |
case "q": | |
// Q.pause(); | |
// Q.currentTime = 0; | |
document.getElementById("sampler1").classList.remove("pressed"); | |
break; | |
case "w": | |
// W.pause(); | |
// W.currentTime = 0; | |
document.getElementById("sampler2").classList.remove("pressed"); | |
break; | |
case "e": | |
// E.pause(); | |
// E.currentTime = 0; | |
document.getElementById("sampler3").classList.remove("pressed"); | |
break; | |
case "r": | |
// R.pause(); | |
// R.currentTime = 0; | |
document.getElementById("sampler4").classList.remove("pressed"); | |
break; | |
} | |
} | |
// BPM slider | |
const bpmSlider = document.getElementById("bpm-slider"); | |
const bpmText = document.getElementById("bpm"); | |
var BPM = bpmSlider.value; | |
bpmText.innerHTML = bpmSlider.value + " BPM"; | |
bpmSlider.oninput = function () { | |
bpmText.innerHTML = this.value + " BPM"; | |
BPM = parseInt(((60 / bpmSlider.value) * 1000) / 4); | |
} | |
let i = -1; | |
rowLoop = () => { | |
setTimeout(function () { | |
i++; | |
if (i === rows.length) { | |
i = 0; | |
document.querySelector(".d16").childNodes[1].classList.remove("row-highlight"); | |
document.querySelector(".d16").childNodes[3].classList.remove("row-highlight"); | |
document.querySelector(".d16").childNodes[5].classList.remove("row-highlight"); | |
document.querySelector(".d16").childNodes[7].classList.remove("row-highlight"); | |
} | |
document.querySelector(".d" + (i + 1)).childNodes[1].classList.add("row-highlight"); | |
document.querySelector(".d" + (i + 1)).childNodes[3].classList.add("row-highlight"); | |
document.querySelector(".d" + (i + 1)).childNodes[5].classList.add("row-highlight"); | |
document.querySelector(".d" + (i + 1)).childNodes[7].classList.add("row-highlight"); | |
if (i > 0) { | |
document.querySelector(".d" + i).childNodes[1].classList.remove("row-highlight"); | |
document.querySelector(".d" + i).childNodes[3].classList.remove("row-highlight"); | |
document.querySelector(".d" + i).childNodes[5].classList.remove("row-highlight"); | |
document.querySelector(".d" + i).childNodes[7].classList.remove("row-highlight"); | |
} | |
document.querySelectorAll(".d" + (i + 1)).forEach(function (bruh) { | |
if (bruh.childNodes[1].classList.contains("row-highlight") && bruh.childNodes[1].classList.contains("item-selected")) { | |
kick.load(); | |
kick.play(); | |
} | |
if (bruh.childNodes[3].classList.contains("row-highlight") && bruh.childNodes[3].classList.contains("item-selected")) { | |
clap.load(); | |
clap.play(); | |
} | |
if (bruh.childNodes[5].classList.contains("row-highlight") && bruh.childNodes[5].classList.contains("item-selected")) { | |
hihat.load(); | |
hihat.play(); | |
} | |
if (bruh.childNodes[7].classList.contains("row-highlight") && bruh.childNodes[7].classList.contains("item-selected")) { | |
rim.load(); | |
rim.play(); | |
} | |
}); | |
rowLoop(); | |
}, BPM); | |
} | |
// Call rowLoop() function | |
rowLoop(); |
@import url('https://fonts.googleapis.com/css2?family=Lexend+Zetta&display=swap'); | |
* { | |
margin: 0; | |
padding: 0; | |
user-select: none; | |
} | |
html { | |
font-family: 'Lexend Zetta', sans-serif; | |
background-color: rgb(248, 248, 248); | |
} | |
.container { | |
background-color: rgb(255, 255, 255); | |
/* box-shadow: 0px 12px 30px rgba(0, 0, 0, 0.07); */ | |
height: 370px; | |
width: 950px; | |
border-radius: 11px; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
padding: 12px 20px; | |
display: flex; | |
border: 1px solid rgba(0, 0, 0, 0.2); | |
} | |
.sequencer { | |
display: flex; | |
height: 270px; | |
width: 840px; | |
margin-top: 100px; | |
} | |
#p0 { | |
margin-top: 109px; | |
width: 160px; | |
padding-left: 2px; | |
padding-right: 26px; | |
} | |
.drum-name { | |
font-weight: bold; | |
font-size: 12px; | |
letter-spacing: -0.5px; | |
line-height: 58px; | |
padding: 0px 36px 0px 16px; | |
border-radius: 6px; | |
margin-bottom: 4px; | |
background-color: #fff; | |
color: rgba(0, 0, 0, 0.6); | |
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.05); | |
border: 1px solid rgba(0, 0, 0, 0.2); | |
} | |
#controls { | |
position: absolute; | |
left: 20px; | |
right: 20px; | |
top: 0px; | |
height: 120px; | |
} | |
#controls-left-side { | |
float: left; | |
height: 100%; | |
} | |
#controls-right-side { | |
float: right; | |
height: 100%; | |
} | |
.sampler { | |
display: inline; | |
padding: 30px 48px; | |
border-radius: 6px; | |
line-height: 120px; | |
text-align: center; | |
background-color: #fff; | |
color: rgba(0, 0, 0, 0.6); | |
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.05); | |
border: 1px solid rgba(0, 0, 0, 0.2); | |
position: relative; | |
} | |
.pressed { | |
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.05); | |
top: 2px; | |
background-color: rgba(0, 0, 0, 0.1); | |
} | |
#bpm { | |
font-weight: bold; | |
color: rgba(0, 0, 0, 0.6); | |
line-height: 120px; | |
position: absolute; | |
top: 25px; | |
right: 200px; | |
} | |
#bpm-slider { | |
position: absolute; | |
top: 24px; | |
right: 150px; | |
width: 180px; | |
} | |
#bpm-slider:hover { | |
cursor: pointer; | |
} | |
#controls p { | |
display: inline; | |
font-size: 12px; | |
position: relative; | |
top: -1px; | |
} | |
#clear-track { | |
font-weight: bold; | |
color: rgba(0, 0, 0, 0.6); | |
padding: 16px 24px; | |
border-radius: 6px; | |
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.05); | |
border: 1px solid rgba(0, 0, 0, 0.2); | |
margin-left: 36px; | |
margin-right: 2px; | |
position: relative; | |
-webkit-user-select: none; | |
} | |
#clear-track:hover { | |
cursor: pointer; | |
border: 1px solid rgba(0, 0, 0, 0.4); | |
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05); | |
} | |
#clear-track:active { | |
top: 0px; | |
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.05); | |
} | |
.d1, | |
.d2, | |
.d3, | |
.d4, | |
.d5, | |
.d6, | |
.d7, | |
.d8, | |
.d9, | |
.d10, | |
.d11, | |
.d12, | |
.d13, | |
.d14, | |
.d15, | |
.d16 { | |
background-color: rgba(0, 0, 0, 0); | |
height: 100%; | |
width: 50%; | |
margin: 5px 2px; | |
display: inline-block; | |
} | |
.sample { | |
background-color: rgba(0, 0, 0, 0.1); | |
margin: 4px 0px; | |
display: block; | |
height: 60px; | |
border-radius: 6px; | |
border: 1px solid rgba(0, 0, 0, 0.1); | |
box-sizing: border-box; | |
} | |
.sample:hover { | |
cursor: pointer; | |
} | |
.row-highlight { | |
background-color: rgba(28, 29, 28, 0.2); | |
} | |
.item-selected { | |
background-color: rgba(0, 0, 0, 0.8); | |
} | |
#d-split { | |
margin-right: 20px; | |
} | |
input[type=range] { | |
height: 50px; | |
-webkit-appearance: none; | |
margin: 10px 0; | |
width: 100%; | |
} | |
input[type=range]:focus { | |
outline: none; | |
} | |
input[type=range]::-webkit-slider-runnable-track { | |
width: 100%; | |
height: 10px; | |
cursor: pointer; | |
box-shadow: 0px 0px 0px #000000; | |
background: #EDEDED; | |
border-radius: 5px; | |
border: 1px solid #C2C2C2; | |
} | |
input[type=range]::-webkit-slider-thumb { | |
box-shadow: 0px 0px 0px #707070; | |
border: 1px solid #A3A3A3; | |
height: 42px; | |
width: 15px; | |
border-radius: 17px; | |
background: #FFFFFF; | |
cursor: pointer; | |
-webkit-appearance: none; | |
margin-top: -17px; | |
} | |
input[type=range]:focus::-webkit-slider-runnable-track { | |
background: #EDEDED; | |
} | |
input[type=range]::-moz-range-track { | |
width: 100%; | |
height: 7px; | |
cursor: pointer; | |
background: #EDEDED; | |
border-radius: 50px; | |
border: 1px solid #C2C2C2; | |
} | |
input[type=range]::-moz-range-thumb { | |
border: 1px solid #A3A3A3; | |
height: 42px; | |
width: 13px; | |
border-radius: 17px; | |
background: #FFFFFF; | |
cursor: pointer; | |
} | |
input[type=range]::-ms-track { | |
width: 100%; | |
height: 10px; | |
cursor: pointer; | |
animate: 0.2s; | |
background: transparent; | |
border-color: transparent; | |
color: transparent; | |
} | |
input[type=range]::-ms-fill-lower { | |
background: #EDEDED; | |
border: 1px solid #C2C2C2; | |
border-radius: 10px; | |
} | |
input[type=range]::-ms-fill-upper { | |
background: #EDEDED; | |
border: 1px solid #C2C2C2; | |
border-radius: 10px; | |
} | |
input[type=range]::-ms-thumb { | |
margin-top: 1px; | |
border: 1px solid #A3A3A3; | |
height: 43px; | |
width: 15px; | |
border-radius: 50px; | |
background: #FFFFFF; | |
cursor: pointer; | |
} | |
input[type=range]:focus::-ms-fill-lower { | |
background: #EDEDED; | |
} | |
input[type=range]:focus::-ms-fill-upper { | |
background: #EDEDED; | |
} | |
/* .parent, .parent2 { | |
margin-top: 10px; | |
display: flex; | |
flex-wrap: no-wrap; | |
} | |
.kick, .clap { | |
width: 50%; | |
height: 40px; | |
background-color: rgba(0, 0, 0, 0.1); | |
margin: 0px 2px; | |
line-height: 50px; | |
text-align: center; | |
font-weight: bold; | |
font-family: "Courier New"; | |
font-size: 12px; | |
border-radius: 12px; | |
box-sizing: border-box; | |
} | |
.kick:hover, .clap:hover { | |
cursor: pointer; | |
} | |
.item-selected { | |
background-color: salmon; | |
} | |
.row { | |
background-color: rgba(0, 0, 0, 0.25); | |
} */ |
Awesome work MAN 💪