jquery – 在动画暂停时使用j Query更改动画延迟在Safari上不起作用,但它在其他任何地方都有效

前端之家收集整理的这篇文章主要介绍了jquery – 在动画暂停时使用j Query更改动画延迟在Safari上不起作用,但它在其他任何地方都有效前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在CSS中设置了一个关键帧动画.将其附加到DOM元素并将其设置为暂停.使用 javascript(jQuery),我将动画延迟从0s更改为100s,在滚动时实现了漂亮的动画效果.

这适用于所有浏览器,但不适用于Safari(版本11.1.1(13605.2.8)).

$(document).ready(function() {
      fluider([
        {
          selector: '.manualAnim',start: 100,end: 500
        },{
          selector: '.manualAnim2',start: 500,end: 1000
        },{
          selector: '.manualAnim3',start: 0,end: 1500
        }

      ])
    })
    
    
    function fluider(o) {
      for(var i = 0; i < o.length; i++) {
        $(o[i].selector).css('animation-play-state','paused');
        $(o[i].selector).css('animation-duration','100s');
      }
      $(window).scroll(function() {
        var h = $(window).scrollTop();
        for(var i = 0; i < o.length; i++) {
    
            $(o[i].selector).css('animation-delay',-clamp(0,100,((h-o[i].start)/o[i].end * 100)) + 's');
        }
      });

    }
    
    function clamp(from,to,val) {
      if(val >= from) {
        if(val <= to) {
          return val;
        }
        else {
          return to;
        }
      }
        else {
          return from;
      }
    }
body {
      height: 1000vh;
    }
    .manualAnim {
      position: fixed;
      display: block;
      width: 100px;
      height: 100px;
      background-color: red;
      animation: 100s anim paused both;
      animation-delay: 0s;
    }
    
    .manualAnim2 {
      position: fixed;
      display: block;
      left: 120px;
      width: 100px;
      height: 100px;
      background-color: red;
      animation: 100s anim paused both;
      animation-delay: 0s;
    }
    
    .manualAnim3 {
      position: fixed;
      display: block;
      left: 240px;
      width: 100px;
      height: 100px;
      background-color: red;
      animation: 100s anim paused both;
      animation-delay: 0s;
    }
    
    @keyframes anim{
      0% {
        background-color: red;
        transform: scale(1);
      }
      30% {
        background-color: green;
        transform: scale(1.5);
      }
      60% {
        background-color: blue;
        transform: scale(0.5);
      }
      100% {
        background-color: yellow;
        transform: scale(1);
      }
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="manualAnim"></div>
<div class="manualAnim2"></div>
<div class="manualAnim3"></div>

我现在用谷歌搜索几个小时,但我不知道可能是什么问题.
任何的想法?

解决方法

经过大量的实验,这里有一个带有变通方法的版本,可以在Safari 11.1.2和Chrome 68(以及其他浏览器)中提供平滑,预期的行为.

看起来潜在的问题是,当为暂停的动画更改动画属性时,元素不会重新绘制,正如问题所述.这个解决方案通过每帧重新添加必要的动画相关CSS(具有正确的延迟)来解决这个问题.这通常会导致闪烁(因为Safari会在删除动画时尝试恢复到非动画样式),因此每次修改动画时此解决方案都会手动应用当前动画样式.

$(document).ready(function() {
  fluider([{
      selector: '.manualAnim',end: 500
    },{
      selector: '.manualAnim2',end: 1000
    },{
      selector: '.manualAnim3',end: 1500
    }

  ])
})

function getAnimatedProperties(animName) {
  // Get an array of all property names that
  // are modified by the animation ${animName}
  let properties = {};
  let sheets = document.styleSheets;
  let propertyRegex = /([a-z\-]+):/ig;
  for (let sheet of sheets) {
    let rules = sheet.rules || sheet.cssRules;
    for (let r of rules) {
      if (r.name === animName) {
        let rText = r.cssText;
        let match = propertyRegex.exec(rText);
        while (match) {
          properties[match[1]] = true;
          match = propertyRegex.exec(rText);
        }
      }
    }
  }
  return Object.keys(properties);
}

function fluider(o) {
  const animationName = "anim";
  const preservedProperties = getAnimatedProperties(animationName);
  $(window).scroll(function() {
    var h = $(window).scrollTop();
    for (var i = 0; i < o.length; i++) {
      let el = document.querySelector(o[i].selector);
      let pct = 100 * (parseInt(h) - o[i].start) / o[i].end;
      let delay = -Math.max(Math.min(pct,100),0) + 's';
      let s = window.getComputedStyle(el);
      // without setting these properties and overwriting .style,// the animation will flicker
      let preservedStyles = preservedProperties.map(p => `${p}: ${s[p]};`).join("");
      el.style = `${preservedStyles} animation-delay: ${delay}; animation-duration: 100s; animation-play-state: paused;`;
      // without scheduling this *using setTimeout*,// the animation will not rerender
      window.setTimeout(() => {
        el.style.animationName = animationName;
      },0);
    }
  });
}
body {
  height: 1000vh;
}

.manualAnim {
  position: fixed;
  display: block;
  width: 100px;
  height: 100px;
  background-color: red;
}

.manualAnim2 {
  position: fixed;
  display: block;
  left: 120px;
  width: 100px;
  height: 100px;
  background-color: red;
}

.manualAnim3 {
  position: fixed;
  display: block;
  left: 240px;
  width: 100px;
  height: 100px;
  background-color: red;
}

@keyframes anim {
  0% {
    background-color: red;
    transform: scale(1);
  }
  30% {
    background-color: green;
    transform: scale(1.5);
  }
  60% {
    background-color: blue;
    transform: scale(0.5);
  }
  100% {
    background-color: yellow;
    transform: scale(1);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="manualAnim"></div>
<div class="manualAnim2"></div>
<div class="manualAnim3"></div>

猜你在找的jQuery相关文章