【问题标题】:Animating child elements in ScrollTrigger GSAP horizontal scroll在 ScrollTrigger GSAP 水平滚动中为子元素设置动画
【发布时间】:2022-02-10 14:32:24
【问题描述】:

我有一个svg,它构成了我的horizontal 滚动条的基础。

在这个svg 中,我已将.animate 类添加到我想要在项目出现时淡入的元素中。 svg 中的所有文本项中都添加了 .animate 类供参考。

目前,只有最初在视图中的.animate 元素会逐渐淡出。当我向下滚动以继续滚动时,其他元素是静态的。他们没有淡入或translating以任何方式向上或向下?

TL;DR,这是我想要实现的目标:

  • 当滚动条固定到位并且用户继续向下滚动时,开始淡出.horizontalScroller__intro
  • 一旦.horizontalScroller__intro 消失,开始水平滚动.horizontalScroller__items
  • 我的滚动条中任何具有.animate 类的元素都将淡入到其原始位置。

注意:我了解在此处发布代码的 SO 规则和偏好。但是,我的演示包含一个长度 SVG,我无法在此处发布,因为它超出了 SO 的字符限制。

Here is a demo of my latest approach

来自scrollTrigger docscontainerAnimation 有助于在水平滚动条上实现动画,这也是我试图实现的。

但是,在我上面的演示中,我遇到了以下问题:

  1. .horizontalScroller__intro 最初不显示,何时应该显示,并且应该在滚动时淡出。
  2. 水平滚动条不再起作用
  3. 视图中的.animate 元素不会淡出

如果我使用timeline(参见下面的sn-p),那么介绍会淡出并且滚动条会起作用。但是,在子元素中没有动画,这是我需要containerAnimation

$(function() {

  let container = document.querySelector(".horizontalScroller__items");

  let tl = gsap.timeline({
    scrollTrigger: {
      trigger: ".horizontalScroller",
      pin: ".horizontalScroller",
      anticipatePin: 1,
      scrub: true,
      invalidateOnRefresh: true,
      refreshPriority: 1,
      end: '+=4000px',
      markers: true,
    }
  });

  tl.to('.horizontalScroller__intro', {
    opacity: 0,
  })

  tl.to(container, {
    x: () => -(container.scrollWidth - document.documentElement.clientWidth) + "px",
    ease: "none",
  })

});

我正在努力寻找一种方法,让我可以让简介淡入、滚动条水平滚动以及 .animate 元素淡入或淡入。

编辑:

@onkar ruikar,请参阅下面基于your sandbox 的注释:

  1. 当您向下滚动并进入视图时,我希望最初的 .animate 元素向上滚动到视图中(目前,一旦文本消失,然后水平滚动条开始工作,只有 .animate假设在视图中,淡入
  2. 初始.animate 元素加载后,作为滚动条一部分的下一个.animate 元素不会淡入。它们是静态的。当每个 .animate 元素进入视野时,它应该淡入淡出(我认为它目前正在触发一次,适用于所有元素)。

在此处查看图片:

在上面的 gif 中,你可以看到前两个文本块是隐藏的,一旦它们出现,我希望它们淡出。然后第三个和第四个文本块是静态的,当用户滚动到该部分时它们应该淡出。

【问题讨论】:

    标签: javascript html jquery gsap scrolltrigger


    【解决方案1】:

    您需要在滚动触发器上使用onUpdate 方法。

    onUpdate: self => console.log("progress", self.progress)
    

    根据self.progress设置不透明度、x位置等

    codesandbox 上的完整演示。点击右下角的“Open Sandbox”按钮查看代码。

    if ("scrollRestoration" in history) {
      history.scrollRestoration = "manual";
    }
    $(function() {
      let container = document.querySelector(".horizontalScroller__items");
      let elements = gsap.utils.toArray(
        document.querySelectorAll(".animate")
      );
      let intro = document.querySelector(".horizontalScroller__intro");
      let svg = document.querySelector("svg");
      let animDone = false;
      window.scrollPercent = -1;
    
      var scrollTween = gsap.to(container, {
        ease: "none",
        scrollTrigger: {
          trigger: ".horizontalScroller",
          pin: ".horizontalScroller",
          anticipatePin: 1,
          scrub: true,
          invalidateOnRefresh: true,
          refreshPriority: 1,
          end: "+=600%",
          markers: true,
          onEnter: (self) => {
            moveAnimate();
          },
          onLeaveBack: (self) => {
            resetAnimate();
          },
          onUpdate: (self) => {
            let p = self.progress;
            if (p <= 0.25) {
              let op = 1 - p / 0.23;
              intro.style.opacity = op;
              animDone = false;
            }
    
            if (p > 0.23) {
              moveAnimate();
              // we do not want to shift the svg by 100% to left
              // want to shift it only by 100% - browser width
              let scrollPercent =
                (1 - window.innerWidth / svg.scrollWidth) * 100;
              let shift = ((p - 0.22) * scrollPercent) / 0.78;
              gsap.to(svg, {
                xPercent: -shift
              });
            }
          }
        }
      });
    
      function resetAnimate() {
        gsap.set(".animate", {
          y: 150,
          opacity: 0
        });
      }
      resetAnimate();
    
      function moveAnimate() {
        for (let e of elements) {
          if (ScrollTrigger.isInViewport(e, 0.4, true))
            gsap.to(e, {
              y: 0,
              opacity: 1,
              duration: 2
            });
        }
      }
    });
    

    您需要在 CSS 中为 .animate 元素设置不透明度 0。并使用end: '+=400%' 而不是 4000px。相对尺寸可以很容易地用于基于位置的计算。

    【讨论】:

    • 嗨,感谢您的回答 :) 使用containerAnimation (greensock.com/3-8/#containerAnimation) 后是否有可能实现我的目标,因为 GSAP 建议将其作为在水平方向上执行动画时的最佳实践滚动条?
    • 不幸的是,“在具有 containerAnimation 的 ScrollTriggers 上固定和捕捉不起作用。” ref。我无法将介绍文本固定在中心位置。当我们继续滚动时,它会向左移动。
    • 嗯,谢谢您的确认。我在timelinecontainerAnimation 之间遇到了类似的问题和冲突。我已经编辑了我的问题以跟进您提供的演示。
    • 谢谢。我已经剖析了您的代码并开始更好地理解它。有一点我无法理解,那就是end 参数。因此,在您的演示中,end: '+=400%' 会在屏幕边缘截断最后一段文本(请参见屏幕截图:i.imgur.com/pvxVvpJ.png)。我试图让该部分保持固定,直到最后一段文本靠近该部分的中心。
    • 啊,想通了。我有ScrollTrigger.refresh(); 在滚动上运行,这导致了故障。非常感谢您的帮助和解释:)
    猜你喜欢
    • 2021-06-19
    • 2021-08-26
    • 2021-05-06
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 2019-11-04
    • 2021-11-12
    相关资源
    最近更新 更多