Аудио плееры для сайта

Разработка Аудио плееры для сайта

Нет прав для скачивания
Красивые аудио плееры для сайта.
Фрагменты кода аудио плееров для веб сайтов. HTML код:
HTML:
<div class="player paused">
  <div class="album">
    <div class="cover">
      <div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/38273/3rdburglar-cover-192.jpg" alt="3rdburglar by Wordburglar" /></div>
    </div>
  </div>

  <div class="info">
    <div class="time">
      <span class="current-time">0:00</span>
      <span class="progress"><span></span></span>
      <span class="duration">0:00</span>
    </div>
 
    <h1>Drawings With Words</h1>
    <h2>3RDBURGLAR</h2>
  </div>

  <div class="actions">
    <button class="shuffle">
      <div class="arrow"></div>
      <div class="arrow"></div>
    </button>
    <button class="button rw">
      <div class="arrow"></div>
      <div class="arrow"></div>
    </button>
    <button class="button play-pause">
      <div class="arrow"></div>
    </button>
    <button class="button ff">
      <div class="arrow"></div>
      <div class="arrow"></div>
    </button>
    <button class="repeat"></button>
  </div>

  <audio prelaod src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/38273/Wordburglar_Drawings_with_Words.mp3"></audio>
</div>
Стиль для плеера:
CSS:
.player {
  position: relative;
  width: 20em;
  min-height: 20em;
  overflow: hidden;
  background-color: #eee;
  border-radius: 0.25em;
  box-shadow:
    0 1.5em 2em -1em rgba(0,0,0,0.8),
    inset 0 0.0625em 0 rgba(255,255,255,1),
    inset 0 -0.125em 0.0625em rgba(0,0,0,0.3);
}

.album {
  position: relative;
  left: 50%;
  width: 15em;
  height: 15em;
  margin-bottom: -13%;
  overflow: hidden;
  transform: translate(-50%,-25%);
  background-color: #111;
  border: 1px solid #111;
  border-radius: 50%;
  box-shadow:
    0 0.0625em 0.1875em rgba(0,0,0,0.5),
    0 0 0.125em 0.3125em #ddd,
    0 0.0625em 0 0.375em #bbb,
    0 0 0.375em 0.325em rgba(0,0,0,0.3),
    0 0 0.5em 0.375em rgba(0,0,0,0.3),
    0 0.25em 1em 0.5em rgba(0,0,0,0.15),
    inset 0 0 0 0.0625em rgba(0,0,0,0.5),
    inset 0 0 0 0.1875em rgba(255,255,255,1),
    inset 0 0 0 0.375em rgba(0,0,0,0.5),
    inset 0 0 0 0.4375em rgba(255,255,255,0.2),
    inset 0 0 0 0.5em rgba(0,0,0,0.5),
    inset 0 0 0 0.5625em rgba(255,255,255,0.3),
    inset 0 0 0 0.625em rgba(0,0,0,0.5),
    inset 0 0 0 0.6875em rgba(255,255,255,0.2),
    inset 0 0 0 0.75em rgba(0,0,0,0.5),
    inset 0 0 0 0.8125em rgba(255,255,255,0.3),
    inset 0 0 0 0.875em rgba(0,0,0,0.5),
    inset 0 0 0 0.9375em rgba(255,255,255,0.3),
    inset 0 0 0 1em rgba(0,0,0,0.5),
    inset 0 0 0 1.0625em rgba(255,255,255,0.2),
    inset 0 0 0 1.125em rgba(0,0,0,0.5),
    inset 0 0 0 1.1875em rgba(255,255,255,0.3),
    inset 0 0 0 1.25em rgba(0,0,0,0.5),
    inset 0 0 0 1.3125em rgba(255,255,255,0.2),
    inset 0 0 0 1.375em rgba(255,255,255,0.2),
    inset 0 0 0 1.4375em rgba(0,0,0,0.5),
    inset 0 0 0 1.5em rgba(255,255,255,0.3),
    inset 0 0 0 1.5625em rgba(0,0,0,0.5),
    inset 0 0 0 1.625em rgba(255,255,255,0.3),
    inset 0 0 0 1.6875em rgba(0,0,0,0.5),
    inset 0 0 0 1.75em rgba(255,255,255,0.2),
    inset 0 0 0 1.8125em rgba(0,0,0,0.5),
    inset 0 0 0 1.875em rgba(255,255,255,0.2),
    inset 0 0 0 1.9375em rgba(0,0,0,0.5),
    inset 0 0 0 2em rgba(255,255,255,0.3),
    inset 0 0 0 2.0625em rgba(0,0,0,0.5),
    inset 0 0 0 2.125em rgba(0,0,0,0.5),
    inset 0 0 0 2.1875em rgba(255,255,255,0.1),
    inset 0 0 0 2.25em rgba(0,0,0,0.5),
    inset 0 0 0 2.3125em rgba(255,255,255,0.2),
    inset 0 0 0 2.375em rgba(255,255,255,0.1),
    inset 0 0 0 2.4375em rgba(0,0,0,0.5),
    inset 0 0 0 2.5em rgba(255,255,255,0.3),
    inset 0 0 0 2.5625em rgba(0,0,0,0.5),
    inset 0 0 0 2.625em rgba(255,255,255,0.2),
    inset 0 0 0 2.6875em rgba(0,0,0,0.5),
    inset 0 0 0 2.75em rgba(255,255,255,0.2),
    inset 0 0 0 2.8125em rgba(0,0,0,0.5),
    inset 0 0 0 2.875em rgba(255,255,255,0.2),
    inset 0 0 0 2.9375em rgba(0,0,0,0.5),
    inset 0 0 0 3em rgba(255,255,255,0.3),
    inset 0 0 0 3.0625em rgba(0,0,0,0.5),
    inset 0 0 0 3.125em rgba(0,0,0,0.5),
    inset 0 0 0 3.1875em rgba(255,255,255,0.2),
    inset 0 0 0 3.25em rgba(0,0,0,0.5),
    inset 0 0 0 3.3125em rgba(255,255,255,0.2),
    inset 0 0 0 3.375em rgba(255,255,255,0.1),
    inset 0 0 0 3.4375em rgba(0,0,0,0.5),
    inset 0 0 0 3.5em rgba(255,255,255,0.3);
}

.album::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform: translate(-50%,-50%);
  background-image:
    linear-gradient(
      -45deg,
      rgba(255,255,255,0) 30%,
      rgba(255,255,255,0.125),
      rgba(255,255,255,0) 70%
    ),
    linear-gradient(
      -48deg,
      rgba(255,255,255,0) 45%,
      rgba(255,255,255,0.075),
      rgba(255,255,255,0) 55%
    ),
    linear-gradient(
      -42deg,
      rgba(255,255,255,0) 45%,
      rgba(255,255,255,0.075),
      rgba(255,255,255,0) 55%
    ),
    radial-gradient(
      circle at top left,
      rgba(0,0,0,1) 20%,
      rgba(0,0,0,0) 80%
    ),
    radial-gradient(
      circle at bottom right,
      rgba(0,0,0,1) 20%,
      rgba(0,0,0,0) 80%
    );
}

.cover,
.cover div {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 6em;
  height: 6em;
  overflow: hidden;
  transform-origin: 0 0;
  transform: rotate(0) translate(-50%,-50%);
  border-radius: 50%;
  animation: spin 4s linear infinite paused;
}

.ffing .cover {
  animation-play-state: running;
}

.cover div {
  border-radius: 0;
  animation: spin 2s linear infinite reverse paused;
}

.rwing .cover div {
  animation: spin 2s linear infinite reverse running;
}

.cover::before,
.cover::after {
  content: '';
  position: absolute;
  z-index: 10;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform-origin: 0 0;
  transform: rotate(0) translate(-50%,-50%);
  border-radius: 50%;
  box-shadow: inset 0 0.0625em rgba(255,255,255,0.3);
  animation: spin 4s linear infinite reverse paused;
}

.cover::after {
  width: 0.25em;
  height: 0.3125em;
  margin-top: -0.0625em;
  background-color: #eee;
  border-radius: 0.125em;
  box-shadow:
    inset 0 -0.0625em 0.0625em rgba(0,0,0,0.5),
    inset 0.0625em -0.0625em 0.125em rgba(255,255,255,0.15),
    inset -0.0625em -0.0625em 0.125em rgba(255,255,255,0.15),
    inset 0 -0.125em 0.125em rgba(0,0,0,0.8),
    0 0.0625em 0.0625em rgba(0,0,0,0.5),
    0 0.0625em 0.25em 0.0625em rgba(0,0,0,0.15),
    0 0 0.25em 0.125em rgba(0,0,0,0.15);
}

.ffing .cover::before,
.ffing .cover::after {
  animation-play-state: running;
}

.cover img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform-origin: 0 0;
  transform: rotate(0) translate(-50%,-50%);
  animation: spin 4s linear infinite paused;
}

.paused .cover img {
  animation-play-state: paused;
}

.playing .cover img {
  animation-play-state: running;
}

.info {
  text-align: center;
  text-shadow: 0 0.0625em rgba(255,255,255,1);
}

.time {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 0.5em;
  margin-bottom: 0.5em;
}

.time > * {
  margin: 0 0.5em;
}

.progress {
  flex-grow: 2;
  height: 0.125em;
  background-color: #999;
  border-radius: 0.0625em;
  box-shadow: 0 0.0625em rgba(255,255,255,1);
  cursor: pointer;
}

.progress span {
  display: block;
  width: 0;
  height: 100%;
  background-color: #666;
}

.actions {
  position: relative;
  width: 100%;
  padding: 1em 0 1.125em;
  display: flex;
  justify-content: center;
  align-items: center;
}

button {
  appearance: none;
  outline: none;
  position: relative;
  padding: 0;
  font-size: 100%;
  background-color: transparent;
  border: none;
  cursor: pointer;
}

.button {
  width: 3em;
  height: 3em;
  background-color: transparent;
  background-image: linear-gradient(#ddd, #f6f6f6);
  border: none;
  border-radius: 50%;
}

.button::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 80%;
  height: 80%;
  transform: translate(-50%,-50%);
  background-color: #f4f4f4;
  border: 0.125em solid #d5d5d5;
  border-radius: 50%;
  box-shadow: inset 0 0.25em 1em -0.25em rgba(255,255,255,0.75);
}

.button:hover::before {
  background-color: #fcfcfc;
}

.play-pause {
  width: 4em;
  height: 4em;
}

.rw {
  right: -0.25em;
  margin-left: 0.375em;
  transform: scaleX(-1);
}

.ff {
  left: -0.25em;
  margin-right: 0.375em;
}

.button .arrow {
  position: absolute;
  z-index: 10;
  top: 50%;
  left: 50%;
  width: 30%;
  height: 30%;
  overflow: hidden;
  transform: translate(-50%,-50%);
}

.button .arrow::before,
.button .arrow::after {
  content: '';
  position: absolute;
  left: -50%;
  width: 100%;
  height: 100%;
  transform: scale(1.2,0.7) rotate(45deg);
  background-color: #ddd;
  box-shadow:
    inset 0 0.125em 0.125em -0.0625em rgba(0,0,0,0.15),
    0.0625em 0.0625em 0.125em rgba(255,255,255,1);
}

.button .arrow::after {
  left: 0;
  transform: none;
  background-color: transparent;
  box-shadow: inset 0.0625em 0 0.125em -0.0625em rgba(0,0,0,0.1);
}

.paused .play-pause .arrow {
  margin-left: 0.1875em;
}

.playing .play-pause .arrow::before,
.playing .play-pause .arrow::after {
  left: 0;
  width: 0.4375em;
  transform: none;
  background-color: #ddd;
  box-shadow:
    inset 0.0625em 0.125em 0.125em -0.0625em rgba(0,0,0,0.15),
    0.0625em 0.0625em 0.125em rgba(255,255,255,1);
}

.playing .play-pause .arrow::after {
  left: auto;
  right: 0;
}

.rw .arrow,
.ff .arrow {
  width: 20%;
  height: 20%;
  margin-left: 12%;
}

.rw .arrow:first-child,
.ff .arrow:first-child {
  margin-left: -4%;
}

.button:active .arrow::before,
.playing .play-pause .arrow::before,
.playing .play-pause .arrow::after {
  background-color: #cef;
}

.shuffle {
  width: 1.375em;
  height: 1.375em;
  color: #d5d5d5;
}

.shuffle .arrow {
  position: absolute;
  top: 0.1875em;
  left: 0;
  width: 0.375em;
  height: 0.125em;
  color: inherit;
  background-color: currentColor;
}

.shuffle .arrow::before {
  content: '';
  position: absolute;
  top: 0;
  left: calc(100% + 0.125em);
  width: 0.5em;
  height: 1em;
  transform: skewX(30deg);
  border-bottom: 0.125em solid;
  border-left: 0.125em solid;
  box-shadow:
    -0.3125em 0em 0 -0.1875em #eee,
    inset 0.375em 0.25em 0 -0.25em #eee;
}

.shuffle .arrow::after {
  content: '';
  position: absolute;
  top: 0.6875em;
  left: calc(100% + 0.625em);
  border: 0.25em solid transparent;
  border-left-width: 0.375em;
  border-left-color: currentColor;
}

.shuffle .arrow:first-child {
  transform-origin: 0 0.5em;
  transform: scaleY(-1);
}

.repeat {
  width: 1.375em;
  height: 1.375em;
  color: #d5d5d5;
  border: 0.125em solid;
  border-right-color: transparent;
  border-radius: 50%;
}

.repeat::before {
  content: '';
  position: absolute;
  top: -0.125em;
  left: -0.125em;
  width: calc(100% + 0.25em);
  height: calc(100% + 0.25em);
  transform: rotate(-45deg);
  border: 0.125em solid transparent;
  border-right-color: currentColor;
  border-radius: 50%;
}

.repeat::after {
  content: '';
  position: absolute;
  top: 50%;
  right: -0.3125em;
  border: 0.25em solid transparent;
  border-top-width: 0.375em;
  border-top-color: currentColor;
}

.shuffle.active,
.repeat.active {
  color: #bde;
}

@keyframes spin {
  100% { transform: rotate(360deg) translate(-50%,-50%); }
}
И конечно же jquery:
JavaScript:
var player = $('.player'),
    audio = player.find('audio'),
    duration = $('.duration'),
    currentTime = $('.current-time'),
    progressBar = $('.progress span'),
    mouseDown = false,
    rewind, showCurrentTime;

function secsToMins(time) {
  var int = Math.floor(time),
      mins = Math.floor(int / 60),
      secs = int % 60,
      newTime = mins + ':' + ('0' + secs).slice(-2);

  return newTime;
}

function getCurrentTime() {
  var currentTimeFormatted = secsToMins(audio[0].currentTime),
      currentTimePercentage = audio[0].currentTime / audio[0].duration * 100;

  currentTime.text(currentTimeFormatted);
  progressBar.css('width', currentTimePercentage + '%');

  if (player.hasClass('playing')) {
    showCurrentTime = requestAnimationFrame(getCurrentTime);
  } else {
    cancelAnimationFrame(showCurrentTime);
  }
}

audio.on('loadedmetadata', function() {
  var durationFormatted = secsToMins(audio[0].duration);
  duration.text(durationFormatted);
}).on('ended', function() {
  if ($('.repeat').hasClass('active')) {
    audio[0].currentTime = 0;
    audio[0].play();
  } else {
    player.removeClass('playing').addClass('paused');
    audio[0].currentTime = 0;
  }
});

$('button').on('click', function() {
  var self = $(this);

  if (self.hasClass('play-pause') && player.hasClass('paused')) {
    player.removeClass('paused').addClass('playing');
    audio[0].play();
    getCurrentTime();
  } else if (self.hasClass('play-pause') && player.hasClass('playing')) {
    player.removeClass('playing').addClass('paused');
    audio[0].pause();
  }

  if (self.hasClass('shuffle') || self.hasClass('repeat')) {
    self.toggleClass('active');
  }
}).on('mousedown', function() {
  var self = $(this);

  if (self.hasClass('ff')) {
    player.addClass('ffing');
    audio[0].playbackRate = 2;
  }

  if (self.hasClass('rw')) {
    player.addClass('rwing');
    rewind = setInterval(function() { audio[0].currentTime -= .3; }, 100);
  }
}).on('mouseup', function() {
  var self = $(this);

  if (self.hasClass('ff')) {
    player.removeClass('ffing');
    audio[0].playbackRate = 1;
  }

  if (self.hasClass('rw')) {
    player.removeClass('rwing');
    clearInterval(rewind);
  }
});

player.on('mousedown mouseup', function() {
  mouseDown = !mouseDown;
});

progressBar.parent().on('click mousemove', function(e) {
  var self = $(this),
      totalWidth = self.width(),
      offsetX = e.offsetX,
      offsetPercentage = offsetX / totalWidth;

  if (mouseDown || e.type === 'click') {
    audio[0].currentTime = audio[0].duration * offsetPercentage;
    if (player.hasClass('paused')) {
      progressBar.css('width', offsetPercentage * 100 + '%');
    }
  }
});
Результат:
00543244.gif

HTML:
<link href='https://fonts.googleapis.com/css?family=Roboto:100' rel='stylesheet' type='text/css'>
<div class="player">
        <canvas></canvas>
        <div class="song">
            <div class="artist">Kavinsky</div>
            <div class="name">Odd Look ft. The Weeknd</div>
        </div>
        <div class="playarea">
            <div class="prevSong"></div>
            <div class="play"></div>
            <div class="pause"></div>
            <div class="nextSong"></div>
        </div>
        <div class="soundControl"></div>
        <div class="time">00:00</div>
    </div>
CSS:
.player {
    width: 740px;
    height: 740px;
    margin-left: -370px;
    margin-top: -370px;
    display: block;
    position: absolute;
    left: 50%;
    top: 50%;
}

.player .playarea {
    position: absolute;
    top: 50%;
    left: 50%;
    height: 126px;
    width: 320px;
    margin-top: -63px;
    margin-left: -160px;
}

.player .playarea div {
    display: inline-block;
}

.player .playarea .play {
    cursor: pointer;
    opacity: 0.85;
    vertical-align: middle;
    margin: 0 26px;
    border: 3px solid #FE4365;
    border-radius: 120px;
    width: 120px;
    height: 120px;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iNDVweCIgaGVpZ2h0PSI1NXB4IiB2aWV3Qm94PSIwIDAgNDUgNTUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPnBsYXktPC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPiAgICAgICAgPGZpbHRlciB4PSItNTAlIiB5PSItNTAlIiB3aWR0aD0iMjAwJSIgaGVpZ2h0PSIyMDAlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMSI+ICAgICAgICAgICAgPGZlT2Zmc2V0IGR4PSIwIiBkeT0iMCIgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSI+PC9mZU9mZnNldD4gICAgICAgICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjUiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4gICAgICAgICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMC45NDI0NzI1NjIgICAwIDAgMCAwIDAuOTYxNzk0NTYyICAgMCAwIDAgMCAwLjk4MjE5NjAwMyAgMCAwIDAgMC4zNSAwIiBpbj0ic2hhZG93Qmx1ck91dGVyMSIgdHlwZT0ibWF0cml4IiByZXN1bHQ9InNoYWRvd01hdHJpeE91dGVyMSI+PC9mZUNvbG9yTWF0cml4PiAgICAgICAgICAgIDxmZU1lcmdlPiAgICAgICAgICAgICAgICA8ZmVNZXJnZU5vZGUgaW49InNoYWRvd01hdHJpeE91dGVyMSI+PC9mZU1lcmdlTm9kZT4gICAgICAgICAgICAgICAgPGZlTWVyZ2VOb2RlIGluPSJTb3VyY2VHcmFwaGljIj48L2ZlTWVyZ2VOb2RlPiAgICAgICAgICAgIDwvZmVNZXJnZT4gICAgICAgIDwvZmlsdGVyPiAgICA8L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiAgICAgICAgPGcgaWQ9IlBsYXllci12ZXJzaW9uLTEiIHNrZXRjaDp0eXBlPSJNU0FydGJvYXJkR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00ODIuMDAwMDAwLCAtMjk2LjAwMDAwMCkiIGZpbHRlcj0idXJsKCNmaWx0ZXItMSkiIGZpbGw9IiNGRTQzNjUiPiAgICAgICAgICAgIDxwYXRoIGQ9Ik00ODUsMzE0LjM1MDE1NCBMNDg1LDM0OCBMNTI1LDMyNC4wMzI2MDkgTDQ4NSwyOTkgTDQ4NSwzMTQuMzUwMTU0IFoiIGlkPSJwbGF5LSIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+) 42px 34px no-repeat;
    background-size: 45px 55px;
}

.player .playarea .pause {
    display: none;
    cursor: pointer;
    opacity: 0.85;
    vertical-align: middle;
    margin: 0 26px;
    border: 3px solid #FE4365;
    border-radius: 120px;
    width: 120px;
    height: 120px;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMzRweCIgaGVpZ2h0PSI1MXB4IiB2aWV3Qm94PSIwIDAgMzQgNTEiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPkxpbmU8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJQbGF5ZXItdmVyc2lvbi0xIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDgyLjAwMDAwMCwgLTI5OC4wMDAwMDApIiBzdHJva2U9IiNGRTQzNjUiIHN0cm9rZS1vcGFjaXR5PSIwLjg1IiBmaWxsPSIjRkU0MzY1IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBmaWxsLW9wYWNpdHk9IjAuODUiPiAgICAgICAgICAgIDxwYXRoIGQ9Ik00ODMsMzAxLjI2ODUxOSBMNDgzLDM0NS43MzE0ODEgTDQ4MywzNDggTDQ4OC4wNzI0NjQsMzQ4IEw0ODguMDcyNDY0LDM0NS43MzE0ODEgTDQ4OC4wNzI0NjQsMzAxLjI2ODUxOSBMNDg4LjA3MjQ2NCwyOTkgTDQ4MywyOTkgTDQ4MywzMDEuMjY4NTE5IFogTTUwOS45Mjc1MzYsMzAxLjI2ODUxOSBMNTA5LjkyNzUzNiwzNDUuNzMxNDgxIEw1MDkuOTI3NTM2LDM0OCBMNTE1LDM0OCBMNTE1LDM0NS43MzE0ODEgTDUxNSwzMDEuMjY4NTE5IEw1MTUsMjk5IEw1MDkuOTI3NTM2LDI5OSBMNTA5LjkyNzUzNiwzMDEuMjY4NTE5IFoiIGlkPSJMaW5lIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj48L3BhdGg+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=) 43px 35px no-repeat;
    background-size: 35px 51px;
}

.player .playarea .prevSong {
    cursor: pointer;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iNjZweCIgaGVpZ2h0PSI0M3B4IiB2aWV3Qm94PSIwIDAgNjYgNDMiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPnJld2luZDwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz4gICAgICAgIDxmaWx0ZXIgeD0iLTUwJSIgeT0iLTUwJSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iZmlsdGVyLTEiPiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjAiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+ICAgICAgICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMS41IiBpbj0ic2hhZG93T2Zmc2V0T3V0ZXIxIiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVHYXVzc2lhbkJsdXI+ICAgICAgICAgICAgPGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAuOTQxMTc2NDcxICAgMCAwIDAgMCAwLjk2MDc4NDMxNCAgIDAgMCAwIDAgMC45ODAzOTIxNTcgIDAgMCAwIDAuMzUgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiIHR5cGU9Im1hdHJpeCIgcmVzdWx0PSJzaGFkb3dNYXRyaXhPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4gICAgICAgICAgICA8ZmVNZXJnZT4gICAgICAgICAgICAgICAgPGZlTWVyZ2VOb2RlIGluPSJzaGFkb3dNYXRyaXhPdXRlcjEiPjwvZmVNZXJnZU5vZGU+ICAgICAgICAgICAgICAgIDxmZU1lcmdlTm9kZSBpbj0iU291cmNlR3JhcGhpYyI+PC9mZU1lcmdlTm9kZT4gICAgICAgICAgICA8L2ZlTWVyZ2U+ICAgICAgICA8L2ZpbHRlcj4gICAgPC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJQbGF5ZXItdmVyc2lvbi0xIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzQyLjAwMDAwMCwgLTMwMi4wMDAwMDApIiBmaWx0ZXI9InVybCgjZmlsdGVyLTEpIiBmaWxsPSIjRkU0MzY1IiBmaWxsLW9wYWNpdHk9IjAuODUiPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0zNDUsMzA1IEwzNDUsMzQyIEwzNzUsMzIzLjkwMjE3NCBMMzQ1LDMwNSBMMzQ1LDMwNSBaIE0zNzUsMzA1IEwzNzUsMzQyIEw0MDUsMzIzLjc3NjEyIEwzNzUsMzA1IEwzNzUsMzA1IFoiIGlkPSJyZXdpbmQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM3NS4wMDAwMDAsIDMyMy41MDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTM3NS4wMDAwMDAsIC0zMjMuNTAwMDAwKSAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) 0 0 no-repeat;
}

.player .playarea .nextSong {
    cursor: pointer;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iNjZweCIgaGVpZ2h0PSI0M3B4IiB2aWV3Qm94PSIwIDAgNjYgNDMiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmZvcndhcmQ8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+ICAgICAgICA8ZmlsdGVyIHg9Ii01MCUiIHk9Ii01MCUiIHdpZHRoPSIyMDAlIiBoZWlnaHQ9IjIwMCUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9ImZpbHRlci0xIj4gICAgICAgICAgICA8ZmVPZmZzZXQgZHg9IjAiIGR5PSIwIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIj48L2ZlT2Zmc2V0PiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuNSIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlR2F1c3NpYW5CbHVyPiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwLjk0MTE3NjQ3MSAgIDAgMCAwIDAgMC45NjA3ODQzMTQgICAwIDAgMCAwIDAuOTgwMzkyMTU3ICAwIDAgMCAwLjM1IDAiIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiB0eXBlPSJtYXRyaXgiIHJlc3VsdD0ic2hhZG93TWF0cml4T3V0ZXIxIj48L2ZlQ29sb3JNYXRyaXg+ICAgICAgICAgICAgPGZlTWVyZ2U+ICAgICAgICAgICAgICAgIDxmZU1lcmdlTm9kZSBpbj0ic2hhZG93TWF0cml4T3V0ZXIxIj48L2ZlTWVyZ2VOb2RlPiAgICAgICAgICAgICAgICA8ZmVNZXJnZU5vZGUgaW49IlNvdXJjZUdyYXBoaWMiPjwvZmVNZXJnZU5vZGU+ICAgICAgICAgICAgPC9mZU1lcmdlPiAgICAgICAgPC9maWx0ZXI+ICAgIDwvZGVmcz4gICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+ICAgICAgICA8ZyBpZD0iUGxheWVyLXZlcnNpb24tMSIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU5Mi4wMDAwMDAsIC0zMDIuMDAwMDAwKSIgZmlsbC1vcGFjaXR5PSIwLjg1IiBmaWx0ZXI9InVybCgjZmlsdGVyLTEpIiBmaWxsPSIjRkU0MzY1Ij4gICAgICAgICAgICA8cGF0aCBkPSJNNTk1LDMwNSBMNTk1LDM0MiBMNjI1LDMyMy45MDIxNzQgTDU5NSwzMDUgTDU5NSwzMDUgWiBNNjI1LDMwNSBMNjI1LDM0MiBMNjU1LDMyMy43NzYxMiBMNjI1LDMwNSBMNjI1LDMwNSBaIiBpZD0iZm9yd2FyZCIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+) 0 0 no-repeat;
}

.player .playarea .prevSong,
.player .playarea .nextSong {
    vertical-align: middle;
    background-size: 66px 43px;
    width: 66px;
    height: 43px;
}

.player .playarea .prevSong:hover,
.player .playarea .nextSong:hover,
.player .playarea .pause:hover,
.player .playarea .play:hover,
.player .soundControl:hover {
    opacity: 0.7;
}

.player .song {
    font-family: Roboto, sans-serif;
    color: #FE4365;
    position: absolute;
    top: 225px;
    left: 0;
    width: 100%;
    text-align: center;
}

.player .song .artist {
    font-size: 22px;
    margin-bottom: 5px;
}

.player .song .name {
    font-size: 18px;
}

.player .soundControl {
    cursor: pointer;
    width: 31px;
    height: 27px;
    position: absolute;
    bottom: 240px;
    left: 50%;
    margin-left: -16px;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMzFweCIgaGVpZ2h0PSIyN3B4IiB2aWV3Qm94PSIwIDAgMzEgMjciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmhpZ2gtdm9sdW1lPC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPiAgICAgICAgPGZpbHRlciB4PSItNTAlIiB5PSItNTAlIiB3aWR0aD0iMjAwJSIgaGVpZ2h0PSIyMDAlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMSI+ICAgICAgICAgICAgPGZlT2Zmc2V0IGR4PSIwIiBkeT0iMCIgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSI+PC9mZU9mZnNldD4gICAgICAgICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxIiBpbj0ic2hhZG93T2Zmc2V0T3V0ZXIxIiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVHYXVzc2lhbkJsdXI+ICAgICAgICAgICAgPGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAuOTQxMTc2NDcxICAgMCAwIDAgMCAwLjk2MDc4NDMxNCAgIDAgMCAwIDAgMC45ODAzOTIxNTcgIDAgMCAwIDAuMzUgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiIHR5cGU9Im1hdHJpeCIgcmVzdWx0PSJzaGFkb3dNYXRyaXhPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4gICAgICAgICAgICA8ZmVNZXJnZT4gICAgICAgICAgICAgICAgPGZlTWVyZ2VOb2RlIGluPSJzaGFkb3dNYXRyaXhPdXRlcjEiPjwvZmVNZXJnZU5vZGU+ICAgICAgICAgICAgICAgIDxmZU1lcmdlTm9kZSBpbj0iU291cmNlR3JhcGhpYyI+PC9mZU1lcmdlTm9kZT4gICAgICAgICAgICA8L2ZlTWVyZ2U+ICAgICAgICA8L2ZpbHRlcj4gICAgPC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJQbGF5ZXItdmVyc2lvbi0xIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDgzLjAwMDAwMCwgLTQyNS4wMDAwMDApIiBmaWxsLW9wYWNpdHk9IjAuOCIgZmlsdGVyPSJ1cmwoI2ZpbHRlci0xKSIgZmlsbD0iI0ZFNDM2NSI+ICAgICAgICAgICAgPHBhdGggZD0iTTUwOC4wMDY2MzQsNDI3IEM1MTAuNTE0ODQ4LDQzMC4xNzU0ODQgNTEyLDQzNC4xODQ0NjMgNTEyLDQzOC41NDI0NyBDNTEyLDQ0Mi44NjE3MSA1MTAuNTQxMTUzLDQ0Ni44MzgxMDQgNTA4LjA3MzMyNiw0NTAgTDUwNi45NDMyNjksNDQ5LjE1MzQwNSBDNTA5LjI1OTIwNiw0NDYuMTgwMjQ0IDUxMC42NDk5OTksNDQyLjUxMTY5MSA1MTAuNjQ5OTk5LDQzOC41NDI0NyBDNTEwLjY0OTk5OSw0MzQuNTI5NDcyIDUwOS4yMjgzNTgsNDMwLjgyMzgwOSA1MDYuODY2MzAyLDQyNy44MzM0MTQgTDUwOC4wMDY2MzQsNDI3IEw1MDguMDA2NjM0LDQyNyBaIE01MDMuNjcwMjEyLDQ0Ni43MDEzNTggQzUwNS40OTczMjgsNDQ0LjQzNjg2IDUwNi41OTk5OTksNDQxLjYwOTMzMSA1MDYuNTk5OTk5LDQzOC41NDI0NjkgQzUwNi41OTk5OTksNDM1LjQxNDc0IDUwNS40NTMxMjQsNDMyLjUzNTkzNyA1MDMuNTYwNTcsNDMwLjI0OTQxOSBMNTAyLjU4MjY1OCw0MzAuOTY0MTI5IEM1MDQuMjQ4MDEsNDMzLjA4NDYzOCA1MDUuMjUwMDAxLDQzNS43MDU2MyA1MDUuMjUwMDAxLDQzOC41NDI0NjkgQzUwNS4yNTAwMDEsNDQxLjMxMzU1NCA1MDQuMjkzOTIyLDQ0My44Nzg2ODEgNTAyLjY5NzM4Nyw0NDUuOTcyNTU1IEw1MDMuNjcwMjEyLDQ0Ni43MDEzNTggTDUwMy42NzAyMTIsNDQ2LjcwMTM1OCBaIE00OTkuNjk0ODIsNDQzLjcyMzE0OSBDNTAxLjEwNTE0MSw0NDIuMjkzMTQ3IDUwMS45NzMwNzcsNDQwLjM0NDU3NSA1MDEuOTczMDc3LDQzOC4xOTcwMDcgQzUwMS45NzMwNzcsNDM2LjE2NjYzMiA1MDEuMTk3MjgyLDQzNC4zMTQxMjYgNDk5LjkyMDgwNSw0MzIuOTA5NTUxIEw0OTguOTQyMDkxLDQzMy42MjQ4NDcgQzQ5OS45NzUwOTUsNDM0Ljg3MjYxNSA1MDAuNTk0MjMxLDQzNi40NjM4MzUgNTAwLjU5NDIzMSw0MzguMTk3MDA3IEM1MDAuNTk0MjMxLDQ0MC4wNDE3OTQgNDk5Ljg5Mjc4NCw0NDEuNzI1NzU2IDQ5OC43Mzc0MjUsNDQzLjAwNTkwNSBMNDk5LjY5NDgyLDQ0My43MjMxNDkgTDQ5OS42OTQ4Miw0NDMuNzIzMTQ5IFogTTQ4NSw0MzUuMjExMjI1IEw0ODUsNDQxLjg3MzcxNSBMNDg5LjcyNSw0NDIuNDk3NDk0IEw0ODkuNzI1LDQzNC41MDI1MDYgTDQ4NSw0MzUuMjExMjI1IEw0ODUsNDM1LjIxMTIyNSBaIE00ODkuNzI1LDQ0Mi41Mzk5NjQgTDQ5Ni40NzUsNDQ3LjIwMzcwOCBMNDk2LjQ3NSw0MjkuODgxMjMyIEw0ODkuNzI1LDQzNC41NDQ5NzYgTDQ4OS43MjUsNDQyLjUzOTk2NCBaIiBpZD0iaGlnaC12b2x1bWUiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
    background-size: 31px 27px;
    text-align: center;
}

.player .soundControl.disable {
    opacity: 0.4;
}

.player .time {
    text-align: center;
    font-family: Roboto, sans-serif;
    color: #FE4365;
    position: absolute;
    left: 50%;
    margin-left: -22px;
    font-size: 20px;
    bottom: 190px;
}
JavaScript:
var Framer = {

        countTicks: 360,

        frequencyData: [],

        tickSize: 10,

        PI: 360,

        index: 0,

        loadingAngle: 0,

        init: function (scene) {
            this.canvas = document.querySelector('canvas');
            this.scene = scene;
            this.context = scene.context;
            this.configure();
        },

        configure: function () {
            this.maxTickSize = this.tickSize * 9 * this.scene.scaleCoef;
            this.countTicks = 360 * Scene.scaleCoef;
        },

        draw: function () {
            this.drawTicks();
            this.drawEdging();
        },

        drawTicks: function () {
            this.context.save();
            this.context.beginPath();
            this.context.lineWidth = 1;
            this.ticks = this.getTicks(this.countTicks, this.tickSize, [0, 90]);
            for (var i = 0, len = this.ticks.length; i < len; ++i) {
                var tick = this.ticks[i];
                this.drawTick(tick.x1, tick.y1, tick.x2, tick.y2);
            }
            this.context.restore();
        },

        drawTick: function (x1, y1, x2, y2) {
            var dx1 = parseInt(this.scene.cx + x1);
            var dy1 = parseInt(this.scene.cy + y1);

            var dx2 = parseInt(this.scene.cx + x2);
            var dy2 = parseInt(this.scene.cy + y2);

            var gradient = this.context.createLinearGradient(dx1, dy1, dx2, dy2);
            gradient.addColorStop(0, '#FE4365');
            gradient.addColorStop(0.6, '#FE4365');
            gradient.addColorStop(1, '#F5F5F5');
            this.context.beginPath();
            this.context.strokeStyle = gradient;
            this.context.lineWidth = 2;
            this.context.moveTo(this.scene.cx + x1, this.scene.cx + y1);
            this.context.lineTo(this.scene.cx + x2, this.scene.cx + y2);
            this.context.stroke();
        },

        setLoadingPercent: function (percent) {
            this.loadingAngle = percent * 2 * Math.PI;
        },

        drawEdging: function () {
            this.context.save();
            this.context.beginPath();
            this.context.strokeStyle = 'rgba(254, 67, 101, 0.5)';
            this.context.lineWidth = 1;

            var offset = Tracker.lineWidth / 2;
            this.context.moveTo(this.scene.padding + 2 * this.scene.radius - Tracker.innerDelta - offset, this.scene.padding + this.scene.radius);
            this.context.arc(this.scene.cx, this.scene.cy, this.scene.radius - Tracker.innerDelta - offset, 0, this.loadingAngle, false);

            this.context.stroke();
            this.context.restore();
        },

        getTicks: function (count, size, animationParams) {
            size = 10;
            var ticks = this.getTickPoitns(count);
            var x1, y1, x2, y2, m = [], tick, k;
            var lesser = 160;
            var allScales = [];
            for (var i = 0, len = ticks.length; i < len; ++i) {
                var coef = 1 - i / (len * 2.5);
                var delta = ((this.frequencyData[i] || 0) - lesser * coef) * this.scene.scaleCoef;
                if (delta < 0) {
                    delta = 0;
                }
                tick = ticks[i];
                if (animationParams[0] <= tick.angle && tick.angle <=  animationParams[1]) {
                    k = this.scene.radius / (this.scene.radius - this.getSize(tick.angle, animationParams[0], animationParams[1]) - delta);
                } else {
                    k = this.scene.radius / (this.scene.radius - (size + delta));
                }
                x1 = tick.x * (this.scene.radius - size);
                y1 = tick.y * (this.scene.radius - size);
                x2 = x1 * k;
                y2 = y1 * k;
                m.push({ x1: x1, y1: y1, x2: x2, y2: y2 });
                if (i < 20) {
                    var scale = delta / 50;
                    scale = scale < 1 ? 1 : scale;
                    allScales.push(scale);
                }
            }
            var sum = allScales.reduce(function(pv, cv) { return pv + cv; }, 0) / allScales.length;
            this.canvas.style.transform = 'scale('+sum+')';
            return m;
        },

        getSize: function (angle, l, r) {
            var m = (r - l) / 2;
            var x = (angle - l);
            var h;

            if (x == m) {
                return this.maxTickSize;
            }
            var d = Math.abs(m - x);
            var v = 70 * Math.sqrt(1 / d);
            if (v > this.maxTickSize) {
                h = this.maxTickSize - d;
            } else {
                h = Math.max(this.tickSize, v);
            }

            if (this.index > this.count) {
                this.index = 0;
            }

            return h;
        },

        getTickPoitns: function (count) {
            var coords = [], step = this.PI / count;
            for (var deg = 0; deg < this.PI; deg += step) {
                var rad = deg * Math.PI / (this.PI / 2);
                coords.push({ x: Math.cos(rad), y: -Math.sin(rad), angle: deg });
            }
            return coords;
        }
    };
    'use strict';

    var Tracker = {

        innerDelta: 20,

        lineWidth: 7,

        prevAngle: 0.5,

        angle: 0,

        animationCount: 10,

        pressButton: false,

        init: function (scene) {
            this.scene = scene;
            this.context = scene.context;
            this.initHandlers();
        },

        initHandlers: function () {
            var that = this;

            this.scene.canvas.addEventListener('mousedown', function (e) {
                if (that.isInsideOfSmallCircle(e) || that.isOusideOfBigCircle(e)) {
                    return;
                }
                that.prevAngle = that.angle;
                that.pressButton = true;
                that.stopAnimation();
                that.calculateAngle(e, true);
            });

            window.addEventListener('mouseup', function () {
                if (!that.pressButton) {
                    return;
                }
                var id = setInterval(function () {
                    if (!that.animatedInProgress) {
                        that.pressButton = false;
                        Player.context.currentTime = that.angle / (2 * Math.PI) * Player.source.buffer.duration;
                        clearInterval(id);
                    }
                }, 100);
            });

            window.addEventListener('mousemove', function (e) {
                if (that.animatedInProgress) {
                    return;
                }
                if (that.pressButton && that.scene.inProcess()) {
                    that.calculateAngle(e);
                }
            });
        },

        isInsideOfSmallCircle: function (e) {
            var x = Math.abs(e.pageX - this.scene.cx - this.scene.coord.left);
            var y = Math.abs(e.pageY - this.scene.cy - this.scene.coord.top);
            return Math.sqrt(x * x + y * y) < this.scene.radius - 3 * this.innerDelta;
        },

        isOusideOfBigCircle: function (e) {
            return Math.abs(e.pageX - this.scene.cx - this.scene.coord.left) > this.scene.radius ||
                    Math.abs(e.pageY - this.scene.cy - this.scene.coord.top) > this.scene.radius;
        },

        draw: function () {
            if (!Player.source.buffer) {
                return;
            }
            if (!this.pressButton) {
                this.angle = Player.context.currentTime / Player.source.buffer.duration * 2 * Math.PI || 0;
            }
            this.drawArc();
        },

        drawArc: function () {
            this.context.save();
            this.context.strokeStyle = 'rgba(254, 67, 101, 0.8)';
            this.context.beginPath();
            this.context.lineWidth = this.lineWidth;

            this.r = this.scene.radius - (this.innerDelta + this.lineWidth / 2);
            this.context.arc(
                    this.scene.radius + this.scene.padding,
                    this.scene.radius + this.scene.padding,
                    this.r, 0, this.angle, false
            );
            this.context.stroke();
            this.context.restore();
        },

        calculateAngle: function (e, animatedInProgress) {
            this.animatedInProgress = animatedInProgress;
            this.mx = e.pageX;
            this.my = e.pageY;
            this.angle = Math.atan((this.my - this.scene.cy - this.scene.coord.top) / (this.mx - this.scene.cx - this.scene.coord.left));
            if (this.mx < this.scene.cx + this.scene.coord.left) {
                this.angle = Math.PI + this.angle;
            }
            if (this.angle < 0) {
                this.angle += 2 * Math.PI;
            }
            if (animatedInProgress) {
                this.startAnimation();
            } else {
                this.prevAngle = this.angle;
            }
        },

        startAnimation: function () {
            var that = this;
            var angle = this.angle;
            var l = Math.abs(this.angle) - Math.abs(this.prevAngle);
            var step = l / this.animationCount, i = 0;
            var f = function () {
                that.angle += step;
                if (++i == that.animationCount) {
                    that.angle = angle;
                    that.prevAngle = angle;
                    that.animatedInProgress = false;
                } else {
                    that.animateId = setTimeout(f, 20);
                }
            };

            this.angle = this.prevAngle;
            this.animateId = setTimeout(f, 20);
        },

        stopAnimation: function () {
            clearTimeout(this.animateId);
            this.animatedInProgress = false;
        }
    };
    'use strict';

    var Scene = {

        padding: 120,

        minSize: 740,

        optimiseHeight: 982,

        _inProcess: false,

        init: function () {
            this.canvasConfigure();
            this.initHandlers();

            Framer.init(this);
            Tracker.init(this);
            Controls.init(this);

            this.startRender();
        },

        canvasConfigure: function () {
            this.canvas = document.querySelector('canvas');
            this.context = this.canvas.getContext('2d');
            this.context.strokeStyle = '#FE4365';
            this.calculateSize();
        },

        calculateSize: function () {
            this.scaleCoef = Math.max(0.5, 740 / this.optimiseHeight);

            var size = Math.max(this.minSize, 1/*document.body.clientHeight */);
            this.canvas.setAttribute('width', size);
            this.canvas.setAttribute('height', size);
            //this.canvas.style.marginTop = -size / 2 + 'px';
            //this.canvas.style.marginLeft = -size / 2 + 'px';

            this.width = size;
            this.height = size;

            this.radius = (size - this.padding * 2) / 2;
            this.cx = this.radius + this.padding;
            this.cy = this.radius + this.padding;
            this.coord = this.canvas.getBoundingClientRect();
        },

        initHandlers: function () {
            var that = this;
            window.onresize = function () {
                that.canvasConfigure();
                Framer.configure();
                that.render();
            };
        },

        render: function () {
            var that = this;
            requestAnimationFrame(function () {
                that.clear();
                that.draw();
                if (that._inProcess) {
                    that.render();
                }
            });
        },

        clear: function () {
            this.context.clearRect(0, 0, this.width, this.height);
        },

        draw: function () {
            Framer.draw();
            Tracker.draw();
            Controls.draw();
        },

        startRender: function () {
            this._inProcess = true;
            this.render();
        },

        stopRender: function () {
            this._inProcess = false;
        },

        inProcess: function () {
            return this._inProcess;
        }
    };
    'use strict';

    var Controls = {

        playing: false,

        init: function (scene) {
            this.scene = scene;
            this.context = scene.context;
            this.initHandlers();
            this.timeControl = document.querySelector('.time');
        },

        initHandlers: function () {
            this.initPlayButton();
            this.initPauseButton();
            this.initSoundButton();
            this.initPrevSongButton();
            this.initNextSongButton();
            this.initTimeHandler();
        },

        initPlayButton: function () {
            var that = this;
            this.playButton = document.querySelector('.play');
            this.playButton.addEventListener('mouseup', function () {
                that.playButton.style.display = 'none';
                that.pauseButton.style.display = 'inline-block';
                Player.play();
                that.playing = true;
            });
        },

        initPauseButton: function () {
            var that = this;
            this.pauseButton = document.querySelector('.pause');
            this.pauseButton.addEventListener('mouseup', function () {
                that.playButton.style.display = 'inline-block';
                that.pauseButton.style.display = 'none';
                Player.pause();
                that.playing = false;
            });
        },

        initSoundButton: function () {
            var that = this;
            this.soundButton = document.querySelector('.soundControl');
            this.soundButton.addEventListener('mouseup', function () {
                if (that.soundButton.classList.contains('disable')) {
                    that.soundButton.classList.remove('disable');
                    Player.unmute();
                } else {
                    that.soundButton.classList.add('disable');
                    Player.mute();
                }
            });
        },

        initPrevSongButton: function () {
            var that = this;
            this.prevSongButton = document.querySelector('.prevSong');
            this.prevSongButton.addEventListener('mouseup', function () {
                Player.prevTrack();
                that.playing && Player.play();
            });
        },

        initNextSongButton: function () {
            var that = this;
            this.nextSongButton = document.querySelector('.nextSong');
            this.nextSongButton.addEventListener('mouseup', function () {
                Player.nextTrack();
                that.playing && Player.play();
            });
        },

        initTimeHandler: function () {
            var that = this;
            setTimeout(function () {
                var rawTime = parseInt(Player.context.currentTime || 0);
                var secondsInMin = 60;
                var min = parseInt(rawTime / secondsInMin);
                var seconds = rawTime - min * secondsInMin;
                if (min < 10) {
                    min = '0' + min;
                }
                if (seconds < 10) {
                    seconds = '0' + seconds;
                }
                var time = min + ':' + seconds;
                that.timeControl.textContent = time;
                that.initTimeHandler();
            }, 300);
        },

        draw: function () {
            this.drawPic();
        },

        drawPic: function () {
            this.context.save();
            this.context.beginPath();
            this.context.fillStyle = 'rgba(254, 67, 101, 0.85)';
            this.context.lineWidth = 1;
            var x = Tracker.r / Math.sqrt(Math.pow(Math.tan(Tracker.angle), 2) + 1);
            var y = Math.sqrt(Tracker.r * Tracker.r - x * x);
            if (this.getQuadrant() == 2) {
                x = -x;
            }
            if (this.getQuadrant() == 3) {
                x = -x;
                y = -y;
            }
            if (this.getQuadrant() == 4) {
                y = -y;
            }
            this.context.arc(this.scene.radius + this.scene.padding + x, this.scene.radius + this.scene.padding + y, 10, 0, Math.PI * 2, false);
            this.context.fill();
            this.context.restore();
        },

        getQuadrant: function () {
            if (0 <= Tracker.angle && Tracker.angle < Math.PI / 2) {
                return 1;
            }
            if (Math.PI / 2 <= Tracker.angle && Tracker.angle < Math.PI) {
                return 2;
            }
            if (Math.PI < Tracker.angle && Tracker.angle < Math.PI * 3 / 2) {
                return 3;
            }
            if (Math.PI * 3 / 2 <= Tracker.angle && Tracker.angle <= Math.PI * 2) {
                return 4;
            }
        }
    };
    'use strict';

    var Player = {

        buffer: null,

        duration: 0,

        tracks: [
            {
                artist: "Kavinsky",
                song: "Odd Look ft. The Weeknd",
                url: "//katiebaca.com/tutorial/odd-look.mp3"
            }
        ],

        init: function () {
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            this.context = new AudioContext();
            this.context.suspend && this.context.suspend();
            this.firstLaunch = true;
            try {
                this.javascriptNode = this.context.createScriptProcessor(2048, 1, 1);
                this.javascriptNode.connect(this.context.destination);
                this.analyser = this.context.createAnalyser();
                this.analyser.connect(this.javascriptNode);
                this.analyser.smoothingTimeConstant = 0.6;
                this.analyser.fftSize = 2048;
                this.source = this.context.createBufferSource();
                this.destination = this.context.destination;
                this.loadTrack(0);

                this.gainNode = this.context.createGain();
                this.source.connect(this.gainNode);
                this.gainNode.connect(this.analyser);
                this.gainNode.connect(this.destination);

                this.initHandlers();
            } catch (e) {
                Framer.setLoadingPercent(1);
            }
            Framer.setLoadingPercent(1);
            Scene.init();
        },

        loadTrack: function (index) {
            var that = this;
            var request = new XMLHttpRequest();
            var track = this.tracks[index];
            document.querySelector('.song .artist').textContent = track.artist;
            document.querySelector('.song .name').textContent = track.song;
            this.currentSongIndex = index;

            request.open('GET', track.url, true);
            request.responseType = 'arraybuffer';

            request.onload = function() {
                that.context.decodeAudioData(request.response, function(buffer) {
                    that.source.buffer = buffer;
                });
            };

            request.send();
        },

        nextTrack: function () {
            return;
            ++this.currentSongIndex;
            if (this.currentSongIndex == this.tracks.length) {
                this.currentSongIndex = 0;
            }

            this.loadTrack(this.currentSongIndex);
        },

        prevTrack: function () {
            return;
            --this.currentSongIndex;
            if (this.currentSongIndex == -1) {
                this.currentSongIndex = this.tracks.length - 1;
            }

            this.loadTrack(this.currentSongIndex);
        },

        play: function () {
            this.context.resume && this.context.resume();
            if (this.firstLaunch) {
                this.source.start();
                this.firstLaunch = false;
            }
        },

        stop: function () {
            this.context.currentTime = 0;
            this.context.suspend();
        },

        pause: function () {
            this.context.suspend();
        },

        mute: function () {
            this.gainNode.gain.value = 0;
        },

        unmute: function () {
            this.gainNode.gain.value = 1;
        },

        initHandlers: function () {
            var that = this;

            this.javascriptNode.onaudioprocess = function() {
                Framer.frequencyData = new Uint8Array(that.analyser.frequencyBinCount);
                that.analyser.getByteFrequencyData(Framer.frequencyData);
            };
        }
    };
    Player.init();
Результат:
0054324414.gif


HTML:
<div class="music-player-container is-playing">

        <div class="music-player">
            <div class="player-content-container">
                <h1 class="artist-name">Incubus</h1><!--  /.track-title -->
                <h2 class="album-title">Make Yourself</h2><!--  /.album-title -->
                <h3 class="song-title">"Stellar"</h3><!--  /.song-title -->
                <div class="music-player-controls">
                    <div class="control-back"></div><!--  /.control-back -->
                    <div class="control-play"></div><!--  /.control-play -->
                    <div class="control-forwards"></div><!--  /.control-forwards -->
                </div><!--  /.music-player-controls -->
            </div><!--  /.player-content-container -->
        </div><!--  /.music-player -->

        <div class="album">
            <div class="album-art"></div><!--  /.album-art -->
            <div class="vinyl"></div><!--  /.vinyl -->
        </div><!--  /.album-art -->

    </div><!--  /.music-player -->
SCSS:
// Imports
@import 'bourbon';
@import url(https://fonts.googleapis.com/css?family=Raleway:400,300,700);

// Variables
$color-background: #fef29c;

// CSS

*, *:before, *:after {
    box-sizing: border-box;
}

body {
    background-color: $color-background;
    color: #515044;
    font-family: 'Raleway', sans-serif;
}// body

.music-player-container {
    @include transform( translate(-50%,-50%) );
    display: inline-block;
    height: 370px;
    position: absolute;
    min-width: 460px;
    left: 50%;
    top: 50%;

    &:after {
        @include filter(blur(8px));
        background-color: rgba(0,0,0,0.8);
        bottom: -2px;
        content: ' ';
        display: block;
        height: 10px;
        left: 19px;
        position: absolute;
        transform: rotate(-3deg);
        width: 70%;
        z-index: 0;
    }
}

.music-player {
    background-color: #fff;
    height: 370px;
    padding: 40px 250px 40px 40px;
    position: absolute;
    text-align: right;
    width: 460px;
    z-index: 3;
}// .music-player

.player-content-container {
    @include transform(translateY(-50%));
    top: 50%;
    position: relative;
}// .player-content-container

.artist-name {
    font-size: 28px;
    font-weight: normal;
    margin: 0 0 0.75em 0;
} // .artist-name

.album-title {
    font-weight: 200;
    font-size: 24px;
    margin: 0 0 1.75em 0;
}// .album-title

.song-title {
    font-size: 18px;
    font-weight: 200;
    margin: 0 0 1.5em 0;
}// .song-title

.album {
    box-shadow: 3px 3px 15px rgba(0,0,0,0.65);
    height: 315px;
    margin-left: 250px;
    margin-top: 27px;
    position: relative;
    width: 315px;
    z-index: 10;
}// .album

.album-art {
    background: #fff url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/incubus-make-yourself.jpg') center / cover no-repeat;
    height: 315px;
    position: relative;
    width: 315px;
    z-index: 10;
}

.vinyl {
    @include animation(spin 2s linear infinite);
    @include transition(all 500ms);
    background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/vinyl.png'), url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/incubus-make-yourself.jpg');
    background-position: center, center;
    background-size: cover, 40% auto;
    background-repeat: no-repeat;
    border-radius: 100%;
    box-shadow: 0 0 10px rgba(0,0,0,0.8);
    height: 300px;
    left: 0;
    position: absolute;
    top: 5px;
    width: 300px;
    z-index: 5;
    will-change: transform, left;

    .is-playing & {
        left: 52%;
    }
}

.music-player-controls {
    text-align: center;
}// .music-player-controls

[class^="control-"] {
    @include filter(brightness(95%));
    border-radius: 100%;
    display: inline-block;
    height: 44px;
    margin: 0 3px;
    width: 44px;


    &:hover {
        @include filter(brightness(85%));
        cursor: pointer;
    }// :hover
}// [class^="control-"]

.control-play {
    background: transparent url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/play.svg') center / cover no-repeat;

    .is-playing & {
        background: transparent url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/pause.svg') center / cover no-repeat;
    }// .control-play
}// .control-play

.control-forwards {
    background: transparent url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/forwards.svg') center / cover no-repeat;
}// control-forwards

.control-back {
    background: transparent url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/backwards.svg') center / cover no-repeat;
}// .control-back

@include keyframes(spin) {
    0% {
        @include transform(rotate(0deg));
    }
    100% {
        @include transform(rotate(360deg));
    }
}
JavaScript:
(function($) {
        $(document).ready(function() {

            // Pause/Play functionality
            var playButton = $('.control-play'),
                album = $('.album');

            playButton.on('click', function() {
                $('.music-player-container').toggleClass('is-playing');
            });
        });
    })(jQuery);
Результат:
0054324414а.gif
Автор
baltun
Скачиваний
0
Просмотры
590
Первый выпуск
Обновление
Рейтинг
0.00 звёзд Оценок: 0

Ещё ресурсы от baltun

Похожие ресурсы
Назад
Верх Низ