serhiiL Posted June 4 Share Posted June 4 (edited) Hi GSAP Community, I am working on an animation where an element (targetEl) moves between different zones (zoneEl) as the user scrolls. However, I'm facing an issue with tracking the initial position of targetEl correctly. The targetEl is inside zoneEl.first(), which is in another div with a height of 1500dvh and is animated to move from right to left by -100dvh. This movement is causing the targetEl to start in the wrong position, and the animation does not play correctly. Here is the code I am using (fille in attaches): window.addEventListener("DOMContentLoaded", (event) => { // SETUP PLUGINS gsap.registerPlugin(ScrollTrigger, Flip); ScrollTrigger.normalizeScroll(true); // SETUP ELEMENTS let zoneEl = $("[js-scrollflip-element='zone']"), targetEl = $("[js-scrollflip-element='target']").first(); // SETUP TIMELINE let tl; function createTimeline() { if (tl) { tl.kill(); gsap.set(targetEl, { clearProps: "all" }); } tl = gsap.timeline({ scrollTrigger: { trigger: zoneEl.first(), start: "center center", endTrigger: zoneEl.last(), end: "center center", scrub: true } }); zoneEl.each(function (index) { let nextZoneEl = zoneEl.eq(index + 1); if (nextZoneEl.length) { let nextZoneDistance = nextZoneEl.offset().top + nextZoneEl.innerHeight() / 2; let thisZoneDistance = $(this).offset().top + $(this).innerHeight() / 2; let zoneDifference = nextZoneDistance - thisZoneDistance; tl.add( Flip.fit(targetEl[0], nextZoneEl[0], { duration: zoneDifference, ease: "power2.inOut" }) ); } }); } createTimeline(); // SETUP RESIZE let resizeTimer; window.addEventListener("resize", function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { createTimeline(); }, 250); }); }); The problem is that targetEl is positioned incorrectly because zoneEl.first() is animated with a -100dvh shift from right to left. I need to track the initial position of targetEl correctly so that the animation starts at the correct position with the right coordinates and dimensions. I have included a video explanation and a link to my site for more context: Video: https://www.loom.com/share/9bfb3434afcc432b8fb6ab969bed136c?sid=188e85ea-b5a8-42f3-bd02-f52f103f7b57 Website: https://s-liudvichenko.webflow.io Any help or suggestions would be greatly appreciated! Thank you! gsap--flip-ds-layer.js See the Pen JjqNvyP by SL-Fama (@SL-Fama) on CodePen Edited June 4 by serhiiL Added Codepen project Link to comment Share on other sites More sharing options...
GSAP Helper Posted June 4 Share Posted June 4 Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependencies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer. See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: Using a framework/library like React, Vue, Next, etc.? CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: React (please read this article!) Next Svelte Sveltekit Vue Nuxt Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. ✅ Link to comment Share on other sites More sharing options...
serhiiL Posted June 4 Author Share Posted June 4 Hello @GSAP Helper. I've added my Codepen project. Sorry that I didn't do it at the beginning. Here is a link See the Pen JjqNvyP by SL-Fama (@SL-Fama) on CodePen Link to comment Share on other sites More sharing options...
Rodrigo Posted June 4 Share Posted June 4 Hi, I'm having a hard time following the logic behind your demo, plus you have some CSS Transitions in it as well. Also there is no scrolling available in your demo but for some reason as I scroll down more and more scrolling becomes available (the scroll bar becomes smaller and smaller). I think you have to review your HTML and CSS in order to make this work. Maybe a simpler approach could be a better fit for this situation. This demo is a demonstration of how this works: See the Pen JjVPyxd by GreenSock (@GreenSock) on CodePen Hopefully this helps. Happy Tweening! Link to comment Share on other sites More sharing options...
serhiiL Posted June 4 Author Share Posted June 4 Hey @Rodrigo. I apologize for that, but it was necessary to show the issue I was facing (I've updated my Codepen so it should scroll correctly now). The problem is that my trigger is placed in a div with sticky positioning and an animation that moves it from right to left. Because of this, the initial position was captured incorrectly. I'm wondering if there's a way to set the initial state of the trigger when the animation begins, or to track the position of the target while it animates and scrolls inside the parent div. Are there any GSAP techniques for handling dynamically changing positions of animated elements? Thanks in advance for your help! Link to comment Share on other sites More sharing options...
mvaneijgen Posted June 4 Share Posted June 4 2 hours ago, serhiiL said: The problem is that my trigger is placed in a div with sticky positioning Yep this is something you can't do, if you want to elements to stick, you'll have to let ScrollTrigger handle all the stickiness with using the pin feature in ScrollTrigger, you cant have position: sticky; on an element and use ScrollTrigger on it. Link to comment Share on other sites More sharing options...
Rodrigo Posted June 4 Share Posted June 4 While a more convoluted setup can be achieved, that would require a lot of custom logic and that is a bit beyond the scope of what we do in these free forums, since we don't have the time resources to create custom solutions for our users or solve complex logic issues. At it's core, Flip.fit() will get the states of both elements and animate the first to match the second. The issue here is when is done, not how is done. This is happening while there is another animation that changes the position after those Flip.fit() instances have been created, so naturally that messes all those calculations. In the demo I have there is no initial animation so everything is in it's final position at the start, when the states for the second and third targets are created using getState(). That's why I suggested a simpler approach in my previous post. Hopefully this helps. Happy Tweening! Link to comment Share on other sites More sharing options...
Solution serhiiL Posted June 5 Author Solution Share Posted June 5 Hello @Rodrigo, @mvaneijgen. I know this isn't a common case, so that's okay. Thank you for your time anyway. I handled it by creating a new timeline to capture the position when a specific element enters into view. // Trigger a function when the position element enters the viewport ScrollTrigger.create({ trigger: positionEl, start: "top bottom", onEnter: function () { // Execute the createTimeline function when positionEl enters the viewport createTimeline(); } }); I know it’s not the most elegant solution, but it works for my case. The Codepen has been updated as well, in case someone needs such a weird solution. Cheers 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now