歌曲数据应用

上小节中,基础样式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>
© All Rights Reserved            updated 2017-12-28 02:49:41

results matching ""

    No results matching ""