在 ScrollTrigger GSAP 水平滚动中为子元素设置动画

Animating child elements in ScrollTrigger GSAP horizontal scroll

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

在此 svg 中,我已将 class .animate 添加到我希望在项目出现时淡入的元素。 .animate class 已添加到 svg.

中的所有文本项中以供参考

目前,只有 .animate 个可见的元素最初会淡入淡出。当我向下滚动以继续滚动时,其他元素是静态的。它们没有以任何方式淡入或 translating 上升或下降?

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

注意:我了解 SO 规则和对 post 代码的偏好。但是,我的演示包含一个长度的 SVG,我不能在这里 post 因为它超过了 SO 的字符限制。

Here is a demo of my latest approach

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

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

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

如果我使用 timeline(见下面的代码片段),则介绍淡出并且滚动条起作用。但是,不在子元素中设置动画,这是我需要的 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, see notes based on your sandbox 下面:

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

在此处查看图片:

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

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

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

基于self.progress设置不透明度、x位置等

codesandbox 上的完整演示。单击右下角的“打开沙盒”按钮以查看代码。

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。相对尺寸可以很容易地用于基于位置的计算。