更流畅的 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 数量。
尝试简化样式 - 以透明方式减少
opacity
或 rgba()
的用例数量。
一般来说:你拥有的 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 );
延伸阅读:"requestAnimationFrame for Smart Animating" - Paul IrishCode snippet found here.
【讨论】:
以上是关于更流畅的 Jquery 动画的主要内容,如果未能解决你的问题,请参考以下文章
JQuery 动画运行不流畅,滚动条闪烁很多,DIV 动画化