更流畅的 Jquery 动画

Posted

技术标签:

【中文标题】更流畅的 Jquery 动画【英文标题】:Smoother Jquery Animation 【发布时间】:2011-09-13 11:13:32 【问题描述】:

有另一个关于这个的帖子,但可能因为我的问题不是很清楚,所以没有解决。

只是想再试一次,希望我能尽快解决这个问题:

我最近的任务是创建一个模拟基本 Flash 动画(即滑入和淡入淡出元素)的单页网站。

当我得到一个交互式模型时,我遇到了一个大问题 - 不连贯的动画。该问题出现在屏幕大于 18 英寸的 Mac 中,而不管浏览器和 18 英寸以下的 Mac 仅适用于 FF 版本 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 上正常工作。

我有一种直觉,我在准备好文档时编译了太多动画,这导致了缓慢 - 任何人都可以确认这是否是主要原因,是否有任何其他方法可以解决这个问题?

非常感谢你们的帮助。非常感谢=)

【问题讨论】:

我测试并确定的一件事是动画元素上的阴影导致明显的波动。另一件总是有帮助的事情是减少图像的表面积。 @Babiker:我同意你的看法;在受影响图像的表面区域部分,您是绝对正确的。我已经尝试在 18 英寸及以上的 Mac 上减小浏览器大小,动画确实改进了很多。不幸的是,我在设计方向上没有发言权,并被指示遵守给我的静态组合..跨度> 【参考方案1】:

最好的方法是为此使用 CSS 过渡/动画。 如果某些浏览器不支持它们,那么这样的浏览器就不适用于任何类型的动画。

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

至于您上面的 jquery 动画:

    尝试减少复杂元素上的 fadeTo 数量。 尝试简化样式 - 以透明方式减少 opacityrgba() 的用例数量。

一般来说:你拥有的 DOM 元素越少越好。

【讨论】:

谢谢,我一定会试一试,看看效果如何。我也在决定如何减少 DOM 元素的数量。【参考方案2】:

队列

使用 jQuery animate 时,如果您正在运行超过 1 个动画或重复相同的动画,您应该在动画前加上 dequeue()stop(),否则它们可能会在等待运行时相互堆积并导致意外延迟。

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

Here's a Codepen demo 和 a another slightly more complex demo 使用这个。


帧速率

您可以使用此处记录的jquery.fx.interval 来控制 jQuery 处理动画的帧速率。

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

由于 jQuery 使用一个全局间隔,因此不应运行动画或停止所有动画以使该属性的更改生效。

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


间隔

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

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

Here's a demo.


请求

interval 方法实际上只适用于简单的动画。但是对于更复杂的动画,您可以使用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 );

Code snippet found here.

延伸阅读:"requestAnimationFrame for Smart Animating" - Paul Irish

【讨论】:

以上是关于更流畅的 Jquery 动画的主要内容,如果未能解决你的问题,请参考以下文章

优化 jQuery 悬停代码以更好地执行(更流畅的动画)

JQuery 动画运行不流畅,滚动条闪烁很多,DIV 动画化

GWT 中流畅的类 jQuery 动画

悬停时的Jquery动画子菜单不流畅

自定义 View 动画比自定义 SurfaceView 动画更流畅?

我怎样才能使这个动画更流畅?