create-keyframe-animation插件使用

如何实现这个动画?

 效果分析


点`start`的时候,我们把整个动画拆分为两种效果(过渡和动画)。

1. 中间cd消失,下方播放条显示,这是属于`过渡`

2. `过渡`开始的同时,cd同时移动、放大、缩小到左下方播放条 ,这属于`动画`

上面的效果是【过渡】加【动画】同时使用完成的

对于第一种【过渡】,我们用vue中transition标签,加设置v-enter、v-leave-to、v-enter-active、v-leave-enter即可完成

对于第二种【动画】,我们就要用keyframe来完成了。

这里我们先完成第一种过渡

vue中模板节点

<template>

 <divclass="index">

 <transition>

  <divclass="cd-box"ref="cdWrapper"v-show="fullScreen">

 // CD图片 (动画的时候图片初始位置)

  <imgsrc="../assets/bj.png"alt=""class="bg">

  </div>

 </transition>

 <button@click="switchMode"style="position:absolute;top:0;left:10px;">start</button>

 <transition>

 // 下面播放状态框

  <divclass="mini-player-box"v-show="!fullScreen">

 // 状态看里面的图片 (动画的时候图片结束位置)

  <divclass="mini-img">

   <imgsrc="../assets/bj.png"alt="">

  </div>

  </div>

 </transition>

 </div>

</template>

结构很简单,基本就是 两个大div ,然后把div的布局按效果图那些布置。

css部分(省略布局部分)

.cd-box

 &.v-enter-active, &.v-leave-active

  transition: all0.4s

 &.v-enter, &.v-leave-to

  opacity: 0

.mini-player-box

 &.v-enter-active, &.v-leave-active

  transition: all0.4s

 &.v-enter, &.v-leave-to

  transform: translate3d(0, 40px, 0)

  opacity: 0

这样在fullScreen变量改变的时候,就会触发【过渡】

这里我们完成第二种动画

首先安装插件 , npm i create-keyframe-animation 这个插件是用js写css的keyframe动画用的,至于为什么keyframe不在css里面写呢?那是因为屏幕大小不一样,会导致需要移动的px不一样,所以要动态计算。

给 <transition> 添加动画钩子

<transition >

  @enter="enter"

  @after-enter="afterEnter"

  @leave="leave"

  @after-leave="afterLeave"

 >

  <div class="cd-box"ref="cdWrapper"v-show="fullScreen">

  <img src="../assets/bj.png"alt=""class="bg">

  </div>

 </transition>

// 获得偏移量,以及scale

_getPosAndScale() {

 // 左下角图片的宽度

  const targetWidth = 40

 // cd宽度

  const width = 300

  const scale = targetWidth / width

  // 这里的 x,y要算,过程省略,无非就是加加减减,这的x,y都是算出来了的

  const x = -167.5

  const y = 497

  return{x ,y , scale}

 },

那么动画从 cd中心到左下角,X偏移为负,y偏移为正

然后用animations插件执行动画钩子

// enter是指当 cd从隐藏到显示的动画,

 enter(el, done) {

  const {x, y, scale} = this._getPosAndScale()


  let animation = {

  // 第0帧的时候,先让图片缩小,显示在右下角

  0: {

   transform: `translate3d(${x}px, ${y}px, 0) scale(${scale})`

  },

  // 60%的时候,让图片回到cd中心,变大

  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(){

 //运行完动画之后,注销掉动画

  animations.unregisterAnimation('move')

  this.$refs.cdWrapper.style.animation = ''

 },

 // leave是指 cd从显示到隐藏的动画

 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})`


 // 监听transitionend 事件在 CSS 完成过渡后触发done回调 

 this.$refs.cdWrapper.addEventListener('transitionend', () => {

  done()

  })

 },

 afterLeave() {

  this.$refs.cdWrapper.style.transition = ''

  this.$refs.cdWrapper.style['transform'] = ''

 }

写到这里,我们就把刚开始的效果给写完啦!

但在写js的keyframe的时候

我们还可以加上rotate,让动画效果有一个回弹效果

let animation = {

  0: {

   transform: `translate3d(${x}px, ${y}px, 0) scale(${scale}) rotate(0deg)`

  },

  60: {

   transform: `translate3d(0 ,0 , 0) scale(1.1) rotate(365deg)`

  },

  100: {

   transform: `translate3d(0 ,0 , 0) scale(1) rotate(360deg)`

  }

  }

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。