Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLIP 动画 #105

Open
coconilu opened this issue Oct 28, 2018 · 0 comments
Open

FLIP 动画 #105

coconilu opened this issue Oct 28, 2018 · 0 comments

Comments

@coconilu
Copy link
Owner

coconilu commented Oct 28, 2018

概述

流畅的动画需要浏览器保证每秒60帧的刷新频率。

换句话说,我们应该尽可能多使用GPU(硬件加速),诸如API:transform(translate,rotate 和 scale) 和 opacity;另外,在绝对定位的元素上使用动画也可以优化刷新频率。

只要严格遵循以上两条规则,就能确保在绝大多数情况下你的动画在 60FPS 下运行。但是还有一个新的技术方案,可以帮助你创建真正轻量级的动画。

FLIP 简介

FLIP,将一些开销高昂的动画,如针对 width,height,left 或 top 的动画,映射为 transform 动画。

FLIP 来源于 First,Last,Invert,Play:

  • First:元素的初始状态。
  • Last:元素的最终状态。
  • Invert:先计算出从初始状态到最终状态元素发生的改变,比如宽度、高度、透明度等,然后在元素上应用一个 transform 或 opacity 使这些改变反转。如果一个元素由初始状态到最终状态是向下移动了 90px,那就需要对元素应用 transform: translate(0, -90px),这样就使元素看起来还在初始位置。
  • Play:移除元素上的 transform 并设置 transform 相关的动画。

写一个FLIP

根据上面的描述,我们可以自己写一个FLIP函数

function flip(element, handler, duration = 0.3, timingFn = 'ease') {
  let first, last, invert_top, invert_left
  first = element.getBoundingClientRect()
  handler.call(null, element)
  last = element.getBoundingClientRect()
  invert_top = first.top - last.top
  invert_left = first.left - last.left
  element.style.transform = `translate(${invert_left}px, ${invert_top}px)`
  element.addEventListener('transitionend', () => {
    element.style.transition = ""
  });
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      element.style.transition = `all ${duration}s ${timingFn}`
      element.style.transform = ""
    })
  })
}

CodePen演示地址

GitHub地址

NPM地址

开源项目

Google的开源项目——flipjs

参考

使用 FLIP 来提高 Web 动画的性能

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant