代码之家  ›  专栏  ›  技术社区  ›  woshitom

jquery动画和css动画之间的延迟

  •  0
  • woshitom  · 技术社区  · 7 年前

    我将5幅图像叠加在一起,赋予它们一个绝对位置,具有相同的顶部和左侧坐标以及不同的z索引。

    我的目标是旋转、平移并将具有最高z索引的图像的不透明度设置为0,并将所有其他图像的z索引增加1。 我正在用CSS变换设置索引最高的图像的动画,并用jquery更改其他图像的z索引。 我的代码如下:

    var i = 1;
    
    function swypeStyle(){
      var imageLength = $('.my-image').length;
    
      $('.my-image').each(function(){
        $(this).removeClass('rotated');
      });
    
      $("#image"+i).addClass('rotated'); 
    
      setTimeout(function(){
        for(var j = 1; j <= imageLength; j++){
    
          var currentZindex = $('#image'+j).css('z-index');
    
          if(currentZindex == imageLength){
            currentZindex = 1;
          }else{
            currentZindex++;
          }
    
          $('#image'+j).css('z-index',currentZindex);
        }
      }, 1100);
    
    
      if(i == imageLength){
        i = 1;
      }else{
        i++;
      }
    }
    
    window.setInterval(function () {
    	swypeStyle(); 
    }, 3000);
    .my-image{
      width: 144px;
    	left: 0px;
      top: 0px;
      position: absolute;
    }
    
    .my-image.rotated {
    	left: -150px;
    	top: 25px; 
    	-webkit-transform: rotate(-30deg);
    	opacity: 0;
    	-webkit-transition: all 1s ease-in-out;
    }
    <img src="https://www.otop.sg/retailer/images/image1.jpg" class="my-image" id="image1" style="z-index: 5;">
    <img src="https://www.otop.sg/retailer/images/image2.jpg" class="my-image" id="image2" style="z-index: 4;">
    <img src="https://www.otop.sg/retailer/images/image3.jpg" class="my-image" id="image3" style="z-index: 3;">
    <img src="https://www.otop.sg/retailer/images/image4.jpg" class="my-image" id="image4" style="z-index: 2;">
    <img src="https://www.otop.sg/retailer/images/image5.jpg" class="my-image" id="image5" style="z-index: 1;">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    我的动画效果很好,问题是当我切换并在另一个chrome选项卡上花费一些时间时,当我返回脚本chrome选项卡时,css动画和jquery动画之间存在延迟。

    3 回复  |  直到 7 年前
        1
  •  1
  •   General_Twyckenham    7 年前

    问题是,当你的标签不活动时,Chrome会暂停动画等项目,以降低资源利用率。

    我的建议是只使用CSS进行所有转换/动画,并使用Javascript只添加/删除类;这样,动画将保持同步。

        2
  •  1
  •   soulofmischief    7 年前

    如果你真的不能放弃你的jQuery动画,你可以尝试用一个 requestAnimationFrame() 循环。 作为 MDN explains :

    与CSS转换和动画一样,当当前选项卡被推到背景中时,requestAnimationFrame()会暂停。

    以下是一个例子:

    用法:

    // Get element.
    const elem = document.querySelector( '#elementID' )
    // Get current size.
    const startSize = elem.width
    // Set end size.
    const endSize = startSize * 2 // Double the size of the element.
    // Set animation duration.
    const duration = 1000 // 1000ms -> 1s
    
    animate( ratio => {
      setWidth( elem, lerp( startSize, endSize, ratio ))
    }, duration )
    

    // Resolves a promise once an animation is complete.
    // Allows you to specify an animation duration, start and end values,
    // and automatically handles frame interpolation.
    function animate( callback, duration ) {
      return new Promise( resolve => {
        let
          // Amount of time in ms since last frame
          delta = 0,
          // Used to calculate delta
          lastTimestamp = 0,
          // Ratio for use in linear interpolation.
          // Passed through to the callback and incremented
          // with respect to duration.
          // The ratio determines how far along the start and end values we are.
          ratio = 0,
          // Speed is an inverse function of time, since ratio is normalized.
          speed = 1 / duration
    
        // Start the update loop
        update( performance.now())
    
        // Update loop
        function update( timestamp ) {
          if ( ratio < 1 ) {
            // Calculate frame delta and update last frame's timeStamp.
            // In the first frame, set lastFrame to this frame's timeStamp.
            delta = timestamp - ( lastTimestamp || timestamp )
            lastTimestamp = timestamp
            // Update ratio as a function of speed and frame delta
            ratio = clamp( ratio + ( speed * delta ))
            // Execute callback
            callback( ratio )
            // Request next frame
            requestAnimationFrame( update )
          }
          // Make good on the promise
          else resolve()
        }
      })
    }
    
    /** Linear interpolation between two scalars */
    function lerp( min, max, t ) {
      /*
       * Get difference, multiply by `t` and add min.
       *
       * The ratio `t` represents the percentage of that distance
       * we add back to min, so that a fraction of 1 adds 100%
       * of the distance, which equals the max value.
       *
       * Precise form of linear interpolation,
       * ensures t=1 always equals max.
       */
      return ( 1 - t ) * min + t * max
    }
    
    // Set width of an element
    function setWidth( element, width ) {
      element.style.width = `${ width }px` 
    }
    

    More about requestAnimationFrame()

        3
  •  0
  •   woshitom    7 年前

    我使用css来制作动画,因为不能使用jQuery动画功能来制作旋转动画。

    CSS rotation cross browser with jquery.animate() 我找到了一个解决办法,现在我的动画是100%jQuery,不再有延迟。

    var i = 1;
    
      function AnimateRotate(angle,elem) {
        $({deg: 0}).animate({deg: angle}, {
          duration: 700,
          step: function(now) {
            elem.css({
            transform: 'rotate(' + now + 'deg)'
          });
        }
        });
      }
    
    function swypeStyle(){
      var imageLength = $('.my-image').length;
    
      $('.my-image').each(function(){
          $(this).css({
            "left": 0,
            "top": 0,
            "opacity": 1,
            WebkitTransform: 'rotate(0deg)',
            '-moz-transform': 'rotate(0deg)'
          })
        });
    
        AnimateRotate("-30",$("#image"+i));
    
        $("#image"+i).animate({
          "left": "-150px",
          "top": "25px",
          "opacity": 0
        },700); 
    
      setTimeout(function(){
        for(var j = 1; j <= imageLength; j++){
    
          var currentZindex = $('#image'+j).css('z-index');
    
          if(currentZindex == imageLength){
            currentZindex = 1;
          }else{
            currentZindex++;
          }
    
          $('#image'+j).css('z-index',currentZindex);
        }
      }, 1100);
    
    
      if(i == imageLength){
        i = 1;
      }else{
        i++;
      }
    }
    
    window.setInterval(function () {
    	swypeStyle(); 
    }, 3000);
    .my-image{
    	width: 144px;
    	left: 0px;
    	top: 0px;
    	position: absolute;
    }
    <img src="https://www.otop.sg/retailer/images/image1.jpg" class="my-image" id="image1" style="z-index: 5;">
    <img src="https://www.otop.sg/retailer/images/image2.jpg" class="my-image" id="image2" style="z-index: 4;">
    <img src="https://www.otop.sg/retailer/images/image3.jpg" class="my-image" id="image3" style="z-index: 3;">
    <img src="https://www.otop.sg/retailer/images/image4.jpg" class="my-image" id="image4" style="z-index: 2;">
    <img src="https://www.otop.sg/retailer/images/image5.jpg" class="my-image" id="image5" style="z-index: 1;">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>