jQuery 循环动画每次都会暂停。如何避免停顿?

Posted

技术标签:

【中文标题】jQuery 循环动画每次都会暂停。如何避免停顿?【英文标题】:jQuery Looping Animation pauses each time. How to keep from pausing? 【发布时间】:2011-01-10 23:22:52 【问题描述】:

我试图使块在 100% 不透明度和一些部分透明的不透明度之间“跳动”。如果可能的话,我想使用 jQuery 核心中内置的功能来做到这一点。我宁愿不添加插件来获得这种效果。这是我尝试使用的代码:

    $(document).ready(function() 
 function pulsate() 
  $("#pulsating-block").animate(opacity: 0.2, 3000).animate(opacity: 1, 3000, null, function() pulsate());
 
 pulsate();  );

问题是每次动画完成时,它都会暂停大约一秒钟,然后再次循环。我怎样才能让它不暂停,以便获得平滑的“脉动”效果? (注意:这个例子中的动画被夸大了,以突出我遇到的问题)

【问题讨论】:

我已经尝试了代码,但我根本看不到动画中的暂停。只有我吗?您是在慢速机器还是旧浏览器上运行? 我在四核 G5 上运行,所以我认为这不是速度问题 :-),我在 Firefox 和 Safari(最新版本)中都尝试过。我还在使用最新版本的 jQuery v1.4.1。尝试缩短持续时间,这可能有助于了解我在说什么。这是一个图表如何在我看来:\\\\\/////----\\\\\\/////----(“\”=淡出,“/”淡入,“-” = 不透明度不变) 【参考方案1】:

也许您的问题在于 jQuery 默认使用的 "swing" 缓动函数。

您可能想试试"linear" 缓动函数:

$(document).ready(function() 
  function pulsate() 
    $("#pulsating-block").
      animate(opacity: 0.2, 3000, 'linear').
      animate(opacity: 1, 3000, 'linear', pulsate);
  
  pulsate();
);

我还编写了一个小 pulsate 插件,其中包括一个 "bounce" 缓动函数,它可能更符合您的喜好。我应该注意,该插件使用连续计算来执行动画,而不是两个单独的淡入/淡出动画,因此它可能有助于解决“暂停”问题。 (说实话,我还是没看到你说的停顿。)

工作演示

http://jsbin.com/isicu(可通过http://jsbin.com/isicu/edit编辑)

完整来源

javascript

(function ($) 
  $.fn.pulsate = function (properties, duration, type, speed, callback) 
    type = type || 'Swing'
    speed = speed || 'Normal';
    this.animate(properties, duration, 'pulsate' + type + speed, callback);
  ;

  function createPulsateLinear (speed) 
    speed *= 2;
    return function (p, n) 
      return (Math.asin(Math.sin(Math.PI * n / speed)) + Math.PI / 2) / Math.PI;
    
  

  function createPulsateSwing (speed) 
    return function (p, n) 
      return (1 + Math.sin(n / speed)) / 2;
    
  

  function createPulsateBounce (speed) 
    speed *= 2;
    return function (p, n) 
      return (
        ((Math.asin(Math.sin(Math.PI * n / speed)) + Math.PI / 2) / Math.PI) *
        (Math.sin(Math.PI * n / speed) + 1) / -2 + 1
      );
    
  

  var speeds = 
    fast: 100,
    normal: 200,
    slow: 400
  

  $.extend(jQuery.easing, 
    pulsateLinearFast: createPulsateLinear(speeds.fast),
    pulsateLinearNormal: createPulsateLinear(speeds.normal),
    pulsateLinearSlow: createPulsateLinear(speeds.slow),
    pulsateSwingFast: createPulsateSwing(speeds.fast),
    pulsateSwingNormal: createPulsateSwing(speeds.normal),
    pulsateSwingSlow: createPulsateSwing(speeds.slow),
    pulsateBounceFast: createPulsateBounce(speeds.fast),
    pulsateBounceNormal: createPulsateBounce(speeds.normal),
    pulsateBounceSlow: createPulsateBounce(speeds.slow)
  );
)(jQuery);

$(document).ready(function() 
  var
    pulsatingBlocks = $('.pulsating-block'),
    forever = 5 * 24 * 60 * 60 * 1000; // 5 days! (Which is forever in Internet time)

  pulsatingBlocks.filter('.opacity').each(function () 
    $(this).pulsate(opacity: 0.2, forever, this.className.split(' ')[0], 'Slow');
  );

  pulsatingBlocks.filter('.top').each(function () 
    $(this).pulsate(top: 100, forever, this.className.split(' ')[0], 'Slow');
  );

);

html

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
<meta charset=utf-8 />
<title>Pulsate</title>
<style>
  div  clear: left; margin-bottom: 2em; 
  .pulsating-block 
    width: 6em; height: 4em;
    margin: 0.5em; margin-right: 10em;
    float: left; clear: none; position: relative;
    background: lightblue;
    text-align: center;
    padding-top: 2em;
    font: bold 1em sans-serif;
  
</style>
</head>
<body>
  <div>
    <div class="Linear opacity pulsating-block">linear</div>
    <div class="Swing opacity pulsating-block">swing</div>
    <div class="Bounce opacity pulsating-block">bounce</div>
  </div>
  <div>
    <div class="Linear top pulsating-block"></div>
    <div class="Swing top pulsating-block"></div>
    <div class="Bounce top pulsating-block"></div>
  </div>
</body>
</html>

【讨论】:

谢谢,布赖恩!你的功能正是我最终想要达到的。我不知道如何编写代码以便它可以处理不只是不透明度,但它做到了!我有点尴尬...事实证明,我看到的问题与代码无关,而是与我的显示器校准(!)有关。我使用的示例是在白色背景上淡入淡出的黑色块。我的显示器正在剪掉较低范围的黑色,这使得动画看起来好像暂时停止了。嗬!不过,谢谢,这个脚本正是我需要的。太棒了! 很高兴我能帮上忙。我认为这个问题更多的是视觉而不是技术。注意到这是您的显示器,这是一个不起眼的“错误”:P 这可能是我在这里看到的任何问题的最完整的答案之一。你的演示很棒。【参考方案2】:

试试

 function pulsate() 
      $("#pulsating-block").animate(opacity: 0.2, 3000,function()
          $(this).animate(opacity: 1, 3000, null, function() pulsate());
      );
     

【讨论】:

感谢您的快速回复!不幸的是,这似乎并不能解决我遇到的问题。 (如果将持续时间减少到 500 毫秒,您可能会更好地看到问题)问题是在恢复到 100% 不透明度后,动画似乎在开始再次变暗持续时间之前停止。元素在再次开始变暗之前保持 100% 的不透明度大约半秒或一整秒。它似乎不会在 20% 的不透明度下暂停(这就是我希望它工作的方式)。

以上是关于jQuery 循环动画每次都会暂停。如何避免停顿?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 JQuery 在旋转动画的循环内等待

如何暂停循环几秒钟?

jQuery.getJSON:如何避免在每次刷新时请求 json 文件? (缓存)

如何避免 Animator 动画的加速/减速?

如何在 jQuery .each() 的每次迭代之间添加暂停?

关键帧动画结束后会有短暂停顿