样式
音乐列表
音乐列表需要一个滚动的效果,因此再次借助了BetterScroll
创建一个scroll的组件
<template>
<div ref="scroll">
<slot></slot>
</div>
</template>
<script>
import BScroll from '@better-scroll/core'
import ObserveDOM from '@better-scroll/observe-dom'
export default {
name:'Scroll',
data() {
return {
scrollVal:null
}
},
created(){
},
mounted() {
BScroll.use(ObserveDOM)
this.scrollVal = new BScroll(this.$refs.scroll,{
probeType: 3,
pullUpLoad: true,
observeDOM:true,
click:true,
mouseWheel: true,//开启鼠标滚轮
disableMouse: false,//启用鼠标拖动
disableTouch: false//启用手指触摸
})
this.scrollVal.on('scroll', (positon) => {
// 发射出scroll方法,可以实时获取移动的距离
this.$emit('scroll',positon)
})
},
updated() {
},
methods: {
},
}
</script>
<style>
</style>
借助scroll返回的方法实现样式滚动效果
<template>
<div class="album">
<div class="music-list">
<div class="back">
<i @click="$router.go(-1)" class="icon-back"></i>
</div>
<h1 class="title">{{albumData.title || albumData.name}}</h1>
<div class="bg-image" :style="bgImageStyle" ref="bgImg">
<div class="play-btn-wrapper" :style="playBtnStyle">
<div class="play-btn">
<i class="icon-play"></i>
<span class="text" @click="randomPlay">随机播放全部</span>
</div>
</div>
<div class="filter" :style="filterStyle"></div>
</div>
<!-- 列表 -->
<scroll class="list" @scroll="onScroll" :style="scrollStyle">
<song-list :songs='songs' @select="selectSong"></song-list>
</scroll>
</div>
</div>
</template>
<script>
import songList from '@/component/song-list/song-list.vue'
import Scroll from '../../component/scroll/scroll.vue'
export default {
components: { songList, Scroll },
name:'Album',
data() {
return {
head_hight:40,
scrollY:'',
imgHeight:'',
maxTransLateY:''
}
},
props:{
songs:{
type:Array,
default:()=>[]
},
albumData:{
type:Object,
default:()=>{}
}
},
watch:{
songs(newVal){
console.log(newVal);
}
},
// 在dom结构加载完毕之后进行获取scroll可向上移动的最大距离
mounted() {
this.imgHeight = this.$refs.bgImg.clientHeight
this.maxTransLateY = this.imgHeight - this.head_hight
},
computed:{
// 顶部背景
// 动态变化顶部背景样式
bgImageStyle(){
let height = 0
let zIndex = 0
let paddingTop = '70%'
// 当拖动距离大于最大移动距离时
// 则将顶部的图片层级提高,这样就可以阻止scroll继续向上,从而开始内部向上滚动
// 并且将height高度固定
if(this.scrollY>this.maxTransLateY){
zIndex = 10
height = '40px'
paddingTop = 0
}
let scale = 1
// 拖动y轴小于0时,则开始按比例进行设置缩放数值
if(this.scrollY<0) {scale = 1+ Math.abs(this.scrollY/this.imgHeight)}
return {
zIndex,
height,
paddingTop,
backgroundImage: `url(${this.albumData.pic})`,
transform:`scale(${scale})translateZ(1px)`
}
},
// scroll定位
scrollStyle() {
const bottom = this.songs.length ? '60px' : '0'
return {
top: `${this.imgHeight}px`,
bottom
}
},
// 随机播放按钮样式
playBtnStyle() {
let display = ''
if(this.scrollY>=this.maxTransLateY) display = 'none'
return {
display
}
},
// 高斯模糊
filterStyle(){
let blur = 0
if(this.scrollY>0){
// 这样即可控制最大的模糊程度
blur = Math.min(this.maxTransLateY/this.imgHeight,this.scrollY/this.imgHeight)*20
}
return {
backdropFilter: `blur(${blur}px)`
}
}
},
methods: {
// 滚动时间
onScroll(pos){
this.scrollY = -(pos.y)
},
// songs点击
selectSong(index){
let songs = this.songs
this.$store.dispatch('selectPlay',{songs,index})
},
// 随机播放
randomPlay(){
let songs = this.songs
this.$store.dispatch('randomPlay',songs)
}
},
}
</script>
<style lang='scss' scoped>
.album {
position: fixed;
z-index: 10;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: $color-background;
}
.music-list {
position: relative;
height: 100%;
.back {
position: absolute;
z-index: 20;
top: 0;
left: 6px;
.icon-back {
display: block;
padding: 10px;
color: $color-theme;
font-size: $font-size-large-x;
}
}
.title {
position: absolute;
z-index: 20;
top: 0;
left: 10%;
width: 80%;
text-align: center;
line-height: 40px;
color: $color-theme;
font-size: $font-size-large;
@include no-wrap();
}
.bg-image {
position: relative;
width: 100%;
background-size: cover;
.play-btn-wrapper {
position: absolute;
bottom: 20px;
z-index: 20;
width: 100%;
.play-btn {
box-sizing: border-box;
width: 135px;
padding: 7px 0;
margin: 0 auto;
text-align: center;
border: 1px solid $color-theme;
border-radius: 100px;
font-size: $font-size-medium;
color: $color-theme;
}
}
.filter {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(7, 17, 27, .4);
}
}
.list {
position: absolute;
bottom: 0;
width: 100%;
z-index: 0;
}
}
</style>