简单记录关于Velocity的一些想法

顺滑的动画

在网页开发圈子里有一种误解,那就是认为CSS动画是网络中唯一可以实现高性能动画的方法。因为CSS可以借助硬件加速把动画直接交给GPU处理。

事实上,基于JavaScript的动画与基于CSS的动画一样快。之所以JS动画会卡顿,或许是因为你使用定时器(setTimeout、setInterval)去处理动画了,但这不是JS的错,而是你的使用方法错了。

基于JS的动画有如下的优点:

1.动画中止
2.动画反转
3.动画管理

CSS非常适合实现悬停状态的动画效果(例如:当鼠标位于链接上方时,链接变成蓝色)这类的微互动,这也是通常情况下基本的网页所包含的动画。

Velocity.js核心原理

Velocity.js是一个著名的动画库。这是个轻量级的库,但是功能却异常丰富。

GitHub地址奉上:github.com/julianshapi…

核心JS是:

document.querySelector("#v").velocity(
  {
    opacity: 0.5,
    left: 1000,
  },
  {
    duration: 2000,
  }
); 

下图是帧率和CPU利用率的示意图:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f1bd3bce5b6b41d5bfbf27ee182ba47c~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=14.png “14.png”” style=“margin: auto” />

在CPU那一行,可以看到,有很多执行点,我们放大其中一个:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ffd390c1b06246be82d3496091cf571c~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=4.png “4.png”” style=“margin: auto” />

我们可以看到Animation Frame Fired,其实就是requestAnimationFrame()回调被触发了,接着执行tick和setPropertyValue。我们一个一个看:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a68c4c4960754413b9b42f2e4e923dee~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=7.png “7.png”” style=“margin: auto” />

点击跳转到源码:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a29f34382d3e44d796a37c92871c0bde~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=3.png “3.png”” style=“margin: auto” />

跳转到rAFShim,可以看到这是对 requestAnimationFrame 的调用,tick 是它的回调:

rAFProxy = (callback: FrameRequestCallback) => {
  return setTimeout(callback, Math.max(0, FRAME_TIME - (performance.now() - lastTick)));
},

rAFShim = window.requestAnimationFrame || rAFProxy; 

跳转到 setPropertyValue

function setPropertyValue(element, propertyName, propertyValue, fn) {var noCache = NoCacheNormalizations.has(propertyName),data = !noCache && Data(element);if (noCache || data && data.cache[propertyName] !== propertyValue) {// By setting it to undefined we force a true "get" laterif (!noCache) {data.cache[propertyName] = propertyValue || undefined;}fn = fn || getNormalization(element, propertyName);if (fn) {fn(element, propertyValue);}if (Velocity$$1.debug >= 2) {console.info("Set "" + propertyName + "": "" + propertyValue + """, element);}}
} 

我们继续深究上面的fn函数,发现它是 getSetStyle返回的函数,函数最后会设置元素的style属性:

function getSetStyle(propertyName) {return function (element, propertyValue) {if (propertyValue === undefined) {return computePropertyValue(element, propertyName);}element.style[propertyName] = propertyValue;};
} 

至此,我们可以理顺 Velocity.js 的核心原理:

1.当我们通过velocity去设置某个元素的最终样式,velocity会计算出初始值,在演示里是 opacity 和 left
2.然后通过注册requestAnimationFrame()回调去计算动画的中间态,并应用在元素上

Velocity.js 是通过计算值处理动画效果的中间值的。所以对几何长宽、颜色、透明度这些值非常友好。

不仅如此,Velocity.js还可以终止动画,也可以反转动画,这些都是CSS设置动画办不到的,JS可以通过在执行requestAnimationFrame回调前终止动画,并且通过记录历史中间态并反转。

搭配React使用

Velocity.js 搭配 React 使用的库叫 velocity-react。

GitHub地址奉上:github.com/google-fabr…

velocity-react 暴露两个组件接口:

1.VelocityComponent,添加动画,为子组件注册动画效果;
2.VelocityTransitionGroup,添加过渡效果(显示和隐藏组件,切换组件),这个组件里面的所有子组件的mount、unmount都会触发过渡效果,底层依赖TransitionGroup(react-transition-group)组件。

还有一个API接口:velocityHelpers,用以注册动画效果的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值