Solbeg Posted April 18, 2023 Share Posted April 18, 2023 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 More sharing options...
Solution Rodrigo Posted April 19, 2023 Solution Share Posted April 19, 2023 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 More sharing options...
Solbeg Posted April 19, 2023 Author Share Posted April 19, 2023 @Rodrigo Tnx! You help a lot! Link to comment Share on other sites More sharing options...
Solbeg Posted May 15, 2023 Author Share Posted May 15, 2023 @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 More sharing options...
Rodrigo Posted May 15, 2023 Share Posted May 15, 2023 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now