Jump to content
Search Community

Looking for general thoughts on my logic sequence

gwineman test
Moderator Tag

Recommended Posts

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

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:

  1. 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});

     

  2. 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
      }
    });

     

  3. 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!

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
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...