|
<div class="app"> |
|
<section class="player"> |
|
<img class="player__cover" :src="currentTrack.cover.large" alt="" /> |
|
<div class="player__timer"> |
|
<div class="player__timer__elapsed" v-text="player.elapsed | time"></div> |
|
<div class="player__timer__total" v-text="currentTrack.duration | time"></div> |
|
</div> |
|
<div class="slider player__progress-bar"> |
|
<input type="range" :value="player.elapsed" :max="currentTrack.duration" /> |
|
</div> |
|
<ul class="player__controls"> |
|
<li |
|
class="control control--small" |
|
v-bind:class="{ |
|
'control--active' : player.repeat, |
|
'control--dimmed' : !player.repeat |
|
}" |
|
@click="toggleRepeat" |
|
> |
|
<svg class="icon" viewbox="0 0 100 100"> |
|
<use xlink:href="#repeat"></use> |
|
</svg> |
|
</li> |
|
<li class="control" @click="skipBack"> |
|
<svg class="icon" viewbox="0 0 100 100" > |
|
<use xlink:href="#skip-back"></use> |
|
</svg> |
|
</li> |
|
<li class="control control--outlined"> |
|
<svg |
|
class="icon" |
|
viewbox="0 0 100 100" |
|
@click="play" |
|
v-if="!player.playing" |
|
> |
|
<use xlink:href="#play"></use> |
|
</svg> |
|
<svg |
|
class="icon" |
|
viewbox="0 0 100 100" |
|
@click="pause" |
|
v-if="player.playing" |
|
> |
|
<use xlink:href="#pause"></use> |
|
</svg> |
|
</li> |
|
<li class="control" @click="skipForward"> |
|
<svg class="icon" viewbox="0 0 100 100"> |
|
<use xlink:href="#skip-forward"></use> |
|
</svg> |
|
</li> |
|
<li |
|
class="control control--small" |
|
v-bind:class="{ |
|
'control--active' : player.shuffle, |
|
'control--dimmed' : !player.shuffle |
|
}" |
|
@click="toggleShuffle" |
|
> |
|
<svg class="icon" viewbox="0 0 100 100"> |
|
<use xlink:href="#shuffle"></use> |
|
</svg> |
|
</li> |
|
</ul> |
|
<h1 class="player__title" v-text="currentTrack.title"></h1> |
|
<h2 class="player__sub-title">{{currentTrack.album}} - {{currentTrack.artist}}</h2> |
|
<div class="player__volume"> |
|
<div class="player__volume__icon"> |
|
<svg class="icon" viewbox="0 0 100 100"> |
|
<use xlink:href="#volume"></use> |
|
</svg> |
|
</div> |
|
<div class="slider slider--volume player__volume__slider"> |
|
<input type="range" :value="player.volume" max="100" /> |
|
</div> |
|
</div> |
|
</section> |
|
<aside class="playlist"> |
|
<header class="playlist__header"> |
|
<h1 class="playlist__title" v-text="playlist.title"></h1> |
|
<div class="playlist__info"> |
|
<a href="#" v-text="playlist.author"></a> - {{playlist.tracks.length}} songs, {{playlistDuration | minutes}} min |
|
<a href="#"> |
|
<svg class="icon icon--inline" viewbox="0 0 100 100"> |
|
<use xlink:href="#share"></use> |
|
</svg> |
|
</a> |
|
</div> |
|
</header> |
|
<ol class="playlist__list"> |
|
<li |
|
class="playlist__track" |
|
@click="selectTrack($index)" |
|
v-bind:class="{'playlist__track--active': player.currentTrack === $index}" |
|
v-for="track in playlist.tracks" |
|
> |
|
<img :src="track.cover.small" class="playlist__track__cover" /> |
|
<div class="playlist__track__info"> |
|
<h3 class="playlist__track__title" v-text="track.title"></h3> |
|
<span class="playlist__track__sub-title">{{track.album}} - {{track.artist}}</span> |
|
</div> |
|
<span class="playlist__track__time" v-text="track.duration | time"></span> |
|
</li> |
|
</ol> |
|
</aside> |
|
</div> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="hide"> |
|
<symbol id="play" viewBox="0 0 23.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M23 11.6L6.7 2.4c-1.4-.8-2.6 0-2.6 1.8V22c0 1.8 1.2 2.7 2.6 1.8L23 14.6c1.5-.8 1.5-2.2 0-3z" /> |
|
</symbol> |
|
<symbol id="repeat" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.1 2.1v4h-10c-3.3 0-6 2.7-6 6 0 1 .3 1.9.7 2.8l2.5-1.8c-.1-.3-.2-.7-.2-1 0-1.7 1.3-3 3-3h10v4l8-5v-1l-8-5zm4.8 11c.1.3.2.7.2 1 0 1.7-1.3 3-3 3h-10v-4l-8 5v1l8 5v-4h10c3.3 0 6-2.7 6-6 0-1-.3-1.9-.7-2.8l-2.5 1.8z" |
|
/> |
|
</symbol> |
|
<symbol id="share" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.1 23.1h-20v-20h10l2-2h-12c-1.1 0-2 .9-2 2v20c0 1.1.9 2 2 2h20c1.1 0 2-.9 2-2v-7l-2 2v5zm-18-2c3-8 7-8 13-8v4l7-7-7-7v4c-13 0-13 10-13 14z" /> |
|
</symbol> |
|
<symbol id="shuffle" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.1 1.1v4h-3c-3.3 0-6 2.7-6 6v4c0 1.7-1.3 3-3 3h-4v3h4c3.3 0 6-2.7 6-6v-4c0-1.7 1.3-3 3-3h3v4l8-5v-1l-8-5zM6.4 8.4L8.2 6c-.9-.6-2-.9-3.1-.9h-4v3h4c.5 0 .9.1 1.3.3zm10.7 9.7h-3c-.5 0-.9-.1-1.3-.3L11 20.2c.9.6 2 .9 3.1.9h3v4l8-5v-1l-8-5v4z" |
|
/> |
|
</symbol> |
|
<symbol id="skip-back" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3 5.3l-8.2 4.8V6.7c0-1.3-.8-1.9-1.8-1.3L6.1 9.5V7.1c0-1.1-.9-2-2-2h-1c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h1c1.1 0 2-.9 2-2v-2.4l7.2 4.2c1 .6 1.8 0 1.8-1.3v-3.5l8.2 4.8c1 .6 1.8 0 1.8-1.3V6.7c0-1.4-.8-2-1.8-1.4z" |
|
/> |
|
</symbol> |
|
<symbol id="skip-forward" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.1 5.1h-1c-1.1 0-2 .9-2 2v2.4l-7.2-4.2c-1-.6-1.8 0-1.8 1.3v3.5L2.9 5.3c-1-.6-1.8 0-1.8 1.3v12.9c0 1.3.8 1.9 1.8 1.3l8.2-4.8v3.5c0 1.3.8 1.9 1.8 1.3l7.2-4.2V19c0 1.1.9 2 2 2h1c1.1 0 2-.9 2-2V7c0-1-.9-1.9-2-1.9z" |
|
/> |
|
</symbol> |
|
<symbol id="volume" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.1 13.1c0-3.3-2-6.2-4.9-7.4l-.8 1.8c2.2.9 3.7 3 3.7 5.5s-1.5 4.6-3.7 5.5l.8 1.8c2.9-1 4.9-3.9 4.9-7.2zm-4 0c0-1.7-1-3.1-2.5-3.7l-.8 1.8c.7.3 1.2 1 1.2 1.8s-.5 1.5-1.2 1.8l.8 1.8c1.5-.4 2.5-1.8 2.5-3.5zM17.7 2l-.8 1.8c3.6 1.5 6.2 5.1 6.2 9.2 0 4.2-2.5 7.7-6.2 9.2l.8 1.8c4.3-1.8 7.4-6.1 7.4-11.1s-3-9.1-7.4-10.9zM1.1 8.1v10h4l7 7v-24l-7 7h-4z" |
|
/> |
|
</symbol> |
|
<symbol id="pause" viewBox="0 0 26.2 26.2"> |
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.1 2.1h-4c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h4c1.1 0 2-.9 2-2v-18c0-1.1-.9-2-2-2zm14 0h-4c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h4c1.1 0 2-.9 2-2v-18c0-1.1-.9-2-2-2z" /> |
|
</symbol> |
|
</svg> |