创建弹簧动画

该文章发布于 ,归类于 Javascript 0 条评论

本篇文章有感于:https://juejin.im/post/5bbb67456fb9a05d2c43c66a

创建关键帧动画时,通过设置特定时间段内展示效果,可以模拟类似的弹簧弹动效果,抖动效果等等。

但是,以弹动效果为例,如果你按照如下方式这样写,看起来根本是不像弹动效果的

@keyframes springGrow {
  0% {
    transform: scale(0);
  }
  90% {
    transform: scale(1);
  }
  95% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

本意是在90%到100%之间的时间段先放大,再还原到初始大小,模拟弹动,但是实际上并不像是弹动,看起来十分生硬。

上面的效果是这样的

See the Pen oaZvYj by Leevare (@leevare) on CodePen.

为了实现更加逼真的效果,已经有人早好了轮子,拿过来用即可。

这里,我使用css-springcreate-keyframe-animation两个库,使用css-spring生成关键帧,再用create-keyframe-animation来展现最终动画效果。

首先创建连续的帧动画

spring(
  {scale: 0},
  {scale: 1},
  { damping: 14, precision: 2 }
)

生成如下的形式

0%: {scale: 0.02}
1%: {scale: 0.05}
2%: {scale: 0.1}
3%: {scale: 0.15}
4%: {scale: 0.22}
....
100%: {scale: 1}

接着将其应用到样式中展现出来就可以了

_animateSpringGrow (...keyframeObjects) {
  let keyframes = spring(
    ...keyframeObjects,
    { damping: 14, precision: 2 }
  )

  animations.registerAnimation({
    name: 'springGrow',
    animation: keyframes,
    presets: {
      duration: 1000,
      easing: 'linear'
    }
  })

  animations.runAnimation(this.$refs.box, 'springGrow')
}

通过传入不同的参数展现为不同的效果

this._animateSpringGrow({ scale: 0 }, { scale: 1 })

差不多就是这样了。

最终效果是这样的

这里放上实现代码

<template>
  <div>
    <div class="box" ref="box"></div>

    <button @click="show">show</button>
    <button @click="hide">hide</button>
  </div>
</template>

<script>

  import animations from 'create-keyframe-animation'
  import spring from 'css-spring'

  export default {
    methods: {
      show () {
        this.$refs.box.style.display = ''
        this._animateSpringGrow({ scale: 0 }, { scale: 1 })
        this.$refs.box.addEventListener('animationend', function () {
          this.style.animation = ''
          this.style.display = ''
        })
      },
      hide () {
        this._animateSpringGrow({ scale: 1 }, { scale: 0 })
        this.$refs.box.addEventListener('animationend', function () {
          this.style.display = 'none'
          this.style.animation = ''
        })
      },
      _animateSpringGrow (...keyframeObjects) {
        let keyframes = spring(
          ...keyframeObjects,
          { damping: 14, precision: 2 }
        )

        animations.registerAnimation({
          name: 'springGrow',
          animation: keyframes,
          presets: {
            duration: 1000,
            easing: 'linear'
          }
        })

        animations.runAnimation(this.$refs.box, 'springGrow')
      }
    }
  }
</script>

<style>

  .box {
    width: 100px;
    height: 100px;
    background-color: seagreen;
    border-radius: 10px;
  }
</style>

相关文章