Jump to content


Multiple pinned scrolltriggers on the same element wrong offset on resize

Go to solution Solved by GreenSock,

Recommended Posts

Hey hey,

I have discovered ScrollTrigger a few months ago. I just wanted to add that this plugin is amazing and almost works out of the box for a simple animation. I have tried to do animations in the past without ScrollTrigger (with deboucing, throttling and animationFrames) but I couldn't get it as smooth as ScrollTrigger. Thank you for this wonderful work!

I have been searching this forum for a while but I can't find anything that helps. So after a few days, and many hours of struggling, I finally got the courage to make my first post.

The situation:

I have an element that is pinned in the middle of my screen (height 100%).
As soon as it reaches a certain point in my website, a second ScrollTrigger takes over, that also pins the element in the middle of the screen (element is now height 50%). This second ScrollTrigger adds another animation to translate 'image2' upwards to cover up 'image1'.

The reason that you see translateX's in the animation is because 'image1' needs to be on the same position at all times (also has a vw-size instead of %, ignoring the parent's width animation).

I used two ScrollTriggers because it is very important to be able to control where the first ScrollTrigger ends (ends exactly on a new section).
I have searched for a solution for many many hours and I am sincerely hoping that I'm doing something absolutely forbidden or that I have encountered a bug in ScrollTrigger.

The problem:

Every time I resize my window (or refresh my page) AND the second ScrollTrigger is activated, the pinned element jumps down, getting a wrong translateY that keeps growing every resize tick.

For example:
my 'pin' is now at transform: translate(0%, -50%) translate3d(0px, 461.001px, 0px);
The transform: translate(0%, -50%) is a value from my CSS to center the element in my window.
When I resize my screen 1px, the 'pin' moves instantly to 
transform: translate(0%, -50%) translate3d(0px, 922.002px, 0px); 
When I resize my screen another px, the 'pin' moves instantly to 
transform: translate(0%, -50%) translate3d(0px, 1383px, 0px);
Meaning that it will get the wrong position very quickly. This only happens when I resize below the first ScrollTrigger (so as soon as the second ScrollTrigger took over).

Am I doing something absolutely wrong here?
I am working for a client so I can't really share the project just yet.
Can you guys help me out? Many thanks in advance.

(Quickly deleted my items and replaced my images with some unsplash images. Yes this entire forum will be hungry now!)

PS. I would love to use scale instead of animating the width and height, but I can't seem to make it work.
My image that isn't allowed to scale (but nested in the element that needs the scale) shrinks too. So I would animate it to scale(2) but it doesn't seem to go linear, making the animation incorrect (also very hard with the translateX at the same time). But thats for a whole different topic. If you have any other feedback on how I coded the timelines, please shoot! I can only learn :)


// register scrolltrigger

// animate the hero image

function heroImage() {

	// get elements to animate
	const trigger = document.querySelector('#dtx-hero')
	const pin = document.querySelector('#dtx-hero--image--pin')
	const imageContainer = pin.querySelector('#dtx-hero--image')
	const image1Container = pin.querySelector('#dtx-hero--image-1--container')
	const image1 = pin.querySelector('#dtx-hero--image-1')
	const image2 = pin.querySelector('#dtx-hero--image-2')

	// create scrolltrigger
	const GSAP_timeline = gsap.timeline({
		defaults: { ease: 'linear' },
		scrollTrigger: {
			trigger: trigger,
			pin: pin,
			start: 'top top',
			end: 'bottom center',
			scrub: true,
			pinSpacing: false

			{ height: '100%' },
			{ height: '50%' }
		, '<')
			{ width: '100%' },
			{ width: '50%' }
		, '<')
			{ x: 0 },
			{ x: '-11.25vw' }
		, '<')
			{ x: 0 },
			{ x: '11.25vw' }
		, '<')
			{ xPercent: 0, y: 0 },
			{ xPercent: -50, y: 0 }
		, '<')
			{ yPercent: 100, y: 0 },
			{ yPercent: 50, y: 0, ease: 'sine.in' }
		, '<')

	// create scrolltrigger 2
	const GSAP_timeline2 = gsap.timeline({
		defaults: { ease: 'linear' },
		scrollTrigger: {
			trigger: '#dtx-intro',
			pin: pin,
			start: 'top center',
			endTrigger: '#dtx-intro .dtx-content',
			end: 'center center',
			scrub: true,
			pinSpacing: false

			{ yPercent: 50, y: 0 },
			{ yPercent: 0, y: 0, ease: 'sine.out' }





Link to comment
Share on other sites

Hey heymeindert and welcome to the GreenSock forums!


It's really hard to understand the effect that you're going for and debug the issue based on only the code that you're provided. It's extremely helpful for us to have a minimal demo. Do you think you could create one using unsplash photos for us?


Link to comment
Share on other sites


Thank you for your reply.
It took much less effort and time than I thought to reproduce it in a Codepen!

See the Pen bGwEOaV by heymeindert (@heymeindert) on CodePen

The bug happens here too.
When you resize your window (when the 2nd ScrollTrigger is activated), the pin jump down.

Edit: doesn't seem to work in the iframe but works if you click on edit on codepen

  • Thanks 1
Link to comment
Share on other sites

  • Solution

Thanks for pointing that out. It was indeed using a cached value on subsequent refreshes. That should be fixed in the next release which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js


Here's a fork that seems to be working with the new file - better? 

See the Pen e7a1ab154bd63ecd8a5f5c2145ef7be1?editors=0010 by GreenSock (@GreenSock) on CodePen


  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Hey Jack,

Glad I could help to make this plugin even better :)
It works like a charm now, thanks!


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.