Jump to content
Search Community

Handling window resize with a horizontal animation

pattyb test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hey there GSAP fans,

 

Loving using GSAP and ScrollTrigger. I'm a little lost on how to handle a window resize event. The animation and ScrollTrigger is functioning exactly how I want it to. My problem is that after the animation has been initiated and a client resizes their browser the tween does not seem to recalculate where its position should be relative to the window's new width. 

 

To replicate what I'm trying to resolve. 

1.) Open codesandbox in separate browser window so it can be resized.

2.) Scroll until the animation starts, then scroll to the top of the page.

3.) Resize browser window wider and notice how image one pulls away from the left side of the window. Similarly, if you resize the window narrower than when animation was initiated, image one is pushed outside and left of the viewport even when scrolled all the way to the top.

 

How do I handle the tween recalculating where it should be horizontally similarly to if you'd refresh the page?

 

Thanks in advance for any help here.

 

sandbox link for minimal demo.

https://codesandbox.io/s/gsap-bugfix-0vd6l?file=/pages/index.vue

Link to comment
Share on other sites

  • Solution

Welcome to the forums, @pattyb!

 

When a tween renders for the first time, it records the starting and ending values so that it can very quickly interpolate between them during the course of the animation. You are animating the "right" property, thus it records whatever it is initially (and that is based on the viewport width in your setup). When you kill() the ScrollTrigger, it reverts any associated animation to its starting values. So let's say in your case the viewport is a width that causes the right edge of your content to be 500px off the edge, thus right: 500px. That gets recorded as the start. Then when the user resizes, you're killing the ScrollTrigger which reverts to that 500px value (inline)...and therefore that serves as the start of the one you're re-creating too (I noticed your function gets called on every resize). See the issue? 

 

The solution is pretty simple once you understand what's happening - just wipe out the "right" value from your element BEFORE you create your new ScrollTrigger/animation: 

document.querySelector(".animatedCarousel").style.removeProperty("right");
this.animation = gsap.timeline({
  scrollTrigger: {
    ...

Does that clear things up? 

Link to comment
Share on other sites

@GreenSock Thank you for the speedy reply. I've been doing some experimenting and was wondering if there is a way to avoid killing the instance? I see a lot of methods available on the timeline but am not seeing a clear way to clear the current interpolation and register a new interpolation within the current timeline instance.

The below code is a direction I would like to take but am missing methods to update the interpolation.
 

    handleWindowResize() {
      const progressState = this.animation?.progress()
      const animatedElement = document.querySelector(".animatedCarousel").style.right
      this.animation.pause(progressState)
      // update current animation based on window resize
	  this.animation.resume(progressState)
    },

Essentially I'm trying to handle a window resize more elegantly without the animation jumping around and without needing to start from 0 if mid animation.

Thank you.

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