【问题标题】:How to make IntersectionObserver work with transform translate animations?如何使 IntersectionObserver 与变换平移动画一起使用?
【发布时间】:2020-05-09 15:33:56
【问题描述】:

我想为具有以下属性的元素创建动画:

  • 当元素进入视口时,它会为元素设置动画
  • 如果元素离开视口然后再次进入它应该再次动画
  • 根据滚动方向/相交边(从顶部或底部),动画应该不同

为此,我使用了IntersectionObserver,我接近了预期的结果。
我面临的唯一问题是,当我在动画期间沿滚动方向(在本例中为 transform: translateY)平移元素时。这将导致IntersectionObserver 触发多次甚至无限次。

function isIntersectingFromTop(entry){
  return entry.boundingClientRect.bottom != entry.intersectionRect.bottom;
} 

function isIntersectingFromBottom(entry){
  return entry.boundingClientRect.top != entry.intersectionRect.top;
}

var count = 0;

function incrementCounter(entry){
  document.querySelector(".counter").textContent += "intersectionRation (" + count + "): " + entry.intersectionRatio + "\n";
  count++;
}

let observer = new IntersectionObserver(
function (entries, observer) { 
  entries.forEach(function(entry){
    incrementCounter(entry)
    if (entry.isIntersecting) {
       if(isIntersectingFromTop(entry)){
         entry.target.classList.add("animated--up-in");
       } else if(isIntersectingFromBottom(entry)) {
         entry.target.classList.add("animated--down-in")
       }
    } else { 
      /** element is not in viewport anymore
        * this will be triggered right after the animation starts
        * since the translate is moving the elment out of the view
        * which is causing a new intersection (isIntersecting = false)
        */
      entry.target.classList.remove("animated--up-in");
      entry.target.classList.remove("animated--down-in");
    }
  });
});

observer.observe(document.querySelector(".to-animate"));
.container {
  height: 1000px;
  width: 100%;
}

.box{
  position: static;
  width: 100px;
  height: 100px;
  background: red;
  margin-top: 10px;
}

.to-animate{
  background: blue;
  opacity: 0;
}

.animated--up-in {
  animation: animateUpIn 1.5s forwards ease;
}

.animated--down-in {
  animation: animateDownIn 1.5s forwards ease;
}

@keyframes animateUpIn {
  from {
    transform: translateY(100px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes animateDownIn {
  from {
    transform: translateY(-100px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}



.counter {
  position: fixed;
  top: 10%;
  left: 30%;
  color: black;
  height: 80%;
  width: 50%;
  overflow-y: auto;
  padding: 10px;
}
<div class="container">
  <pre class="counter"></pre>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box to-animate"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

问题

我如何“告诉”IntersectionObserver 忽略翻译位置,只使用初始/原始位置来计算交叉点(没有额外的元素)?这甚至可能吗?

【问题讨论】:

    标签: javascript html css intersection-observer


    【解决方案1】:

    我认为在这种情况下,您需要跟踪固定容器在屏幕上的位置,动画元素将在其中嵌套。

    【讨论】:

      【解决方案2】:

      我在移动设备上遇到了与 translateX 类似的问题 动画有translateX(-100% or 100%);

      阈值:0.1

      块的宽度为 100%,但它应该在 10% 的可见性(阈值 0.1)下工作,因此它无法工作,动画来回切换,无休止。

      如果是 90%,那么它会起作用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-21
        • 2020-09-07
        • 1970-01-01
        • 2022-10-20
        • 2019-04-25
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多