ynamite Posted May 30, 2023 Share Posted May 30, 2023 Hi I've been struggling with the issue of conflicting timelines/tweens over and over again. Notice how in the example, the "more info" divs are consistently not appearing after resizing the browser window while the animation is playing (you'll have to open the example in a new tab to see the problem). I can't seem to revert a timeline/tween to it's initial state and reinitializing the timeline/animation after resizing the browser window. I've tried killing and/or clearing a timeline, I've tried spamming `overwrite: true` everywhere, I've tried debouncing the resize event etc. I'm at a wits end ... I've checked the forum but could only find the solutions I've already tried. Neither overwriting nor killing/clearing tweens/timelines seems to do the job, at least not in all cases. Sometimes it works and in other cases it just doesn't. It feels inconsistent and my code is starting to feel quite hacky. I'm probably missing a thing or doing something wrong. The example shown on the following page seems to exhibit the same behaviour I'm experiencing: Once you click on "move back" and then click on "restart" the animation seems to break. At least in the way that I understand it. By clicking "restart" I'd expect the element to move back to the right edge and roll back to the left (like it doesk on page load). Instead it just hangs and rolls on the left. Thanks! See the Pen jOeovBm by ynamite (@ynamite) on CodePen Link to comment Share on other sites More sharing options...
Solution Rodrigo Posted May 30, 2023 Solution Share Posted May 30, 2023 Hi, Your problem is here: gsap.set(gsap.utils.toArray(entry, name, desc, details), { clearProps: true }); If you check the docs for the toArray method you'll see that the second parameter it's a scope element or selector: Parameters targets : [Object | String | NodeList | Array] - The target(s) that you want wrapped in a flattened Array (it can be selector text, objects, NodeList, jQuery objects, etc.) scope : [Element | Ref] (optional) - The Element (or React ref) to which the selector text scope should be limited, like calling .querySelectorAll([selector-text]) on this Element rather than the document. In other words, it will only return descendant Elements of the scope Element, like jQuery.find(). This is only helpful when targets is selector text. So basically you're telling GSAP, create an array with the entry element and use the name element as scope, the other two (desc and details) are just ignored, because the method is expecting two parameters. There are two solutions: Pass an array with the elements to the method: gsap.set(gsap.utils.toArray([entry, name, desc, details]), { clearProps: true }); Don't use the toArray method. Those elements are already DOM nodes so you can wrap them in an array and be done with it: gsap.set([entry, name, desc, details], { clearProps: true }); Hopefully this helps. Happy Tweening! 3 Link to comment Share on other sites More sharing options...
ynamite Posted May 31, 2023 Author Share Posted May 31, 2023 Thanks a lot @Rodrigo that indeed fixes the problem. My code still feels overly verbose though. Any other tips to share? Suggestions are welcome. Here's an updated codepen for anyone interested: See the Pen eYPwNwY by ynamite (@ynamite) on CodePen Link to comment Share on other sites More sharing options...
Rodrigo Posted May 31, 2023 Share Posted May 31, 2023 Hi, The only thing I can spot is this: if (splits.length) { splits.forEach((split, idx) => { split.revert(); if (tl) { split.elements.forEach((el) => { gsap.set(el, { clearProps: true }); }); } }); } No need to do clearProps after the revert method. The revert method does that for you, so this will have the same effect: if (splits.length) { splits.forEach((split, idx) => { split.revert(); }); } Also this shouldn't have any effect whatsoever: const tl = gsap.timeline({ pause: true, scrollTrigger: { trigger: rowJobs, toggleActions: "play pause resume reset", start: "25% bottom", markers: true, }, onStart: () => { // refresh scrollTrigger on page load to ensure correct scrollTrigger start/end tl.scrollTrigger.refresh(); } }); I don't see the use of that particular refresh method there, when the timeline that has that particular ScrollTrigger config starts, to refresh it's own ScrollTrigger instance. ScrollTrigger already watches for resize events so there is no need for that, if that's what you're aiming for. Other than that your code is quite clear. Hopefully this helps. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
ynamite Posted June 1, 2023 Author Share Posted June 1, 2023 Perfect! Thank you 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