Jump to content
Search Community

ScrollTrigger Animation with inner sync animations

Solbeg test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

I need to pin main section in full content, then animate 2 sections in sync: left side FadeIn/FadeOut, right side scroll sections.

 

1. I have a problem with sync them correctly (left section change to fast)

2. Is it posibble to do right side sections auto height and scroll them if their content bigger than window

Tnx

See the Pen jOeMyPw by AnnaShubskaya (@AnnaShubskaya) on CodePen

Link to comment
Share on other sites

  • Solution

Hi,

 

I think is better to create a single timeline with a scrolltrigger instance for this.

 

See the Pen yLRabvg by GreenSock (@GreenSock) on CodePen

 

I make a few changes in your code, HTML and CSS in order to accommodate this approach that is simpler IMHO. Unfortunately I ran out of time to create the animation to conditionally scroll the text content if it's larger than the container's height, but I think that part should not be that hard to achieve. Also you'll have to take care of the last image fading out, my guess is that you don't want that.

 

Hopefully this is enough to get you started.

Happy Tweening!

Link to comment
Share on other sites

  • 4 weeks later...

@Rodrigo

I've added anchors to each section with text

is it possible to navigate to the correct section when you click on an anchor from another page?

I've changed the code slightly, but I'm not quite sure how to affect timeline

const images = gsap.utils.toArray(services.querySelectorAll('.media-wrap'));
const texts = gsap.utils.toArray(services.querySelectorAll('.text-wrap'));
if(images.length > 1 && texts.length > 1 ) {
          const heights = []
    
          texts.forEach((text, i) => {
            gsap.set(texts[i + 1], { y: `${texts[i].scrollHeight}`});
            heights.push(text.scrollHeight)
          })
          const heightSum = heights.reduce(
            (accumulator, currentValue) => accumulator + currentValue
          );
      
          function fadeImage(index) {
            if (tl.scrollTrigger.direction > 0) {
              gsap.to(images[index], { opacity: 0 });
              if (images[index + 1]) {
                gsap.to(images[index + 1], { opacity: 1 });
              }
            } else {
              gsap.to(images[index], { opacity: 1 });
              if (images[index + 1]) {
                gsap.to(images[index + 1], { opacity: 0 });
              }
            }
          }
      
          let tl = gsap.timeline({
            defaults: {
              ease: "none"
            },
            scrollTrigger: {
              trigger: ".animation-wrap",
              scrub: true,
              pin: true,
              start: () => "top top",
              end: () => "+=" + heightSum
              //end: () => "+=" + texts.length * 200 + "%"
            }
          });

          function scrollToHash(hash, e) {
            const elem = hash ? document.querySelector(hash) : false;
            if (elem) {
              if (e) e.preventDefault();
              //ScrollSmoother.get().scrollTo(elem, true);
              gsap.to(window, {
                duration: 1,
                scrollTo: elem,
                ease: "Power1.easeInOut"
              });
            }
          }

          document.querySelectorAll("a[href^='#']").forEach((a) => {
            a.addEventListener("click", (e) => {
              e.preventDefault();
              scrollToHash(a.hash);
              window.history.pushState({}, "", a.hash);
            });
          });

          window.addEventListener("load", refreshScroll);

          function refreshScroll() {
            document.querySelector("#smooth-content").scrollTop = 0;
            window.scrollTo(100, 100);
            ScrollTrigger.refresh();
            console.log("refresh", window.location.hash);
            // Scroll to the element in the URL's hash on load
            scrollToHash(window.location.hash);
          }

          scrollToHash(window.location.hash);

          texts.forEach((text, i) => {
            console.log('all:', text)
            if (i && i !== texts.length - 1) {
              console.log('not first:', text)
              tl.to(text, { y: 0 }, "<")
                .to(text, {}) // conditionally scroll here
                //.to(text, { yPercent: -100 })
                .to(text, { y: `-${text.scrollHeight}` })
                .call(fadeImage, [i], "<");
            } else if (i === 0 ){
              console.log('first:', text)
              tl.to(text, {}) // conditionally scroll here
                .to(text, { y: `-${text.scrollHeight}` })
                .call(fadeImage, [i], "<");
            } else {
              tl.to(text, { y: 0 }, "<")// conditionally scroll here
            }
          });
      
          const parent = services.querySelector('.element.left');
          texts.forEach((text, i) => {
            if(text.contains(images[i])) {
              const movedImages = text.querySelector('.media-wrap')
              parent.append(movedImages)
            }
          })
        }

 

Link to comment
Share on other sites

Hi,

 

That's a bit trickier since you'll have to get the URL's param that you want to apply in the new URL. When that happens you'll have to create the ScrollTrigger instances and once they're ready, grab that parameter from the URL, match it to a specific scroll position based on the ScrollTrigger start and end points (specially if you have pinned ScrollTriggers).

 

Without a minimal demo is really hard for us to see what the issue could be. In the mean time here are a couple of examples of this:

See the Pen ZEXYrJR by GreenSock (@GreenSock) on CodePen

 

See the Pen jOezPLN by GreenSock (@GreenSock) on CodePen

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...