<!--
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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.