点击歌曲时,出现播放器,为避免页面切换太生硬,给播放器展开和收起添加动画。
动画1:播放器顶部标题部分由上至下滑动,播放器底部由下至上滑动
给播放器所在div包裹上transition,并指定name为normal
<transition name="normal">
<div class="normal-player">
//.......
<div class="top></div>
<div class="bottom></div>
</div>
</transition>
组件过渡过程中,会有四个CSS类名进行切换,这四个类名与上面transition的name属性有关,比如name="normal",会有如下四个CSS类名:
normal-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立即删除;
normal-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成之后移除;
normal-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立即删除;
normal-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成之后被删除;
从上面四个类名可以看出,fade-enter-active和fade-leave-active在整个进入或离开过程中都有效,所以CSS的transition属性在这两个类下进行设置。
&.normal-enter-active, &.normal-leave-active
transition: all 0.4s
.top, .bottom
transition: all 0.4s cubic-bezier(0.86, 0.18, 0.82, 1.32)
&.normal-enter, &.normal-leave-to
opacity: 0
.top
transform: translate3d(0, -100px, 0)
.bottom
transform: translate3d(0, 100px, 0)
动画2:歌曲图片在由mini-player过渡到normal-player的动画
这个动画使用transition的事件函数实现。
<transition name="normal">
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:leave="leave"
v-on:after-leave="afterLeave"
>
methods: {
//设置过渡进入完成时的组件状态
enter:function(el, done){
// ...
done()
},
//设置过渡进入完成之后的组件状态
afterEnter:function(el){
// ...
},
//设置过渡离开完成时地组件状态
leave:function(el, done){
// ...
done()
},
//设置过渡离开完成之后的组件状态
afterLeave:function(el){
// ...
}
}
在enter函数中,设置图片的位移和放大缩小等动画。需要演示图片从左下角mini-player图片的位置位移至中间cdWrapper的位置,并且放大缩小相应的倍数。由于需要中间的动画帧,使用create-keyframe-animation插件
使用_getPosAndScale函数来获取图片位移的x,y和放大缩小比例scale,函数返回{x, y, scale}
在enter函数中,设置animation动画,注册和运行动画:
enter(el, done) {
let {x, y, scale} = this._getPosAndScale()
let animation = {
0: {
transform: `translate3d(${x}px, ${y}px, 0) scale(${scale})`
},
60: {
transform: 'translate3d(0, 0 ,0) scale(1.1)'
},
100: {
transform: `translate3d(0, 0, 0) scale(1)`
}
}
animations.registerAnimation({
name: 'move',
animation,
presets: {
duration: 400,
easing: 'linear'
}
})
animations.runAnimation(this.$refs.cdWrapper, 'move', done)
}
在afterEnter函数中,unregisterAnimation并且清除元素style的animation:
afterEnter() {
animations.unregisterAnimation('move')
this.$refs.cdWrapper.style.animation = ''
}
在leave函数中,由于不需要中间帧的动画,可以使用js直接操作元素:
leave(el, done) {
this.$refs.cdWrapper.style.transition = 'all 0.4s'
let {x, y, scale} = this._getPosAndScale()
this.$refs.cdWrapper.style[transform] = `translate3d(${x}px, ${y}px, 0) scale(${scale})`
this.$refs.cdWrapper.addEventListener('transitionend', done)
}
同样的,在afterLeave函数中,需要清除动画的样式:
afterLeave() {
this.$refs.cdWrapper.style.transition = ''
this.$refs.cdWrapper.style[transform] = ''
}