Vue组件设计 | 如何定制js、css动画曲线

写在前面

我们的组件库团队还在募集爱好者来参与贡献,近期有进一步丰富一部分通用组件的计划,有兴趣的小伙伴欢迎加入讨论。

仓库地址
文档地址

希望大家多多支持,star,有意愿加入贡献或是讨论的可以在issue列表留邮箱,我们看见会第一时间反馈。感谢掘金社区的小伙伴们。

定制css动画曲线

animation-timing-function

cssanimationtransition都存在控制动画曲线的属性,animation-timing-functiontransition-timing-function。我们经常见到的值有linear,ease,ease-in……除了这些之外还有一个可自定义定制动画曲线的函数cubic-bezier(x1,y1,x2,y2),可以通过两个贝塞尔曲线的控制点来描述一个动画的曲线

贝塞尔曲线

这里关于贝塞尔曲线的数学细节不展开讨论,通俗的讲就是在坐标系内做一条(0, 0)到(1, 1)的直线,再通过两个控制点牵引成了一条曲线,这个曲线描述了动画执行时间比率动画当前执行进度的关系,也就是我们通常所说的动画曲线,两个控制点就是对应cubic-bezier(x1,y1,x2,y2)中的(x1, y1),(x2, y2),如下图所示。

image.png

一个很省事的做法

这里有一个很省事方便的做法,你可以到这个工具站点拖拽出一个贝塞尔曲线,你可以获取这两个控制点的坐标也可以直接复制生成的贝塞尔曲线函数到你的css中,是不是很方便呢?

定制js动画曲线

在一些情况下,css动画并不能满足组件对于动画可控性以及灵活性的要求,例如需要实现一个自定义浏览器滚动到顶部的效果,或是点击一个tab自动滚动到视图中心的效果,我又需要定制动画的执行曲线。这种情况下使用js来控制动画整体执行过程就会是一个更好的实践方式

requestAnimationFrame

针对这个方法的具体细节这里也不展开讨论,通俗的讲就是在浏览器绘制下一帧之前去执行我们要执行的任务,这样就可以保证浏览器的每一帧都能去处理我们的绘制任务,避免掉帧。

js中使用贝塞尔曲线

首先函数就是一个求值的过程,那么贝塞尔曲线的动画函数就是通过动画执行时间比率动画当前执行进度的过程,这个动画函数可以通过算法来实现,类似bezier-easing这样的实现有很多很多,可以直接通过贝塞尔曲线控制点生成动画函数(timing-function),也就是下面例子中的animation,这里我以线性的动画作为一个例子实现一个自定义动画的scrollTo方法。

function scrollTo(element, { top = 0, left = 0, duration = 300, animation }) {
  const startTime = Date.now()

  const { scrollTop, scrollLeft } = element

  const frame = () => {
    // 算出动画执行时间比率 0 -> 1
    const progress = (Date.now() - startTime) / duration

    if (progress < 1) {
      const nextTop = scrollTop + (top - scrollTop) * animation(progress)
      const nextLeft = scrollLeft + (left - scrollLeft) * animation(progress)

      element.scrollTo(nextLeft, nextTop)
      requestAnimationFrame(frame)
    } else {
      element.scrollTo(left, top)
    }
  }

  requestAnimationFrame(frame)
}

// 线性增长 x y成正比
const linear = value => value

// 执行方法 元素会线性的滚动到100px的位置
scrollTo(document.getElementById('scroller'), {
  top: 100,
  animation: linear
})
 

写在最后

这就是常用的两种动画使用方式了,也是我在项目中最经常使用的方式,希望小伙伴们能有所启发。

原创文章,作者:我心飞翔,如若转载,请注明出处:https://www.pipipi.net/14662.html

发表评论

登录后才能评论