多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] #### 唱片飞入效果 ![](https://box.kancloud.cn/a270366155c27ece3ef5e2026141abdc_376x666.png) * [ ] 基础效果实现 ~~~ // 全屏播放器效果 <transition name="normal"></transition> // 迷你播放器效果 <transition name="mini"></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) ~~~ ~~~ .mini-enter-active, &.mini-leave-active transition: all 0.4s .mini-enter, &.mini-leave-to opacity: 0 ~~~ * [ ] 扩展效果 ~~~ <div class="player" v-show="playList.length > 0"> <!-- 全屏播放器 --> <transition name="normal" @enter="enter" @after-enter="afterEnter" @leave="leave" @after-leave="afterLeave" > <div class="normal-player" v-show="fullScreen"> ~~~ * [ ] 图示 ![](https://box.kancloud.cn/d10dcf5b536ac78f9155231857594186_376x668.png) ``` import { PlayerMixin } from 'utils/mixin' import animations from 'create-keyframe-animation' methods: { // 动画即将出现,设置动画结束位置 enter (el, done) { // 动画即将开始,设置动画初始坐标 const { 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' } }) // 执行动画,调用done函数跳到afterEnter函数 animations.runAnimation(this.$refs.cdWrapper, 'move', done) }, afterEnter () { // 清除动画 animations.unregisterAnimation('move') this.$refs.cdWrapper.style.animation = '' }, // 动画结束 leave (el, done) { this.$refs.cdWrapper.style.transition = 'all 0.4s' const { x, y, scale } = this._getPosAndScale() this.$refs.cdWrapper.style[transform] = `translate3d(${x}px,${y}px,0) scale(${scale})` const timer = setTimeout(done, 400) this.$refs.cdWrapper.addEventListener('transitionend', () => { clearTimeout(timer) done() }) }, // 清除参数 afterLeave () { this.$refs.cdWrapper.style.transition = '' this.$refs.cdWrapper.style[transform] = '' }, // 动画初始位置 _getPosAndScale () { const targetWidth = 40 // 迷你播放球宽度 const paddingLeft = 40 // 迷你播放器距离左边偏移 const paddingBottom = 30 // 迷你播放球距离底部偏移 const paddingTop = 80 // 顶部导航宽度 const width = window.innerWidth * 0.8 // 大播放球宽度80% const scale = targetWidth / width // 初始缩放比例 const x = -(window.innerWidth / 2 - paddingLeft) // 迷你播放器初始X坐标 // 迷你播放球初始Y坐标 const y = window.innerHeight - paddingTop - width / 2 - paddingBottom return { x, y, scale } } } ```