gwineman Posted July 18, 2021 Share Posted July 18, 2021 See below. This is all working perfectly, but just want to confirm that this is the best way to create a sequence of animations/scrollTriggers for a home page. The main thing I'm curious about is all the gsap.set call's i'm doing to "reset" positioning if a user its refresh mid-animation. ScrollTrigger.matchMedia({ "(max-width: 767px)": function() { // I dont really do much below this breakpoint... so i just altered a few settings here. gsap.set('.screen', { opacity:0, scale:.7, transformOrigin: '50% 100%', x:0, y:0, xPercent:0 }) const sections = gsap.utils.toArray('.highlight') sections.forEach((sec, i) => { const headline = sec gsap.set(headline, { y:50, opacity:1 }) }); }, "(min-width: 768px)": function() { // This is the bulk of the animation gsap.set('.screen', { opacity:0, scale:.7, transformOrigin: '50% 100%', x:0, y:0, xPercent:0 }) gsap.set('.main-title', { y:0, }) // Background / Panel - This is pinned for the entire sequence gsap.to('.home-animation', { scrollTrigger: { pin:'.panel', trigger: '.home-animation', start: "top +=132", //I would like to make this dynamic to account for a header/nav that changes size responsively end: "bottom +=650", toggleActions: "play none none reverse", markers: false, scrub:1, pinSpacing:false } }) // Fade Screen In gsap.to('.screen ', { opacity:1, scale:1, //filter: "blur(20px)", ease: "none", scrollTrigger: { pin:false, trigger: '.screen', endTrigger: '.screen', start: 'top 60%', end: 'top 60%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) // Reset screen if page refresh mid-animation gsap.set('.screen', { opacity:1, scale:1, x:0, y:0, xPercent:0 }) // Pin Screen gsap.to('.screen', { ease: "none", scrollTrigger: { pin:true, trigger: '.screen', endTrigger: '.screen-trigger-end', start: 'bottom 90%', end: 'bottom bottom', toggleActions: "play none none reverse", markers: false, scrub:1, pinSpacing:false } }) // Reset screen if page refresh mid-animation gsap.set('.screen', { opacity:1, scale:1, transformOrigin: '50% 100%', xPercent:0, x:0, y:0 }) //Move Screen Back gsap.to('.screen', { xPercent:30, y:-100, scale:.4, //y:80, //filter: "blur(20px)", ease: "none", scrollTrigger: { trigger: '.headline2', start: 'top 60%', end: 'top 60%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) // Reset screen if page refresh mid-animation gsap.set('.screen', { opacity:0, scale:.4, x:0, y:-100, xPercent:30 }) // Exit Main title gsap.to('.main-title', { y:-150, opacity:0, //filter: "blur(20px)", ease: "none", scrollTrigger: { trigger: '.headline2', start: 'top center', end: 'bottom center', toggleActions: "play none none reverse", markers: false, scrub:1 } }) gsap.set('.headline2 h2', { opacity:0, }) // Phone Headline Opactity gsap.to('.headline2 h2', { ease: "none", opacity:1, scrollTrigger: { pin:false, trigger: '.headline2', start: 'top +=130', end: 'top +=150', toggleActions: "play none none reverse", markers: false, scrub:1 } }) // Reset phone and screen if page refresh mid-animation gsap.set('.screen', { xPercent:30, y:-100, x:0, scale:.4, zIndex:0, opacity:1 }) gsap.set('.phone', { scale:.7, transformOrigin: '50% 100%', opacity:0 //y:-100, }) // Phone Headline Pin gsap.to('.headline2 h3', { //filter: "blur(20px)", ease: "none", scrollTrigger: { pin:true, duration:.5, pinSpacing:false, trigger: '.headline2', endTrigger: ".phone-end-trigger", start: 'top 20%', end: 'top 20%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) gsap.set('.phone', { scale:.7, transformOrigin: '50% 100%', opacity:0 //y:-100, }) // Phone Scale gsap.to('.phone', { //filter: "blur(20px)", ease: "none", scale:1, opacity:1, scrollTrigger: { trigger: '.phone', start: 'bottom 105%', end: 'bottom 95%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) gsap.set('.phone', { scale:1, transformOrigin: '50% 100%', opacity:1 //y:-100, }) // Phone Pin gsap.to('.phone', { //filter: "blur(20px)", ease: "none", scrollTrigger: { pin:true, pinSpacing:false, trigger: '.phone', endTrigger: ".phone-end-trigger", start: 'bottom 90%', end: 'bottom 70%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) // Move the desktop screen back to center gsap.to('.screen ', { scale:1, xPercent:0, y:0, zIndex:1, //filter: "blur(20px)", ease: "none", scrollTrigger: { trigger: '.phone-end-trigger', start: 'top 60%', end: 'top 60%', toggleActions: "play none none reverse", markers: false, scrub:1, onEnter: () => myEnterFunc("onEnter"), onEnterBack: () => myEnterBackFunc("onEnterBack") } }) gsap.set('.phone', { scale:1, transformOrigin: '50% 100%', opacity:1 }) // We're done with the phone, but not done with the show... The Screen Trigger pin is still active... gsap.to('.phone ', { scale:.4, opacity:0, ease: "none", scrollTrigger: { trigger: '.phone-end-trigger', start: 'bottom 70%', end: 'bottom 70%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) // Box / Highlight Animations const sections = gsap.utils.toArray('.highlight') sections.forEach((sec, i) => { const headline = sec gsap.set(headline, { y:50, opacity:0, zIndex:2 }) gsap.to(headline, { y:-50, //filter: "blur(20px)", ease: "none", scrollTrigger: { trigger: headline, start: 'top 70%', end: 'top 30%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) gsap.to(headline, { opacity:1, //filter: "blur(20px)", ease: "none", scrollTrigger: { trigger: headline, start: 'top 70%', end: 'top 65%', toggleActions: "play none none reverse", markers: false, scrub:1 } }) }); } // End MatchedMedia }) // End Home Animation function myEnterFunc(message){ $(".screenHolder img").attr("src", "/img/screen2.png"); } function myEnterBackFunc(message){ $(".screenHolder img").attr("src", "/img/screen1.png"); } Link to comment Share on other sites More sharing options...
GreenSock Posted July 18, 2021 Share Posted July 18, 2021 Welcome to the forums, @gwineman. It's a bit much to ask for a full code review here, but we're happy to answer any GSAP-specific questions. I skimmed your code and there's definitely a fair amount of waste in there. Here are some tips: You can simplify things like: // OLD const sections = gsap.utils.toArray('.highlight') sections.forEach((sec, i) => { const headline = sec gsap.set(headline, { y:50, opacity:1 }) }); // NEW gsap.set('.highlight', {y:50, opacity:1}); You've got a ton of gsap.set() calls you're doing to the SAME element in the SAME function. Consolidate those into one. I'd guess that the majority of your .set() calls could be eliminated. And whenever you have a .set() followed by a .to(), you can almost always simplify to a .fromTo(): // OLD gsap.set('.phone', { scale:1, transformOrigin: '50% 100%', opacity:1 }); gsap.to('.phone ', { scale:.4, opacity:0, ease: "none", scrollTrigger: { trigger: '.phone-end-trigger', start: 'bottom 70%', end: 'bottom 70%', toggleActions: "play none none reverse", markers: false, scrub:1 } }); // NEW gsap.fromTo('.phone', { scale:1, transformOrigin: '50% 100%', opacity:1 }, { scale:.4, opacity:0, ease: "none", scrollTrigger: { trigger: '.phone-end-trigger', start: 'bottom 70%', end: 'bottom 70%', toggleActions: "play none none reverse", scrub:1 } }); Try not to repeat code. You're doing this in both matchMedia functions: gsap.set('.screen', { opacity:0, scale:.7, transformOrigin: '50% 100%', x:0, y:0, xPercent:0 }); So just wrap that in a function that you call from each. That way your code is centralized. I hope that helps. If you run into any trouble, just isolate the issue in a minimal demo and post here. We're always glad to assist with GSAP-specific questions. Enjoy! 1 Link to comment Share on other sites More sharing options...
gwineman Posted July 18, 2021 Author Share Posted July 18, 2021 This is great. Exactly the feedback I was looking for. Sorry to post full code and certainly wasn’t looking for a full review. Just wanted to see if this was generally the right method from 10,000 feet as I’ve never used gsap before. Thank you again for the look! Greg 1 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