Hello Guys! Welcome to Coding Torque. In this blog, we are going to make a Sonorous track mixer using HTML, CSS and JavaScript. You can create this if you are an intermediate-level web developer. This project is created using pure HTML, CSS and JavaScript.
Before we start, here are some more projects for you:
1. Analog Clock using JavaScript
2. Tip Calculator using JavaScript
3. QR Code Generator using JavaScript
I would recommend you don't just copy and paste the code, just look at the code and type by understanding it.
Let's go step by step:
Step 1: HTML Code
Starter Template
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sonorous track mixer using HTML, CSS and JavaScript - @codingtorque</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css?family=Varela+Round" rel="stylesheet">
</head>
<body>
<!-- further code in next block -->
<!-- JQuery CDN -->
<script src="https://code.jquery.com/jquery-3.6.1.js"
integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=" crossorigin="anonymous"></script>
<script src="script.js"></script>
</body>
</html>
Paste the below code in your <body> tag
<div class="mixerContainer">
<div id="master" class="controllerBox">
<h3 class="title">Master</h3>
<div class="box">
<div class="row a">
<div class="radialSlider volumeContainer">
<input type="range" min="0" max="11" step="0.1" value="10" id="master-volume">
<label for="master-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<a href="https://github.com/EkoLabs/sonorous" target="_blank" class="sonorousLink">Sonorous</a>
<div class="radialSlider rateContainer">
<input type="range" min="0.5" max="1.5" step="0.1" value="1" id="master-rate">
<label for="master-rate">Speed</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
</div>
<div class="dotDisplay songName"><a href="http://tillian.band" target="_blank">Tillian / Reborn >>> Click to hear more</a></div>
<div class="progressSlider">
<span class="timeElapsed">--:--</span>
<input type="range" min="0" max="100" step="1" value="0" id="master-progress">
<span class="timeLeft">--:--</span>
</div>
<div class="row">
<div class="buttonContainer">
<button class="play" id="play-btn">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 10 10" xml:space="preserve">
<path class="st0" d="M0,0.81v8.03c0,0.63,0.67,1,1.22,0.7l6.84-4.03c0.52-0.3,0.52-1.07,0-1.39L1.22,0.09C0.67-0.19,0,0.2,0,0.81z"></path>
</svg>
</button>
<button class="stop" id="stop-btn">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 10.69 10.69" xml:space="preserve">
<path class="st0" d="M8.8,10.34H1.9c-0.85,0-1.55-0.7-1.55-1.55V1.9c0-0.85,0.7-1.55,1.55-1.55h6.9c0.85,0,1.55,0.7,1.55,1.55v6.9C10.34,9.67,9.65,10.34,8.8,10.34z"/>
</svg>
</button>
<button class="loop" id="master-loop">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 17.25 13.54" xml:space="preserve">
<g>
<path d="M10.96,11.08c-0.71,0.39-1.5,0.59-2.3,0.59C5.95,11.69,3.74,9.5,3.73,6.8l0-0.18L5,6.61c0.22,0,0.42-0.11,0.51-0.31
c0.11-0.18,0.09-0.42-0.02-0.6L3.27,2.28C3.16,2.12,2.97,2.01,2.77,2.01c-0.2,0-0.38,0.11-0.49,0.27l-2.2,3.44
c-0.11,0.18-0.12,0.4-0.01,0.6c0.11,0.18,0.29,0.31,0.51,0.31l1.27-0.01l0,0.18c0.02,3.74,3.07,6.75,6.81,6.73
c1.11-0.01,2.21-0.28,3.17-0.82c0.45-0.24,0.63-0.82,0.37-1.27C11.97,11.02,11.41,10.84,10.96,11.08z"/>
<path d="M17.18,7.21c-0.11-0.18-0.29-0.31-0.51-0.31L15.4,6.91l0-0.18C15.38,2.99,12.33-0.02,8.59,0C7.48,0.01,6.38,0.28,5.42,0.82
C4.96,1.05,4.79,1.64,5.04,2.09C5.28,2.54,5.86,2.7,6.32,2.46C7,2.08,7.8,1.87,8.6,1.87c2.7-0.01,4.91,2.17,4.93,4.87l0,0.18
l-1.27,0.01c-0.22,0-0.42,0.11-0.51,0.31c-0.11,0.18-0.09,0.42,0.02,0.6l2.22,3.42c0.11,0.16,0.29,0.27,0.49,0.27
c0.2,0,0.38-0.11,0.49-0.27l2.2-3.44C17.27,7.63,17.29,7.41,17.18,7.21z"/>
</g>
</svg>
</button>
</div>
<div class="toggleContainer">
<div class="title">Mute all</div>
<input type="checkbox" id="master-mute" class="toggle">
<label for="master-mute"></label>
</div>
</div>
<div class="shoutout">Trivia bit: <a href="http://tillian.band" target="_blank">Tillian's</a> guitarist is an <a href="https://eko.engineering" target="_blank">eko dev</a>!</div>
</div>
</div>
<div id="track-vocals" class="controllerBox track">
<h3 class="title">Vocals</h3>
<div class="box">
<div class="radialSlider">
<input type="range" min="0" max="11" step="0.1" value="10" id="track-vocals-volume">
<label for="track-vocals-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<div class="toggleContainer">
<div class="title">Solo</div>
<input type="checkbox" id="track-vocals-solo" class="toggle">
<label for="track-vocals-solo"></label>
</div>
<div class="toggleContainer">
<div class="title">Mute</div>
<input type="checkbox" id="track-vocals-mute" class="toggle">
<label for="track-vocals-mute"></label>
</div>
<div class="buttonContainer">
<button class="fadeIn" id="track-vocals-fadeIn" title="Fade in">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M12.11,0.87c0.33,0,0.6,0.25,0.6,0.56c0,0.31-0.27,0.56-0.6,0.56c-3.36,0-5.38,1.57-7.06,4.69
C4.69,7.36,3.66,9.56,3.5,9.88c-0.58,1.12-1.09,1.74-1.81,2c-0.07,0.03-0.14,0.04-0.22,0.04c-0.24,0-0.47-0.14-0.56-0.36
c-0.12-0.29,0.03-0.61,0.34-0.73c0.34-0.12,0.71-0.57,1.16-1.44C2.57,9.1,3.6,6.89,3.98,6.18C5.84,2.72,8.22,0.87,12.11,0.87
C12.11,0.87,12.11,0.87,12.11,0.87 M12.11,0L12.11,0C8.1,0,5.36,1.78,3.22,5.77C2.96,6.24,2.44,7.34,2.06,8.13
C1.86,8.55,1.7,8.89,1.65,8.99c-0.46,0.88-0.68,1.02-0.7,1.04c-0.36,0.13-0.66,0.41-0.82,0.77c-0.16,0.35-0.16,0.74-0.01,1.1
c0.22,0.55,0.76,0.9,1.36,0.9c0.17,0,0.35-0.03,0.51-0.09c1.11-0.4,1.75-1.4,2.29-2.42c0.06-0.12,0.25-0.51,0.48-0.98
C5.11,8.54,5.6,7.5,5.82,7.1c1.62-3.01,3.44-4.23,6.29-4.23c0.38,0,0.74-0.14,1.02-0.4c0.29-0.27,0.45-0.64,0.45-1.03
C13.58,0.64,12.92,0,12.11,0L12.11,0z"/>
</svg>
</button>
<button class="fadeOut" id="track-vocals-fadeOut" title="Fade out">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M1.47,0.87c3.89,0,6.27,1.85,8.13,5.3c0.38,0.7,1.42,2.92,1.57,3.21c0.46,0.87,0.82,1.32,1.16,1.44
c0.31,0.11,0.46,0.44,0.34,0.73c-0.09,0.22-0.32,0.36-0.56,0.36c-0.07,0-0.14-0.01-0.22-0.04c-0.71-0.26-1.23-0.88-1.81-2
c-0.17-0.32-1.2-2.53-1.56-3.2c-1.68-3.12-3.7-4.69-7.06-4.69c0,0,0,0,0,0c0,0,0,0,0,0c-0.33,0-0.6-0.25-0.6-0.56
C0.87,1.12,1.14,0.87,1.47,0.87C1.47,0.87,1.47,0.87,1.47,0.87 M1.47,0L1.47,0L1.47,0C1.09,0,0.73,0.14,0.45,0.4
C0.16,0.67,0,1.04,0,1.43c0,0.79,0.66,1.43,1.47,1.43c2.85,0,4.68,1.23,6.29,4.23c0.22,0.4,0.71,1.44,1.08,2.2
c0.23,0.48,0.41,0.86,0.48,0.99c0.53,1.02,1.18,2.02,2.29,2.42c0.16,0.06,0.34,0.09,0.51,0.09c0.6,0,1.14-0.35,1.37-0.9
c0.15-0.36,0.14-0.75-0.02-1.1c-0.16-0.36-0.46-0.64-0.84-0.77c0-0.01-0.23-0.15-0.69-1.03c-0.05-0.1-0.21-0.43-0.41-0.85
c-0.38-0.8-0.91-1.89-1.16-2.37C8.22,1.78,5.48,0,1.47,0L1.47,0z"/>
</svg>
</button>
</div>
</div>
</div>
<div id="track-guitars" class="controllerBox track">
<h3 class="title">guitars</h3>
<div class="box">
<div class="radialSlider">
<input type="range" min="0" max="11" step="0.1" value="10" id="track-guitars-volume">
<label for="track-guitars-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<div class="toggleContainer">
<div class="title">Solo</div>
<input type="checkbox" id="track-guitars-solo" class="toggle">
<label for="track-guitars-solo"></label>
</div>
<div class="toggleContainer">
<div class="title">Mute</div>
<input type="checkbox" id="track-guitars-mute" class="toggle">
<label for="track-guitars-mute"></label>
</div>
<div class="buttonContainer">
<button class="fadeIn" id="track-guitars-fadeIn" title="Fade in">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M12.11,0.87c0.33,0,0.6,0.25,0.6,0.56c0,0.31-0.27,0.56-0.6,0.56c-3.36,0-5.38,1.57-7.06,4.69
C4.69,7.36,3.66,9.56,3.5,9.88c-0.58,1.12-1.09,1.74-1.81,2c-0.07,0.03-0.14,0.04-0.22,0.04c-0.24,0-0.47-0.14-0.56-0.36
c-0.12-0.29,0.03-0.61,0.34-0.73c0.34-0.12,0.71-0.57,1.16-1.44C2.57,9.1,3.6,6.89,3.98,6.18C5.84,2.72,8.22,0.87,12.11,0.87
C12.11,0.87,12.11,0.87,12.11,0.87 M12.11,0L12.11,0C8.1,0,5.36,1.78,3.22,5.77C2.96,6.24,2.44,7.34,2.06,8.13
C1.86,8.55,1.7,8.89,1.65,8.99c-0.46,0.88-0.68,1.02-0.7,1.04c-0.36,0.13-0.66,0.41-0.82,0.77c-0.16,0.35-0.16,0.74-0.01,1.1
c0.22,0.55,0.76,0.9,1.36,0.9c0.17,0,0.35-0.03,0.51-0.09c1.11-0.4,1.75-1.4,2.29-2.42c0.06-0.12,0.25-0.51,0.48-0.98
C5.11,8.54,5.6,7.5,5.82,7.1c1.62-3.01,3.44-4.23,6.29-4.23c0.38,0,0.74-0.14,1.02-0.4c0.29-0.27,0.45-0.64,0.45-1.03
C13.58,0.64,12.92,0,12.11,0L12.11,0z"/>
</svg>
</button>
<button class="fadeOut" id="track-guitars-fadeOut" title="Fade out">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M1.47,0.87c3.89,0,6.27,1.85,8.13,5.3c0.38,0.7,1.42,2.92,1.57,3.21c0.46,0.87,0.82,1.32,1.16,1.44
c0.31,0.11,0.46,0.44,0.34,0.73c-0.09,0.22-0.32,0.36-0.56,0.36c-0.07,0-0.14-0.01-0.22-0.04c-0.71-0.26-1.23-0.88-1.81-2
c-0.17-0.32-1.2-2.53-1.56-3.2c-1.68-3.12-3.7-4.69-7.06-4.69c0,0,0,0,0,0c0,0,0,0,0,0c-0.33,0-0.6-0.25-0.6-0.56
C0.87,1.12,1.14,0.87,1.47,0.87C1.47,0.87,1.47,0.87,1.47,0.87 M1.47,0L1.47,0L1.47,0C1.09,0,0.73,0.14,0.45,0.4
C0.16,0.67,0,1.04,0,1.43c0,0.79,0.66,1.43,1.47,1.43c2.85,0,4.68,1.23,6.29,4.23c0.22,0.4,0.71,1.44,1.08,2.2
c0.23,0.48,0.41,0.86,0.48,0.99c0.53,1.02,1.18,2.02,2.29,2.42c0.16,0.06,0.34,0.09,0.51,0.09c0.6,0,1.14-0.35,1.37-0.9
c0.15-0.36,0.14-0.75-0.02-1.1c-0.16-0.36-0.46-0.64-0.84-0.77c0-0.01-0.23-0.15-0.69-1.03c-0.05-0.1-0.21-0.43-0.41-0.85
c-0.38-0.8-0.91-1.89-1.16-2.37C8.22,1.78,5.48,0,1.47,0L1.47,0z"/>
</svg>
</button>
</div>
</div>
</div>
<div id="track-cello" class="controllerBox track">
<h3 class="title">cello</h3>
<div class="box">
<div class="radialSlider">
<input type="range" min="0" max="11" step="0.1" value="10" id="track-cello-volume">
<label for="track-cello-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<div class="toggleContainer">
<div class="title">Solo</div>
<input type="checkbox" id="track-cello-solo" class="toggle">
<label for="track-cello-solo"></label>
</div>
<div class="toggleContainer">
<div class="title">Mute</div>
<input type="checkbox" id="track-cello-mute" class="toggle">
<label for="track-cello-mute"></label>
</div>
<div class="buttonContainer">
<button class="fadeIn" id="track-cello-fadeIn" title="Fade in">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M12.11,0.87c0.33,0,0.6,0.25,0.6,0.56c0,0.31-0.27,0.56-0.6,0.56c-3.36,0-5.38,1.57-7.06,4.69
C4.69,7.36,3.66,9.56,3.5,9.88c-0.58,1.12-1.09,1.74-1.81,2c-0.07,0.03-0.14,0.04-0.22,0.04c-0.24,0-0.47-0.14-0.56-0.36
c-0.12-0.29,0.03-0.61,0.34-0.73c0.34-0.12,0.71-0.57,1.16-1.44C2.57,9.1,3.6,6.89,3.98,6.18C5.84,2.72,8.22,0.87,12.11,0.87
C12.11,0.87,12.11,0.87,12.11,0.87 M12.11,0L12.11,0C8.1,0,5.36,1.78,3.22,5.77C2.96,6.24,2.44,7.34,2.06,8.13
C1.86,8.55,1.7,8.89,1.65,8.99c-0.46,0.88-0.68,1.02-0.7,1.04c-0.36,0.13-0.66,0.41-0.82,0.77c-0.16,0.35-0.16,0.74-0.01,1.1
c0.22,0.55,0.76,0.9,1.36,0.9c0.17,0,0.35-0.03,0.51-0.09c1.11-0.4,1.75-1.4,2.29-2.42c0.06-0.12,0.25-0.51,0.48-0.98
C5.11,8.54,5.6,7.5,5.82,7.1c1.62-3.01,3.44-4.23,6.29-4.23c0.38,0,0.74-0.14,1.02-0.4c0.29-0.27,0.45-0.64,0.45-1.03
C13.58,0.64,12.92,0,12.11,0L12.11,0z"/>
</svg>
</button>
<button class="fadeOut" id="track-cello-fadeOut" title="Fade out">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M1.47,0.87c3.89,0,6.27,1.85,8.13,5.3c0.38,0.7,1.42,2.92,1.57,3.21c0.46,0.87,0.82,1.32,1.16,1.44
c0.31,0.11,0.46,0.44,0.34,0.73c-0.09,0.22-0.32,0.36-0.56,0.36c-0.07,0-0.14-0.01-0.22-0.04c-0.71-0.26-1.23-0.88-1.81-2
c-0.17-0.32-1.2-2.53-1.56-3.2c-1.68-3.12-3.7-4.69-7.06-4.69c0,0,0,0,0,0c0,0,0,0,0,0c-0.33,0-0.6-0.25-0.6-0.56
C0.87,1.12,1.14,0.87,1.47,0.87C1.47,0.87,1.47,0.87,1.47,0.87 M1.47,0L1.47,0L1.47,0C1.09,0,0.73,0.14,0.45,0.4
C0.16,0.67,0,1.04,0,1.43c0,0.79,0.66,1.43,1.47,1.43c2.85,0,4.68,1.23,6.29,4.23c0.22,0.4,0.71,1.44,1.08,2.2
c0.23,0.48,0.41,0.86,0.48,0.99c0.53,1.02,1.18,2.02,2.29,2.42c0.16,0.06,0.34,0.09,0.51,0.09c0.6,0,1.14-0.35,1.37-0.9
c0.15-0.36,0.14-0.75-0.02-1.1c-0.16-0.36-0.46-0.64-0.84-0.77c0-0.01-0.23-0.15-0.69-1.03c-0.05-0.1-0.21-0.43-0.41-0.85
c-0.38-0.8-0.91-1.89-1.16-2.37C8.22,1.78,5.48,0,1.47,0L1.47,0z"/>
</svg>
</button>
</div>
</div>
</div>
<div id="track-keys" class="controllerBox track">
<h3 class="title">keys</h3>
<div class="box">
<div class="radialSlider">
<input type="range" min="0" max="11" step="0.1" value="10" id="track-keys-volume">
<label for="track-keys-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<div class="toggleContainer">
<div class="title">Solo</div>
<input type="checkbox" id="track-keys-solo" class="toggle">
<label for="track-keys-solo"></label>
</div>
<div class="toggleContainer">
<div class="title">Mute</div>
<input type="checkbox" id="track-keys-mute" class="toggle">
<label for="track-keys-mute"></label>
</div>
<div class="buttonContainer">
<button class="fadeIn" id="track-keys-fadeIn" title="Fade in">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M12.11,0.87c0.33,0,0.6,0.25,0.6,0.56c0,0.31-0.27,0.56-0.6,0.56c-3.36,0-5.38,1.57-7.06,4.69
C4.69,7.36,3.66,9.56,3.5,9.88c-0.58,1.12-1.09,1.74-1.81,2c-0.07,0.03-0.14,0.04-0.22,0.04c-0.24,0-0.47-0.14-0.56-0.36
c-0.12-0.29,0.03-0.61,0.34-0.73c0.34-0.12,0.71-0.57,1.16-1.44C2.57,9.1,3.6,6.89,3.98,6.18C5.84,2.72,8.22,0.87,12.11,0.87
C12.11,0.87,12.11,0.87,12.11,0.87 M12.11,0L12.11,0C8.1,0,5.36,1.78,3.22,5.77C2.96,6.24,2.44,7.34,2.06,8.13
C1.86,8.55,1.7,8.89,1.65,8.99c-0.46,0.88-0.68,1.02-0.7,1.04c-0.36,0.13-0.66,0.41-0.82,0.77c-0.16,0.35-0.16,0.74-0.01,1.1
c0.22,0.55,0.76,0.9,1.36,0.9c0.17,0,0.35-0.03,0.51-0.09c1.11-0.4,1.75-1.4,2.29-2.42c0.06-0.12,0.25-0.51,0.48-0.98
C5.11,8.54,5.6,7.5,5.82,7.1c1.62-3.01,3.44-4.23,6.29-4.23c0.38,0,0.74-0.14,1.02-0.4c0.29-0.27,0.45-0.64,0.45-1.03
C13.58,0.64,12.92,0,12.11,0L12.11,0z"/>
</svg>
</button>
<button class="fadeOut" id="track-keys-fadeOut" title="Fade out">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M1.47,0.87c3.89,0,6.27,1.85,8.13,5.3c0.38,0.7,1.42,2.92,1.57,3.21c0.46,0.87,0.82,1.32,1.16,1.44
c0.31,0.11,0.46,0.44,0.34,0.73c-0.09,0.22-0.32,0.36-0.56,0.36c-0.07,0-0.14-0.01-0.22-0.04c-0.71-0.26-1.23-0.88-1.81-2
c-0.17-0.32-1.2-2.53-1.56-3.2c-1.68-3.12-3.7-4.69-7.06-4.69c0,0,0,0,0,0c0,0,0,0,0,0c-0.33,0-0.6-0.25-0.6-0.56
C0.87,1.12,1.14,0.87,1.47,0.87C1.47,0.87,1.47,0.87,1.47,0.87 M1.47,0L1.47,0L1.47,0C1.09,0,0.73,0.14,0.45,0.4
C0.16,0.67,0,1.04,0,1.43c0,0.79,0.66,1.43,1.47,1.43c2.85,0,4.68,1.23,6.29,4.23c0.22,0.4,0.71,1.44,1.08,2.2
c0.23,0.48,0.41,0.86,0.48,0.99c0.53,1.02,1.18,2.02,2.29,2.42c0.16,0.06,0.34,0.09,0.51,0.09c0.6,0,1.14-0.35,1.37-0.9
c0.15-0.36,0.14-0.75-0.02-1.1c-0.16-0.36-0.46-0.64-0.84-0.77c0-0.01-0.23-0.15-0.69-1.03c-0.05-0.1-0.21-0.43-0.41-0.85
c-0.38-0.8-0.91-1.89-1.16-2.37C8.22,1.78,5.48,0,1.47,0L1.47,0z"/>
</svg>
</button>
</div>
</div>
</div>
<div id="track-drums" class="controllerBox track">
<h3 class="title">drums</h3>
<div class="box">
<div class="radialSlider">
<input type="range" min="0" max="11" step="0.1" value="10" id="track-drums-volume">
<label for="track-drums-volume">Volume</label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.73 83.82">
<g class="jogContainer">
<circle class="jog" cx="41.42" cy="41.42" r="33.84" />
<circle class="thumb" cx="42" cy="22" r="4.29" />
</g>
<path class="bar" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
<path class="barActive" d="M12.66,70.19c-3.69-3.68-6.67-8.07-8.73-12.94S0.72,47.04,0.72,41.43s1.14-10.96,3.2-15.83
s5.04-9.25,8.73-12.94s8.07-6.67,12.94-8.73S35.8,0.72,41.41,0.72s10.96,1.14,15.83,3.2s9.25,5.04,12.94,8.73
s6.67,8.07,8.73,12.94c2.06,4.87,3.21,10.22,3.21,15.83s-1.14,10.96-3.2,15.83c-2.06,4.87-5.04,9.25-8.73,12.94" />
</svg>
<div class="dotDisplay">--</div>
</div>
<div class="toggleContainer">
<div class="title">Solo</div>
<input type="checkbox" id="track-drums-solo" class="toggle">
<label for="track-drums-solo"></label>
</div>
<div class="toggleContainer">
<div class="title">Mute</div>
<input type="checkbox" id="track-drums-mute" class="toggle">
<label for="track-drums-mute"></label>
</div>
<div class="buttonContainer">
<button class="fadeIn" id="track-drums-fadeIn" title="Fade in">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M12.11,0.87c0.33,0,0.6,0.25,0.6,0.56c0,0.31-0.27,0.56-0.6,0.56c-3.36,0-5.38,1.57-7.06,4.69
C4.69,7.36,3.66,9.56,3.5,9.88c-0.58,1.12-1.09,1.74-1.81,2c-0.07,0.03-0.14,0.04-0.22,0.04c-0.24,0-0.47-0.14-0.56-0.36
c-0.12-0.29,0.03-0.61,0.34-0.73c0.34-0.12,0.71-0.57,1.16-1.44C2.57,9.1,3.6,6.89,3.98,6.18C5.84,2.72,8.22,0.87,12.11,0.87
C12.11,0.87,12.11,0.87,12.11,0.87 M12.11,0L12.11,0C8.1,0,5.36,1.78,3.22,5.77C2.96,6.24,2.44,7.34,2.06,8.13
C1.86,8.55,1.7,8.89,1.65,8.99c-0.46,0.88-0.68,1.02-0.7,1.04c-0.36,0.13-0.66,0.41-0.82,0.77c-0.16,0.35-0.16,0.74-0.01,1.1
c0.22,0.55,0.76,0.9,1.36,0.9c0.17,0,0.35-0.03,0.51-0.09c1.11-0.4,1.75-1.4,2.29-2.42c0.06-0.12,0.25-0.51,0.48-0.98
C5.11,8.54,5.6,7.5,5.82,7.1c1.62-3.01,3.44-4.23,6.29-4.23c0.38,0,0.74-0.14,1.02-0.4c0.29-0.27,0.45-0.64,0.45-1.03
C13.58,0.64,12.92,0,12.11,0L12.11,0z"/>
</svg>
</button>
<button class="fadeOut" id="track-drums-fadeOut" title="Fade out">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 14 13.54" xml:space="preserve">
<path d="M1.47,0.87c3.89,0,6.27,1.85,8.13,5.3c0.38,0.7,1.42,2.92,1.57,3.21c0.46,0.87,0.82,1.32,1.16,1.44
c0.31,0.11,0.46,0.44,0.34,0.73c-0.09,0.22-0.32,0.36-0.56,0.36c-0.07,0-0.14-0.01-0.22-0.04c-0.71-0.26-1.23-0.88-1.81-2
c-0.17-0.32-1.2-2.53-1.56-3.2c-1.68-3.12-3.7-4.69-7.06-4.69c0,0,0,0,0,0c0,0,0,0,0,0c-0.33,0-0.6-0.25-0.6-0.56
C0.87,1.12,1.14,0.87,1.47,0.87C1.47,0.87,1.47,0.87,1.47,0.87 M1.47,0L1.47,0L1.47,0C1.09,0,0.73,0.14,0.45,0.4
C0.16,0.67,0,1.04,0,1.43c0,0.79,0.66,1.43,1.47,1.43c2.85,0,4.68,1.23,6.29,4.23c0.22,0.4,0.71,1.44,1.08,2.2
c0.23,0.48,0.41,0.86,0.48,0.99c0.53,1.02,1.18,2.02,2.29,2.42c0.16,0.06,0.34,0.09,0.51,0.09c0.6,0,1.14-0.35,1.37-0.9
c0.15-0.36,0.14-0.75-0.02-1.1c-0.16-0.36-0.46-0.64-0.84-0.77c0-0.01-0.23-0.15-0.69-1.03c-0.05-0.1-0.21-0.43-0.41-0.85
c-0.38-0.8-0.91-1.89-1.16-2.37C8.22,1.78,5.48,0,1.47,0L1.47,0z"/>
</svg>
</button>
</div>
</div>
</div>
</div>
<svg>
<linearGradient id="jogGradient" gradientUnits="userSpaceOnUse" x1="22.9189" y1="76.1371" x2="90.5909" y2="76.1371" gradientTransform="matrix(1 -2.775030e-04 2.775030e-04 1 -15.3562 -34.7017)">
<stop offset="0" style="stop-color:#232323" />
<stop offset="0.4624" style="stop-color:#100E0F" />
<stop offset="0.7146" style="stop-color:#121011" />
<stop offset="0.8573" style="stop-color:#1A1919" />
<stop offset="0.9723" style="stop-color:#272627" />
<stop offset="1" style="stop-color:#2B2B2B" />
</linearGradient>
</svg>
Output Till Now
Step 2: CSS Code
Create a file style.css and paste the code below.
html, body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
body{
background : #606060;
display: flex;
align-items: center;
justify-content: center;
}
body > svg{
display: none;
}
@font-face {
font-family: 'ChessType';
font-style: normal;
font-weight: normal;
src: local('ChessType'), url('https://video.eko.com/s/sonorous/demos/track_mixer/ChessType.woff') format('woff');
}
.controllerBox{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
--main-color: #f6b018;
--secondary-color: #fff686;
display: flex;
flex-direction: column;
}
.controllerBox h3.title {
box-sizing: border-box;
font-size: 18px;
background: #161616;
border-radius: 5px 5px 0px 0px;
color: #8E8E8E;
margin: 0;
padding: 10px;
padding-bottom: 9px;
text-transform: uppercase;
background-repeat: no-repeat;
background-position: right 10px top 10px;
background-size: 16px;
}
.controllerBox .box {
box-sizing: border-box;
flex-grow: 1;
padding: 18px 18px 10px 18px;
background : linear-gradient(90deg, rgba(43, 43, 43, 1) 0%, rgba(31, 31, 31, 1) 100%);
border-radius : 0 0 6px 6px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
display: flex;
flex-direction: column;
align-items: center;
}
.controllerBox .dotDisplay,
.controllerBox .progressSlider,
.controllerBox .buttonContainer,
.controllerBox .toggle + label
{
border-top: 3px solid #100e0f;
border-bottom: 2px solid #3b393a;
background: #100e0f;
padding: 6px 10px;
margin: 10px;
border-radius: 6px;
}
.controllerBox .dotDisplay{
position: relative;
font-family: ChessType;
color: var(--main-color);
text-transform: lowercase;
display: inline-block;
}
.songName{
overflow: hidden;
white-space: nowrap;
max-width: 300px;
}
.songName a{
display: block;
animation: scroll 10s steps(14, end) infinite;
text-decoration: none;
color: var(--main-color);
transition: all 0.3s linear;
}
.songName a:hover{
color: var(--secondary-color);
}
@keyframes scroll {
0% { transform: translateX(0%); }
50% { transform: translateX(0%); }
100% { transform: translateX(-100%); }
}
.controllerBox .progressSlider{
display: flex;
padding: 4px 10px;
padding-bottom: 5px;
border-radius: 12px;
margin-top: 0;
}
.progressSlider span{
display: inline-block;
color: #7a7a7a;
font-size: 10px;
margin-top: 1px;
}
.progressSlider input[type=range] {
flex: 1;
margin: 0 10px;
border: 1px solid #565656;
}
.progressSlider input[type=range] {
-webkit-appearance: none;
-moz-apperance: none;
border-radius: 6px;
height: 10px;
--progress-percent: 0%;
background-image: linear-gradient(90deg,
var(--main-color) var(--progress-percent),
black var(--progress-percent)
);
transition: all 0.3s linear;
cursor: pointer;
}
.progressSlider input[type="range"]::-moz-range-track {
/*border: none;*/
background: none;
outline: none;
}
.progressSlider input[type=range]:focus {
outline: none;
/*border: none;*/
}
.progressSlider input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none !important;
background-color: #df7164;
height: 13px;
width: 13px;
border-radius: 50%;
visibility: hidden;
}
.progressSlider .progressSlider input[type=range]::-moz-range-thumb {
-moz-appearance: none !important;
background-color: #df7164;
border: none;
height: 13px;
width: 13px;
border-radius: 50%;
visibility: hidden;
}
/*radial slider*/
.radialSlider {
position: relative;
width: 100px;
min-width: 100px;
display: flex;
flex-direction: column;
}
.radialSlider svg{
pointer-events: none;
}
.radialSlider .jogContainer {
transform-origin: center;
cursor: pointer;
pointer-events: all;
touch-action: none;
}
.radialSlider input { display: none}
.radialSlider label{
display: block;
color: #8E8E8E;
margin: 0;
padding: 0px;
text-align: center;
text-transform: uppercase;
font-size: 16px;
}
.radialSlider svg {
margin-top: 8px;
}
.radialSlider .jog {
fill: url(#jogGradient);
stroke: #545454;
stroke-width: 1.3855;
stroke-miterlimit: 10;
}
.radialSlider .bar, .radialSlider .barActive{
fill: none;
stroke: #FFA412;
stroke-width: 1.4431;
stroke-miterlimit: 10;
stroke-dasharray: 191;
}
.radialSlider .bar{
stroke: #7A7A7A;
}
.radialSlider .thumb{
fill: #FFA412;
}
.radialSlider .dotDisplay {
align-self: center;
margin-top: 3px;
text-align: center;
width: 30px;
}
/*main button container*/
.controllerBox .buttonContainer {
display: inline-flex;
padding: 0px 3px 3px 4px;
height: 36px;
margin: 0;
}
.buttonContainer button{
border: 0;
width: 36px;
height: 36px;
background : linear-gradient(180deg, rgba(35, 35, 35, 1) 0%, rgba(16, 14, 15, 1) 46.24%, rgba(18, 16, 17, 1) 71.46%, rgba(26, 25, 25, 1) 85.73%, rgba(39, 38, 39, 1) 97.23%, rgba(43, 43, 43, 1) 100%);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 2px;
cursor: pointer;
transition: all 0.2s ease-out;
}
.buttonContainer button:hover{
background: var(--secondary-color);
}
.buttonContainer button.active{
background: var(--main-color);
}
.buttonContainer button.active path, .buttonContainer button:hover path {
stroke: none;
fill: black;
}
.buttonContainer button svg{
width: 60%;
height: 60%;
}
.buttonContainer button path{
fill:none;
stroke:#666666;
stroke-width:0.7003;
stroke-miterlimit:10;
}
button.loop svg {
width: 100%;
height: 100%;
}
button.fadeIn svg, button.fadeOut svg{
width: 90%;
height: 90%;
}
.controllerBox .toggle {
display: none;
}
.controllerBox .toggle {
display: none;
}
.row{
display: flex;
align-items: flex-end;
justify-content: space-between;
margin: 15px 0;
}
.row.a{
margin-top: 0;
margin-bottom: 0;
}
.toggleContainer{
display: flex;
flex-direction: column;
}
.toggleContainer .title{
color: #8E8E8E;
margin: 0;
padding: 0px;
text-align: center;
text-transform: uppercase;
}
.controllerBox .toggle + label{
display: inline-block;
position: relative;
width: 80px;
height: 27px;
border-radius: 50px;
cursor: pointer;
margin: 0;
margin-top: 8px;
}
.toggle + label:before{
position: absolute;
top: 0;
left: 3px;
content: "";
width: 57px;
height: 36px;
background : linear-gradient(90deg, rgba(35, 35, 35, 1) 0%, rgba(16, 14, 15, 1) 46.24%, rgba(18, 16, 17, 1) 71.46%, rgba(26, 25, 25, 1) 85.73%, rgba(39, 38, 39, 1) 97.23%, rgba(43, 43, 43, 1) 100%);
border-radius : 50px;
transition: all 0.2s ease-out;
}
.toggle:checked + label:before{
left: 39px;
background: var(--main-color);
}
/*layout */
.mixerContainer{
display: flex;
align-items: stretch;
}
.track {
margin-left: 10px;
display: flex;
flex-direction: column;
}
.track .toggleContainer{
margin-top: 20px;
}
.track .buttonContainer {
margin-top: 20px;
}
#track-vocals > .title{
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/vocals.svg);
}
#track-guitars > .title{
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/guitars.svg);
background-size: 20px;
}
#track-cello > .title{
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/cello.svg);
background-size: 20px;
}
#track-keys > .title{
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/keys.svg);
background-size: 20px;
}
#track-drums > .title{
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/drums.svg);
background-size: 20px;
}
#master .box{
align-items: stretch;
}
.sonorousLink{
display: block;
width: 100px;
background-image: url(https://eko.com/s/sonorous/demos/track_mixer/sonorous.svg);
background-repeat: no-repeat;
background-position: top center;
text-align: center;
text-decoration: none;
color: #626262;
margin: 0 20px;
font-weight: bold;
font-size: 12px;
text-transform: uppercase;
padding-top: 48px;
align-self: center;
}
.shoutout{
color: #bbbbbb;
text-align: center;
font-size: 12px;
margin-top: auto;
}
.shoutout a{
color: #cccccc;
}
Output Till Now
Step 3: JavaScript Code
Create a file script.js and paste the code below.
// UI logic
let progressInput = document.querySelector("#master-progress");
let timeElapsed = document.querySelector(".timeElapsed");
let timeLeft = document.querySelector(".timeLeft");
function addMasterControls() {
// master volume
setupRadialSlider(document.querySelector(`#master .volumeContainer`),
// volume is 0-11, map it to 0-1
value => { Sonorous.masterVolume = value/11 });
setupRadialSlider(document.querySelector(`#master .rateContainer`),
// rate is 0.5 to 2
value => {
Sonorous.sonors.forEach(sonor => sonor.playbackRate = value);
});
// play
document.getElementById('play-btn').addEventListener('click', e => {
let isPlaying = e.currentTarget.classList.contains('active');
if (isPlaying) {
e.currentTarget.classList.remove('active');
Sonorous.sonors.forEach(sonor => {
sonor.pause();
});
} else {
e.currentTarget.classList.add('active');
Sonorous.sonors.forEach(sonor => {
sonor.play();
sonor.volume = parseFloat(document.getElementById(`${sonor.id}-volume`).value) / 11;
});
}
});
// stop
document.getElementById('stop-btn').addEventListener('click', () => {
document.querySelector("#play-btn").classList.remove('active');
Sonorous.sonors.forEach( sonor => {
sonor.stop();
});
});
// loop
document.getElementById(`master-loop`).addEventListener('click', e => {
Sonorous.sonors.forEach(sonor => sonor.loop = !sonor.loop);
e.currentTarget .classList.toggle('active');
});
//master mute
document.getElementById('master-mute').addEventListener('click', () => {
console.log(Sonorous.muteAll);
Sonorous.muteAll = !Sonorous.muteAll;
});
let progressSonor = Sonorous.get('track-vocals');
// update progress on playback
setInterval(()=>{
if (progressSonor.isPlaying && progressSonor.duration !== 0) {
let currentTime = progressSonor.playbackPosition;
let percentComplete = currentTime / progressSonor.duration;
updateProgressUI(percentComplete, progressSonor.duration);
} else {
updateProgressUI(0, null);
}
}, 100);
// progress bar seeking
progressInput.addEventListener('change', e=>{
let newValue = e.currentTarget.value;
if (progressSonor.isPlaying) {
Sonorous.sonors.forEach(sonor => {
sonor.seek(sonor.duration * newValue / 100)
})
}
});
}
function setupTrackControls(sonor, trackId) {
// Create volume listener
setupRadialSlider(document.getElementById(`${trackId}`),
// volume is 0-11, map it to 0-1
value => { sonor.volume = value/11 });
// Create mute listener
document.getElementById(`${trackId}-mute`).addEventListener('click', () => {
// when other tracks are soloed, mute has no immediate effect
if (getSoloToggles().length == 0) {
sonor.muted = !sonor.muted;
}
});
// Create solo listener
document.getElementById(`${trackId}-solo`).addEventListener('click', () => {
//get an array of track ids for all checked solo toggles
let soloToggles = getSoloToggles();
// we have at least one soloed track, ignore mutes
if (soloToggles.length > 0){
Sonorous.sonors.forEach(sonor => sonor.muted = !soloToggles.includes(sonor.id));
} else {
// no soloed track, revert mute status
Sonorous.sonors.forEach(
sonor => sonor.muted = document.querySelector(`#${sonor.id}-mute:checked`) !== null
);
}
});
// Create fadeIn listener
document.getElementById(`${trackId}-fadeIn`).addEventListener('click', () => {
let volumeInput = document.getElementById(`${trackId}-volume`);
let fadeStartTime = Date.now();
let fadeStartVolume = sonor.volume;
// we want to update the knobs with the fade
// note: this is a temp hacky way
let fadeInterval = setInterval(()=>{
let volumePercent = (Date.now() - fadeStartTime) / 1000;
if(volumePercent >= 0 && volumePercent <= 1){
volumeInput.value = fadeStartVolume * 11 + volumePercent * ( 10 - fadeStartVolume * 11);
volumeInput.dispatchEvent(new Event('change'));
} else if (volumePercent >= 0) {
volumeInput.value = 10;
volumeInput.dispatchEvent(new Event('change'));
clearInterval(fadeInterval)
}
}, 30);
sonor.fade(10/11, 1);
});
// Create fadeOut listener
document.getElementById(`${trackId}-fadeOut`).addEventListener('click', () => {
let volumeInput = document.getElementById(`${trackId}-volume`);
let fadeStartTime = Date.now();
let fadeStartVolume = sonor.volume;
// we want to update the knobs with the fade
// note: this is a temp hacky way
let fadeInterval = setInterval(()=>{
let volumePercent = 1 - (Date.now() - fadeStartTime) / 1000;
if(volumePercent >= 0 && volumePercent <= 1){
volumeInput.value = volumePercent * fadeStartVolume * 11;
volumeInput.dispatchEvent(new Event('change'));
} else if (volumePercent < 0) {
volumeInput.value = 0;
volumeInput.dispatchEvent(new Event('change'));
clearInterval(fadeInterval)
}
}, 30);
});
sonor.fade(0, 1);
}
function setupRadialSlider(parentElement, onChange) {
let input = parentElement.querySelector('input[type=range]');
let knobJog = parentElement.querySelector('.jogContainer');
let barActive = parentElement.querySelector('.barActive');
let text = parentElement.querySelector('.dotDisplay');
let rangeStart = parseFloat(input.getAttribute("min"));
let rangeEnd = parseFloat(input.getAttribute("max"));
knob(input, knobJog, {
rangeInDegrees: 270,
rangeStartDegree: 220,
onUpdate: value => {
let progress = (value - rangeStart) / (rangeEnd - rangeStart);
let degrees = progress * 270 + 220;
knobJog.style.transform = `rotate(${degrees}deg)`;
// this magic number is the path length. Why recalculate it when it's constant?
barActive.style.strokeDashoffset = (1 - progress) * 191;
text.innerHTML = value.toFixed(1);
onChange(value);
}
});
}
function updateProgressUI(percentComplete, duration){
let timeElapsedNumber;
let timeLeftNumber;
if (duration) {
// luckily our audio demo is shorter than one minute
timeElapsedNumber = String(parseInt(percentComplete * duration)).padStart(2, '0');
timeLeftNumber = String(parseInt(duration - duration * percentComplete)).padStart(2, '0');
timeElapsed.innerHTML = `00:${timeElapsedNumber}`;
timeLeft.innerHTML = `-00:${timeLeftNumber}`;
} else {
timeElapsed.innerHTML = '--:--';
timeLeft.innerHTML = '--:--';
}
progressInput.style.setProperty('--progress-percent', `${percentComplete*100}%`);
}
// returns an array of track ids for all checked solo toggles
function getSoloToggles(){
return Array.from(document.querySelectorAll('input[id$="solo"]:checked'))
.map(el => el.id.substring(0, el.id.length-5));
}
if (Sonorous && Sonorous.isSupported()) {
let trackMap = {
'track-vocals': 'https://video.eko.com/s/sonorous/demos/track_mixer/Tillian_Reborn_Vocals.mp3',
'track-guitars': 'https://video.eko.com/s/sonorous/demos/track_mixer/Tillian_Reborn_Guitars.mp3',
'track-keys': 'https://video.eko.com/s/sonorous/demos/track_mixer/Tillian_Reborn_Keys.mp3',
'track-cello': 'https://video.eko.com/s/sonorous/demos/track_mixer/Tillian_Reborn_Cello.mp3',
'track-drums': 'https://video.eko.com/s/sonorous/demos/track_mixer/Tillian_Reborn_Drums.mp3',
};
Object.keys(trackMap).forEach((trackId) => {
let sonor = Sonorous.addSonor(trackMap[trackId], { id: trackId });
setupTrackControls(sonor, trackId);
});
addMasterControls();
}
Code Credits: @OpherV
If you want me to code any project or post any specific
post, feel free
to DM me at IG @code.scientist or @codingtorque
If you have any doubts or any project ideas feel free to
Contact
Us
Hope you find this post helpful💖
Follow us on Instagram for more projects like
this👨💻