Jump to content
Search Community

Pinned item messes up the remaining animations

jsd219 test
Moderator Tag

Recommended Posts

I am running several animations on the page. Once the user scrolls through the animatedImages the remaining paragraphs and dividers animation's start and end markers get messed up.

 

See screen shot for the messed up markers.

 

2095752260_ScreenShot2021-12-15at12_28_55PM.thumb.png.1c9e6b5f779b007a13ef0b9939368706.png

 

Below is my code:

 

    const animatedImages = gsap.utils.toArray('.animated-photo-section')

	animatedImages.forEach((ai, i) => {
		
		let h = gsap.getProperty(ai, 'height', 'px')
		var scrollHeight = h + h / 2

		gsap.to(ai, {
		  scrollTrigger: {
		    trigger: ai,
		    pin: '#et-main-area',
		    // pinSpacing: false,
		    start: 'top 100',
		    end: '+='+scrollHeight,
		    scrub: 1,
		    // toggleActions: "restart none none pause",
		    // markers: true,
		    onUpdate: (self) => {
		    	// console.log("update", index, self.progress.toFixed(3))
		    	$(ai).find('.animated-photo-image-outline').css({
		    		opacity: 1- self.progress.toFixed(3)
		    	})
		    	$(ai).find('.animated-photo-image-full').css({
		    		opacity: self.progress.toFixed(3)
		    	})
		    },
		  }
		})

	})

	// header animation
	gsap.from(".post-header-content div", {duration: 1, delay: 0.5, scale: 0, opacity: 0, stagger: 0.2})

	// paragraphs animation
	const paragraphs = gsap.utils.toArray('.standard-copy p')
	gsap.set(paragraphs, {autoAlpha: 0, y: 50})
	
	paragraphs.forEach((paragraph, i) => {
  		// Set up your animation
	  	const anim = gsap.to(paragraph, {duration: 1, autoAlpha: 1, y: 0, paused: true})
	  
	  	// Use callbacks to control the state of the animation
	  	ScrollTrigger.create({
	    	trigger: paragraph,
	    	end: "bottom bottom",
	    	once: true,
	    	// markers: true,
	    	// toggleActions: "restart pause reverse pause",
	    	onEnter: self => {
	      		// If it's scrolled past, set the state
	      		// If it's scrolled to, play it
	      		self.progress === 1 ? anim.progress(1) : anim.play()
	    	}
	  	})
	})

	const dividers = gsap.utils.toArray('.section-divider-icon')
	// gsap.set(dividers, {autoAlpha: 0, y: 50})

	dividers.forEach((divider, i) => {
		// Set up your animation
		const zoom = gsap.from(divider, {duration: 1, autoAlpha: 0, scale:0.03, rotation:360, ease:Power1.easeInOut, paused: true})
		
		// Use callbacks to control the state of the animation
	  	ScrollTrigger.create({
	    	trigger: divider,
	    	start: "bottom bottom",
	    	once: true,
	    	// markers: true,
	    	// toggleActions: "restart pause reverse pause",
	    	onEnter: self => {
	      		// If it's scrolled past, set the state
	      		// If it's scrolled to, play it
	      		self.progress === 1 ? zoom.progress(1) : zoom.play()
	    	}
	  	})
	})

	// logo animation
	gsap.set('.sf', {fill: "rgba(255,255,255,.15)"})

	gsap.to('.sf', {
		fill: "#fff",
		duration: 3,
		delay: 2,
	})

 

See the Pen abLJgNb by jsd219 (@jsd219) on CodePen

Link to comment
Share on other sites

Welcome to the forums, @jsd219. Unfortunately we don't have the resources to troubleshoot a live site (please read the forum guidelines) but it sounds like maybe you're animating things in one set of ScrollTriggers that shift things around on the page that'd affect later ScrollTriggers. If so, that's very tricky to accommodate logically. Not totally impossible, but you'd probably need to wire up some custom logic. 

 

If you need help, please isolate the condition in a minimal demo and post here (like a simple CodePen). 

 

By the way, this looked very strange to me: 

gsap.to(ai, {
  scrollTrigger: {
    trigger: ai,
    pin: '#et-main-area',
    start: 'top 100',
    end: '+='+scrollHeight,
    scrub: 1,
    onUpdate: (self) => {
      $(ai).find('.animated-photo-image-outline').css({
        opacity: 1- self.progress.toFixed(3)
      })
      $(ai).find('.animated-photo-image-full').css({
        opacity: self.progress.toFixed(3)
      })
    },
  }
})

That onUpdate() is rather expensive. You're asking jQuery to find 2 nodes every single time and then set the opacity. This should be cleaner/faster: 

gsap.timeline({
	scrollTrigger: {
		trigger: ai,
		pin: '#et-main-area',
		start: 'top 100',
		end: () => '+=' + scrollHeight,
		scrub: 1,
	},
	defaults: {ease: "none"}
}).fromTo($(ai).find('.animated-photo-image-outline'), {opacity: 1}, {opacity: 0})
  .fromTo($(ai).find('.animated-photo-image-full'), {opacity: 0}, {opacity: 1}, 0);

Also, I noticed this: 

onEnter: self => {
  // If it's scrolled past, set the state
  // If it's scrolled to, play it
  self.progress === 1 ? zoom.progress(1) : zoom.play()
}

You should check out fastScrollEnd: true feature added in 3.8.0. It would probably simplify that for you :)

 

Link to comment
Share on other sites

Hi jsd,

 

I think you might be looking for the pinnedContainer property to prevent the shifting.

 

Quote
pinnedContainer Element | String - If your ScrollTrigger's trigger/endTrigger element is INSIDE an element that gets pinned by another ScrollTrigger (pretty uncommon), that would cause the start/end positions to be thrown off by however long that pin lasts, so you can set the pinnedContainer to that parent/container element to have ScrollTrigger calculate those offsets accordingly. Again, this is very rarely needed. (added in 3.7.0)

 

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