<!--
design by: https://www.behance.net/vahanhovh
-->
<nav>
<div class="controls">
Backing track: Shuffle Blues in A
<a class="rewind">
<svg width="26" height="16" viewBox="160 18 26 16" xmlns="http://www.w3.org/2000/svg" class="rewind-icon"><path d="M173.3 26.143l12 6.857V18.778l-12 6.857v-6.857l-12.444 7.11L173.3 33v-6.857z" fill="#A8B5C3" fill-rule="evenodd"/></svg>
</a>
<a class="play">
<svg width="21" height="24" viewBox="210 14 21 24" xmlns="http://www.w3.org/2000/svg" class="play-icon"><path fill="#A8B5C2" fill-rule="evenodd" d="M230.677 25.815L210 37.63V14"/></svg>
<svg width="21px" height="24px" viewBox="210 14 21 24" xmlns="http://www.w3.org/2000/svg" class="pause-icon">
<rect id="pause-1" fill="#A8B5C2" fill-rule="evenodd" x="210" y="14" width="7" height="24"></rect>
<rect id="pause-2" fill="#A8B5C2" fill-rule="evenodd" x="224" y="14" width="7" height="24"></rect>
</svg>
</a>
</div>
<div class="social">
<a href="//www.reddit.com/submit?url=https://codepen.io/gregh/full/zNzvOm/" target="_blank"><i class="fa fa-reddit-alien" aria-hidden="true"></i></a>
<a href="https://twitter.com/intent/tweet?text=You%20can%20play%20the%20blues!&url=https://codepen.io/gregh/full/zNzvOm/&via=greghvns" target="_blank"><i class="fa fa-twitter" aria-hidden="true"></i></a>
</div>
</nav>
<div class="loading">
<svg xmlns="http://www.w3.org/2000/svg" width="468" height="153" viewBox="166 91 468 153" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="a" d="M55.185 12.262c-.347.79-.546 1.666-.546 2.62 0 4.574-7.84 53.744-7.84 58.546 0 4.8-2.533 11.727 0 11.727 2.534 0 7.29 1.25 11.385-4.788 4.097-6.037 17.77-29.975 19.23-29.975 1.457 0-7.587 28.44-.427 29.975 4.607.99 11.635-3.858 16.48-8.035.96 5.18 4.9 8.22 13.818 8.22 12.986 0 22.383-13.286 22.383-13.286s.418-3.898-5.88 0c-6.298 3.897-4.258 4.342-15.55 6.068-5.856.895-6.797-2.81-6.797-7.433 0-.348.01-.712.03-1.088 3.232.077 12.677-2.964 14.942-4.124 2.67-1.366 2.08-6.77.455-11.34-.923-2.6-3.263-3.09-5.11-3.03-.186-.393-.76-.63-1.858-.63-4.007 0-13.592 7.772-15.904 17.514-2.3 3.564-5.817 7.81-7.944 7.81-3.366 0 8.153-26.21-3.07-29.058-11.224-2.846-23.298 22.52-24.8 23.84-1.5 1.32 8.156-48.312 8.156-53.375 0-.72-.008-1.335-.032-1.86 23.668-3.402 43.71-5.064 47.54-5.783C118.167 3.967 124.47 0 117.77 0c-6.698 0-69.834 4.218-88.825 8.207-18.99 3.99-26.468 6.64-26.468 6.64s-4.406 2.98-1.465 7.264c2.003 2.92 14.57-.838 31.063-4.904-1.912 10.082-5.225 32.205-5.225 37.298 0 6.254-1.285 25.32 0 27.04 1.284 1.72 7.134 2.55 7.134 2.55s2.74-18.423 4.41-24.52c1.673-6.095 5.42-38.66 5.42-43.82 0-.438-.05-.857-.143-1.256 3.752-.813 7.61-1.578 11.515-2.236zm47.16 47.12c.716-2.64 1.88-5.208 3.58-6.947 1.872-.27 6.04-1.18 7.043-1.18 1.18 0-1.666 4.308-4.883 6.612-1.822 1.304-4.04 1.548-5.74 1.514zm308.077.98c-3.754 4.996-9.936 12.48-13.515 11.07-5.393-2.128 0-23.466 0-24.174 0-.708-4.796 1.183-4.796 1.183s-10.757 21.35-11.752 22.213c-.994.863-2.053.954-2.053-.863 0-1.816 1.36-13.787 4.584-18.434 3.222-4.646 14.017-4.098 14.017-4.098s-1.107-2.823-4.796-2.823c-3.69 0-13.716 1.784-15.924 6.92-1.59 3.704-2.59 8.748-3.027 12.375-3.405 4.434-8.936 11.337-10.376 11.337-2.122 0 3.153-20.888-5.338-21.898-8.49-1.012-17.85 14.475-18.994 14.475-1.146 0 9.642-17.113-2.152-18.254-8.382-.81-16.238 17.294-16.946 17.4-.71.105.2-9.366 1.424-11.494 1.223-2.127.36-8.983-2.133-8.983s-5.02 1.976-5.992 3.078c-.325.37-.886 2.133-1.512 4.477-.006 0-.013.003-.02.005-1.787.448-8.053 4.868-11.753 7.556.016-6.705-.437-14.322-.437-15.153 0-1.4.905-1.3.905-2.878 0-1.58-3.283-2.717-3.283-2.717s-1.128.397-2.133.928c-1-.626-2.41-.473-4.163 2.36-3.704 5.993-16.807 27.328-28.098 29.054-5.858.895-6.8-2.81-6.8-7.433 0-.722.042-1.476.127-2.246 2.705.608 6.99 1.246 10.766.37 6.075-1.41 6.41-7.447 4.783-13.976-.952-3.817-3.634-4.266-5.697-3.98-.31-.243-.803-.383-1.52-.383-4.115 0-14.113 8.198-16.075 18.307-.157.813-.287 1.603-.385 2.367-2.808 3.068-6.123 6.123-8.195 6.123-4.162 0-1.923-12.285-.96-16.346.96-4.06 3.052-8.888-.867-8.888-1.1 0-2.13.316-3.043.772.125-.452.193-.732.193-.732s-2.312-.368-4.313 1.548c-2.002 1.916-11.73 22.404-14.072 22.404-2.343 0 2.113-18.69 3.02-20.43.91-1.74-1.256-5.44-3.273-5.44-2.018 0-5.27.057-7.424 3.7-2.153 3.64-9.613 28.076 1.482 29.856 7.366 1.18 13.472-9.378 17.287-16.94-1.346 6.808-1.316 14.448 5.376 15.013 5.68.48 10.806-2.43 14.667-5.69.624 5.798 4.48 9.24 13.967 9.24 8.812 0 21.748-16.698 29.155-27.435.44 3.67 1.39 11.16-.453 12.307-2.29 1.427-10.852 11.156-10.852 13.987 0 2.83 7.12 5.846 14.007 2.828 6.888-3.02 3.49-7.366 5.32-10.48.373-.633.616-1.988.768-3.76 2.86-1.804 7.654-5.13 10.338-7.012-.694 3.1-1.284 6.047-1.52 7.652-.63 4.242.956 11.83 5.817 11.83 4.86 0 11.666-5.806 12.492-8.598.826-2.792 7.683-12.927 7.683-12.927s-7.13 20.16 1.014 18.932c8.145-1.227 16.56-15.495 16.56-15.495s-3.793 16.692 5.912 18.893c6.495 1.473 12.594-5.326 15.918-9.985.65 2.29 2.2 4.478 5.82 4.96 5.757.767 11.875-16.112 11.875-17.35 0-1.238-1.168 9.45-1.168 12.843 0 3.393 3.64 6.622 7.015 6.622 3.13 0 8-3.485 12.017-6.898-.082 1.837-.905 5.614.288 6.25 1.254.67 2.1.034 3.71 1.024 1.61.99 5.336.628 5.336-1.062s9.778-20.095 10.96-20.095c1.182 0 .005 12.518.005 14.814 0 2.297-1.605 8.397 5.58 8.397 7.187 0 15.475-8.768 18.706-13.227 3.23-4.458 5.57-10.708 3.387-10.708-2.185 0-12.76 17.47-15.456 17.47-2.695 0-.667-7.944-.667-12.344 0-4.4.92-10.06-4.022-10.06-4.94 0-10.654-.732-12.85 4.664-2.196 5.397-4.435 7.706-4.435 7.706s1.557-9.286 2.298-11.815c.74-2.528-.092-5.317-1.798-4.433-1.707.884-6.938 1.25-7.603 2.646-.33.692-1.172 5.297-1.94 9.983zm-153.99-1.363c.92-2.733 2.464-5.25 4.772-6.75.15-.098.298-.2.445-.304 1.762-.64 3.81-1.418 4.603-1.418 1.507 0 .972 4.376-2.508 6.85-2.166 1.54-5.166 1.71-7.312 1.62zM148.527 77.516c-.032 4.315-.068 9.77.144 11.704.283 2.578-2.03.9-2.03.45s-1.774-.874-1.774-.01c0 .866-1.8-.763-1.965-1.688-.162-.926.528 2.883.528 2.883s-2.185-1.67-2.185-2.277c0-.606.402 2.11.2 2.194-.2.083-1.507.714-2.8.714-1.296 0-2.018 1.208-2.706-4.108-.687-5.316.91-29.215 2.486-39.33 1.575-10.113 4.315-28.36 4.315-28.36s1.07-4.042 5.866-4.042c4.797 0 6.565.378 6.565 3.12 0 .21-.04.692-.113 1.403 6.176-1.825 20.582-4.423 20.582 11.02 0 8.447-5.253 13.987-10.833 17.488 7.493 1.866 14.923 5.715 15.428 13.628 1.036 16.256-22.15 22.55-22.15 22.55l1.95-2.913-3.092.716-.483-1.817-5.99-1.62-1.944-1.706zm0-.214c.01-1.35.02-2.578.02-3.538 0-1.585 1.01-9.91 2.244-19.63 6.05-.065 20.933.774 20.312 10.63-.73 11.6-20.183 12.474-22.575 12.538zm5.69-50.017c-.62 4.99-1.472 11.583-2.326 18.238 4.845-.486 15.583-2.86 16.707-14.334.817-8.334-11.644-4.78-14.38-3.904zm36.82 63.546s-11.07-14.215-5.535-45.883c5.537-31.67 15.348-41.56 17.477-41.56 2.13 0 3.68-1.113 4.647-1.113.967 0 3.688-1.534 4.842 1.412 1.153 2.945-1.16 22.18-5.325 30.35-4.163 8.172-7.558 18.625-7.558 18.625v-8.23s-2.05 1.948 4.043-16.04c6.093-17.987 3.84-19.758 3.678-19.758-.162 0-4.375 8.254-5.63 13.007-1.256 4.753-6.29 26.72-5.3 44.006.99 17.286 5.193 25.438 5.193 25.438s-.76-.782-1.984-.782c-1.226 0-1.258.684-2.98.684-1.72 0-2.95-.16-3.592-.16-.642.002-1.973.002-1.973.002zm100.38-19.198s-4.027 3.352-4.027 5.042 1.554 2.058 2.466 1.495c.912-.562 2.007-2.366 2.007-3.11 0-.746-.446-3.426-.446-3.426z"/>
</defs>
<g fill="none" fill-rule="evenodd" transform="translate(166 91)">
<g transform="translate(5)">
<mask id="b" fill="#fff">
<use xlink:href="#a"/>
</mask>
<use fill="#FFF" xlink:href="#a"/>
<rect fill="#FF6545" x="0" y="0" width="0" height="100" mask="url(#b)" class="progress"/>
</g>
<text fill="#F2D9AE" font-family="Roboto-Bold, Roboto" font-size="24" font-weight="bold">
<tspan x="82" y="141">YOU CAN PLAY THE BLUES!</tspan>
</text>
<path fill="#DDC08E" d="M0 111h468v2H0zM0 152h468v1H0z"/>
<circle cx="30" cy="132" r="4" fill="#DDC08E"/>
<circle cx="444" cy="132" r="4" fill="#DDC08E"/>
</g>
</svg>
</div>
<div class="notes">
<div class="note" data-note="0"><div>G<span>4</span></div></div>
<div class="note key" data-note="1"><div>A<span>4</span></div></div>
<div class="note" data-note="2"><div>C<span>5</span></div></div>
<div class="note" data-note="3"><div>D<span>5</span></div></div>
<div class="note" data-note="4"><div>E<span>5</span></div></div>
<div class="note" data-note="5"><div>G<span>5</span></div></div>
<div class="note key" data-note="6"><div>A<span>5</span></div></div>
<div class="note" data-note="7"><div>C<span>6</span></div></div>
<div class="note" data-note="8"><div>D<span>6</span></div></div>
<div class="note" data-note="9"><div>D<span>#6</span></div></div>
<div class="note" data-note="10"><div>E<span>6</span></div></div>
<div class="note" data-note="11"><div>G<span>6</span></div></div>
<div class="note key" data-note="12"><div>A<span>6</span></div></div>
<div class="note" data-note="13"><div>C<span>7</span></div></div>
<div class="note" data-note="14"><div>D<span>7</span></div></div>
</div>
<div class="guitar">
<div class="circle"></div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/guitar.png">
</div>
<audio src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/Shuffle_A.mp3"></audio>
nav {
background-color: #221C44;
height: 52px;
font-family: 'Roboto', sans-serif;
color: #969DA2;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 40px;
font-size: 14px;
line-height: 17px;
position: relative;
z-index: 2;
.rewind {
margin-left: 28px;
height: 16px;
cursor: pointer;
}
.play {
margin-left: 24px;
height: 24px;
cursor: pointer;
}
.play-icon,
.rewind-icon,
.pause-icon {
&:hover path,
&:hover rect {
fill: #566574;
}
}
.pause-icon {
display: none;
}
.controls {
display: flex;
align-items: center;
}
.social a {
font-size: 24px;
color: #A8B5C2;
margin-left: 18px;
&:hover {
color: #566574;
}
}
}
.loading {
display: flex;
justify-content: center;
margin-top: 24px;
.progress {
transition: width 0.3s linear;
}
position: relative;
z-index: 1;
}
.notes {
display: flex;
height: 0;
opacity: 0;
transition: opacity 1s ease;
justify-content: center;
position: relative;
z-index: 2;
overflow: hidden;
.note {
& > div {
height: 100%;
width: 32px;
border-radius: 16px;
background-color: #D8D8D8;
color: #541F5D;
font-family: 'Roboto', sans-serif;
font-size: 20px;
font-weight: 700;
line-height: 23px;
text-align: center;
box-sizing: border-box;
padding: 5px 0;
box-shadow: 0 7px 8px rgba(0, 0, 0, .16);
}
&:hover div {
background-color: #FF6545;
color: #fff;
}
height: 132px;
&.key{
height: 172px;
& > div {
background-color: #ECDCCA;
}
&:hover > div {
background-color: #FF6545;
color: #fff;
}
}
&:not(:first-child) > div {
margin-left: 8px;
}
&:not(:last-child) > div {
margin-right: 8px;
}
span {
font-size: 0.7em;
}
}
}
.guitar {
width: 96%;
min-width: 772px;
position: fixed;
bottom: 0;
right: 0;
&.visible {
transition: opacity 0.5s ease;
}
img {
width: 100%;
display: block;
pointer-events: none;
}
.circle {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/switch.png);
background-size: 100%;
background-repeat: no-repeat;
width: 5vw;
height: 5vw;
min-width: 40px;
min-height: 40px;
border-radius: 50%;
position: absolute;
right: 44.5%;
top: 33.5%;
cursor: pointer;
&.rock {
background-position: 0 100%;
&:before {
color: #FFF;
}
&:after {
color: #C17CA4;
}
}
&:before, &:after {
font-weight: 700;
font-size: 12px;
line-height: 13px;
text-align: center;
display: block;
position: relative;
transition: color 0.3s ease;
}
&:before {
content: "ROCK";
top: -14px;
color: #C17CA4;
}
&:after {
content: "BLUES";
top: 100%;
color: #FFF;
position: absolute;
width: 100%;
margin-top: 2px;
}
}
}
body {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/bluesman_background.svg), linear-gradient(-180deg, #242150 5%, #572250 91%);
background-size: cover;
background-position: center;
margin: 0;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-family: 'Roboto', sans-serif;
& * {
user-select: none;
}
}
html,
body {
height: 100%;
min-width: 726px;
}
View Compiled
class Guitar {
constructor(context, buffer) {
this.context = context;
this.buffer = buffer;
}
setup() {
this.gainNode = this.context.createGain();
this.source = this.context.createBufferSource();
this.source.buffer = this.buffer;
this.source.connect(this.gainNode);
this.gainNode.connect(this.context.destination);
this.gainNode.gain.setValueAtTime(0.8, this.context.currentTime);
}
play() {
this.setup();
this.source.start(this.context.currentTime);
}
stop() {
var ct = this.context.currentTime + 0.5;
this.gainNode.gain.exponentialRampToValueAtTime(0.001, ct);
this.source.stop(ct);
}
}
class Buffer {
constructor(context, urls) {
this.context = context;
this.urls = urls;
this.buffer = [];
}
loadSound(url, index) {
let request = new XMLHttpRequest();
request.open('get', url, true);
request.responseType = 'arraybuffer';
let thisBuffer = this;
request.onload = function() {
// Safari doesn't support promise based syntax
thisBuffer.context
.decodeAudioData(request.response, function(buffer) {
thisBuffer.buffer[index] = buffer;
updateProgress(thisBuffer.urls.length);
if(index == thisBuffer.urls.length-1) {
thisBuffer.loaded();
}
});
};
request.send();
};
getBuffer() {
this.urls.forEach((url, index) => {
this.loadSound(url, index);
})
}
loaded() {
document.querySelector('.loading').style.opacity = 0;
document.querySelector('.loading').style.height = 0;
document.querySelector('.notes').style.height = "auto";
document.querySelector('.notes').style.opacity = 1;
loaded = true;
}
getSound(index) {
return this.buffer[index];
}
}
let progressBar = document.querySelector('.progress');
let iteration = 0;
function updateProgress(total) {
progressBar.style.width = ++iteration/total * 100 + '%';
}
let guitar = null;
let preset = 0;
let loaded = false;
function playGuitar() {
let index = parseInt(this.dataset.note) + preset;
guitar = new Guitar(context, buffer.getSound(index));
guitar.play();
}
function stopGuitar() {
guitar.stop();
}
let context = new (window.AudioContext || window.webkitAudioContext)();
let sounds = [
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/G4.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/A4.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/C5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/D5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/E5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/G5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/A5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/C6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/D6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/D%236.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/E6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/G6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/A6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/C7.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/D7.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_G4.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_A4.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_C5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_D5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_E5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_G5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_A5.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_C6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_D6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_D%236.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_E6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_G6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_A6.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_C7.mp3',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/d_D7.mp3'
];
let buffer = new Buffer(context, sounds);
let guitarSound = buffer.getBuffer();
let buttons = document.querySelectorAll('.notes .note');
buttons.forEach(button => {
button.addEventListener('mouseenter', playGuitar.bind(button));
button.addEventListener('mouseleave', stopGuitar);
})
let audio = document.querySelector('audio');
let play = document.querySelector('.play');
let rewind = document.querySelector('.rewind');
let circle = document.querySelector('.circle');
audio.addEventListener('pause', pauseTrack);
audio.addEventListener('play', playTrack);
play.addEventListener('click', () => {
if(audio.paused) {
audio.play();
playTrack();
} else {
audio.pause();
pauseTrack();
}
})
rewind.addEventListener('click', () => {
audio.currentTime = 0;
})
circle.addEventListener('click', () => {
preset = (preset == 0) ? 15 : 0;
circle.classList.toggle('rock');
})
audio.addEventListener('ended', () => {
pauseTrack();
});
function playTrack() {
play.querySelector('.pause-icon').style.display = "block";
play.querySelector('.play-icon').style.display = "none";
}
function pauseTrack() {
play.querySelector('.pause-icon').style.display = "none";
play.querySelector('.play-icon').style.display = "block";
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.