Jump to content
Search Community

Translate the pinned element after pinning "ends"

2Pacalypse- test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hi, I have the following animation:

  1. After scrolling for a bit, I need to pin an element
  2. After scrolling for a bit more, the pinned element gets unpinned
  3. As soon as the element gets unpinned I need to run a tween which translates the element to a specific x/y position
  4. On scrolling backwards, the tween needs to play in reverse order


I attached the codepen with the minimal amounts of code (I used React & styled-components for ease of use) to show where I got so far. The problem I'm noticing is that when the element gets unpinned, the morphing animation starts playing from initial position of the pinned element, not from the position it had when it got unpinned.


I guess this kind of makes sense due to how pinning works (pin-spacer adds position: fixed to the pinned element and then just permanently translates it after it's unpinned). So my assumption is that I would have to do something like this:

const morphAnimation = gsap.fromTo(
    y: (index, target) => {
      // Read the `translateY` value that the pin-spacer added to the
      // pinned element and start the animation from there?
      return new DOMMatrix(getComputedStyle(target).transform).m42
    x: () => buttonRef.current.offsetLeft - CIRCLE_LEFT + BUTTON_PADDING / 2,
    y: () => buttonRef.current.offsetTop - CIRCLE_TOP + BUTTON_PADDING / 2,
    ease: "none",
    duration: 3,
    paused: true,

But this doesn't quite work for some reason.


Is there an official way of reading the position of the element after it gets unpinned? Also, I'm not sure if this same tween can work in reverse, since it's animating into a position: fixed that's added after the element is pinned again on backwards scroll. Any ideas on how to make the reverse animation work as well?


Thank you for your help!

See the Pen WNaLYyX by 2Pacalypse- (@2Pacalypse-) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @2Pacalypse- and welcome to the GreenSock forums!


I don't have time right now to create a custom example from scratch for this. I know my way around React but I don't know enough about styled components to get it working the way I intend. Here is my idea:


Instead of using a regular animation I'd use the Flip plugin to reparent the circle using conditional rendering, this would require an extra wrapper for the circle at and use the onLeave and onEnterBack callbacks to trigger that animation. Also an extra wrapper means that you don't have to pin the circle (actually I think that's the main cause of your issues right now), but you can pin the wrapper and animate the circle a lot easier with Flip. Here is a super simple example using re-parenting to create the animation:

See the Pen MWyGoxZ by GreenSock (@GreenSock) on CodePen


Hopefully this is enough to get you started.

Happy Tweening!

Link to comment
Share on other sites

Hi @Rodrigo!


You know, I was actually already starting to think on how I could move the circle element to be inside the button itself after the pinning ends, but the task seemed pretty daunting. I had no idea Flip existed. That's amazing!


That's exactly what I needed, thank you so much.


For any other brave souls stumbling on a similar problem, I've updated my codepen to use Flip and it works like a charm.

  • Like 2
  • Thanks 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...