Skip to content

FLIP 动画 #105

@coconilu

Description

@coconilu

概述

流畅的动画需要浏览器保证每秒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 动画的性能

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions