更流畅的Jquery动画

6

我曾经发过另一个关于这个问题的帖子,但它没有得到解决,可能是因为我的问题表述不够清晰。

现在我想再试一次,希望能够更接近解决这个问题:

最近,我被指派创建一个单页网站,模拟基本的Flash动画效果,例如元素的滑入和淡入淡出。

当我得到一个交互式模型后,我遇到了一个大问题——动画效果很卡顿。无论在Mac上使用什么浏览器,只要屏幕大小超过18英寸,这个问题都存在;而在小于18英寸的Mac上,只有Firefox版本3及以下才会遇到这个问题。在PC上,动画效果几乎完美。

这里是我的jQuery代码,受影响的元素带有id #md1、#md2和#md3:

$(document).ready(function () {
    $('#md1').animate({ top: "-60px" }, 500);
    $('#md2').animate({ top: "60px" }, 800);
    $('#md3').animate({ left: "60px" }, 1000);
    $('.home').fadeTo(3000, 0.8);
    $('#bg-img-4').fadeTo(1200, 1);
    $('#menu').fadeTo(4000, 1);
    $('#copyright').fadeTo(4000, 1);
});

我已经尝试了各种优化方法,包括在索引页面上缓存受影响div中的图像,并在稍后将用户重定向到实际页面,以及排队动画,但什么都没有起作用。
这真的很令人沮丧,因为我似乎已经尽了自己所知道的所有可用方法,但是我就是无法让它在Mac上正常运行。
我有一种直觉,那就是在文档准备好时编译了太多的动画,这导致了运行缓慢-有人能否确认这是主要原因,并且是否有其他方法可以解决这个问题?
非常感谢大家的帮助。非常感激 =)

1
我测试并确保的一件事是导致动画元素明显卡顿的阴影。另一件总是有帮助的事情是减少图像的表面积。 - Babiker
@Babiker:我同意你的观点,关于受影响图像的表面积,你说得完全正确。我已经尝试在18英寸及以上的Mac上缩小浏览器大小,动画效果确实有所改善。不幸的是,我对设计方向没有发言权,并被指示遵守给我的静态合成图。 - vynx
2个回答

1

最好的方法是使用CSS过渡/动画。如果某个浏览器不支持它们,那么这样的浏览器对任何类型的动画都不好。

CSS中的过渡和动画可以通过本地代码更好地优化,因此理论上可能表现出更平滑(更高的FPS)的行为。

至于您上面的jquery动画:

  1. 尝试减少复杂元素上fadeTo的数量。
  2. 尝试简化样式-减少使用透明度的情况下opacity或rgba()的数量。

总的来说:您拥有的DOM元素越少,就越好。


谢谢,我一定会尝试并看看效果如何。我也在考虑如何减少DOM元素的数量。 - vynx

0

队列

在使用jQuery动画时,如果您正在运行多个动画或重复相同的动画,则应在动画前加上dequeue()stop()前缀,否则它们可能会在等待运行时积累在一起,并导致意外延迟。

$('#md1').dequeue().stop().animate({ top: "-60px" }, 500);

这里有一个 Codepen 演示另一个稍微复杂一些的演示,使用了这个。


帧率

您可以使用jquery.fx.interval来控制jQuery处理动画的帧率,该属性在此处有文档记录。

此属性可被调整以调整每秒运行的动画帧数。默认值为13毫秒。将其设置为较低的数字可能会使动画在更快的浏览器(如Chrome)中运行更流畅,但这样做可能会影响性能和CPU。

由于jQuery使用一个全局间隔,因此更改此属性需要停止所有动画或停止所有动画才能生效。

参考资料:http://api.jquery.com/jquery.fx.interval/


间隔

您可以使用setInterval将动画分解为更小的部分,这样处理起来会更容易和更快。

例如,如果您想要在任何扩展距离上动画显示div的位置,您可以将距离分成小部分,并设置其以恒定速度运行,这样看起来就像是单个平滑过渡。

这里有一个演示。


请求

间隔方法只适用于简单的动画。但对于更复杂的动画,您可以使用requestAnimationFrame,它将控制权交给浏览器来选择最佳执行代码的时机。

function animLoop( render, element ) {
    var running, lastFrame = +new Date;
    function loop( now ) {
        // stop the loop if render returned false
        if ( running !== false ) {
            requestAnimationFrame( loop, element );
            running = render( now - lastFrame );
            lastFrame = now;
        }
    }
    loop( lastFrame );
}

// Usage
animLoop(function( deltaT ) {
    elem.style.left = ( left += 10 * deltaT / 16 ) + "px";
    if ( left > 400 ) {
      return false;
    }
// optional 2nd arg: elem containing the animation
}, animWrapper );

代码片段在此处找到。

  • 进一步阅读:{{link2:“requestAnimationFrame for Smart Animating” - Paul Irish}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接