歌曲数据应用
上小节中,基础样式ok后,这里使用点击的当前歌曲数据信息填充界面
首先要获取当前歌曲的信息,根据播放列表和当前歌曲的索引进行获取
src/store/getters.js
export const currentSong = (state) => {
return state.playlist[state.currentIndex] || {}
}
<template>
<!--主要分为两大块内容:1. 全屏播放器 2, 迷你播放器-->
<div class="player" v-show="playlist.length >0">
<div class="normal-player" v-show="fullScreen">
<!--背景图-->
<div class="background">
<img width="100%" height="100%" :src="currentSong.image">
</div>
<!--顶部信息-->
<div class="top">
<div class="back" @click="back">
<i class="icon-back"></i>
</div>
<h1 class="title" v-html="currentSong.name"></h1>
<h2 class="subtitle">{{currentSong.singer}}</h2>
</div>
<!--唱片转动效果-->
<div class="middle">
<div class="middle-l">
<div class="cd-wrapper">
<div class="cd">
<img class="image" :src="currentSong.image">
</div>
</div>
</div>
</div>
<!--底部操作区-->
<div class="bottom">
<div class="operators">
<div class="icon i-left">
<i class="icon-sequence"></i>
</div>
<div class="icon i-left">
<i class="icon-prev"></i>
</div>
<div class="icon i-center">
<i class="icon-play"></i>
</div>
<div class="icon i-right">
<i class="icon-next"></i>
</div>
<div class="icon i-right">
<i class="icon-not-favorite"></i>
</div>
</div>
</div>
</div>
<div class="mini-player" v-show="!fullScreen" @click="open">
<div class="icon">
<img width="40" height="40" :src="currentSong.image">
</div>
<div class="text">
<h2 class="name" v-html="currentSong.name"></h2>
<p class="desc">{{currentSong.singer}}</p>
</div>
<div class="control"></div>
<div class="control">
<i class="icon-playlist"></i>
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import { mapGetters, mapMutations } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapGetters([
'fullScreen',
'playlist',
'currentSong'
])
},
methods: {
// 这里也可以像上面那样简写
// 但是 我们一般的习惯是 方法名驼峰写法,所以要映射
...mapMutations({
setFullScreen: 'SET_FULL_SCREEN'
}),
back () {
this.setFullScreen(false)
},
open () {
this.setFullScreen(true)
}
}
}
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable"
@import "~common/stylus/mixin"
.player {
// 这里并必须要分开写,不然就会影响迷你播放器下的样式。
.normal-player {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background $color-background
.background {
position absolute
left 0
top 0
right 0
bottom 0
z-index: -1
opacity: 0.6
filter: blur(20px)
}
.top {
position relative
margin-bottom 25px
.back {
position absolute
top 0
left 6px
.icon-back {
display block
padding 9px
font-size $font-size-large-x
color $color-theme
transform rotate(-90deg)
}
}
.title {
width 70%
margin 0 auto
text-align center
line-height 40px
no-wrap()
font-size $font-size-large
color $color-text
}
.subtitle {
text-align center
line-height 20px
font-size $font-size-medium
color $color-text
}
}
.middle {
position absolute
top 80px
bottom 170px
width 100%
font-size 0
white-space nowrap
.middle-l {
display: inline-block
vertical-align: top
position: relative
width: 100%
// padding 的百分比始终参考的是 宽度值,而这里宽度是100%
// 而 内部的cd-wrapper 的宽度是百分之 80%,高为100%
// 所以 middle-l 的高是 宽度的 80%,而 cd-wrapper的高为100%也就是和 middle-l的高一致
// 而 cd-wrapper de 宽为80%,那么就和middle-l的高度一致,正方形
padding-top: 80%
.cd-wrapper {
position: absolute
left: 10% // 左右10% + 宽80% 刚好让这个容器居中
top: 0
width: 80%
height: 100%
.cd {
width 100%
height 100%
border 10px solid rgba(255, 255, 255, 0.1)
border-radius: 50%
box-sizing border-box // 任何内边距和边框都将在已设定的宽度和高度内进行绘制。让绘制的圆形始终在限制的高度内
&.play {
animation: rotate 20s linear infinite
}
&.pause {
animation-play-state: paused // css3属性 动画是否暂停 或则运行
}
.image {
position absolute
left 0
top 0
width 100%
height 100%
border-radius 50%
}
}
}
}
}
.bottom {
position absolute
bottom 50px
width 100%
.operators {
display flex
align-items center // 当高度不一致的时候,能让他们垂直居中
.icon {
flex 1
color $color-theme
&.disable {
color $color-theme-d
}
i {
font-size 30px
}
}
.i-left {
text-align right
}
.i-center {
text-align center
padding 0 20px
i {
font-size 40px
}
}
.i-right {
text-align left
}
.icon-favorite {
color: $color-sub-theme
}
}
}
}
.mini-player {
position fixed
bottom 0
right 0
left 0
height 60px
background $color-highlight-background
display flex
align-items center // 所有元素垂直居中
.icon {
display 0 0 40px
padding: 0 10px 0 20px
img {
border-radius 50%
&.play {
animation: rotate 10s linear infinite
}
&.pause {
animation-play-state: paused
}
}
}
.text {
flex 1
display flex
flex-direction column // 垂直布局
justify-content center
line-height 20px
overflow hidden
.name {
no-wrap()
font-size $font-size-medium
color $color-text
margin-bottom 2px
}
.desc {
no-wrap()
font-size $font-size-small
color $color-text-d
}
}
.control {
flex 0 0 30px
width 30px
padding 0 10px
.icon-play-mini, .icon-pause-mini, .icon-playlist {
font-size: 30px
color: $color-theme-d
}
/* .icon-mini {
font-size: 32px
position: absolute
left: 0
top: 0
}*/
}
}
@keyframes rotate {
0% {
transform: rotate(0)
}
100% {
transform: rotate(360deg)
}
}
}
</style>