ektorp Posted December 5, 2023 Share Posted December 5, 2023 Hello team Greensock - I am looking to do a fairly basic hover cursor follow within bounds using GSAP. I've looked around the forums and have seen many cursor followers but none within bounds. If you view the attached codepen and scroll down EXACTLY to the middle screen, it is working as expected. The issue is that once you scroll the page up or down, and then hover over the circle call to action, the hover interaction basically falls apart. I am using gsap.getProperty and gsap.quickTo to set the intended coordinates but there is apparently an issue. If you scroll up or scroll down and then hover over the CTA, you will see how things get misaligned and offset. The circle should never fully flow outside of the box container as it currently does. I believe it is some miscalculation and/or misuse of gsap.getProperty and/or gsap.quickTo. Any help with getting this resolved would be greatly appreciated. This is the approach I took with this specific interaction. I am open to other ideas of how this can be done. The GSAP website under the UI page has a very similar interaction that I am looking to achieve. Many of the GSAP website interactions are often included on Codepen but I was not able find one for this use case. On the GSAP UI page, under the "Create complex UI in a snap (Or click)" section, the bottom center element with the circle is basically what I am looking to do, without SVG, just standard divs: https://gsap.com/ui/ See the Pen ZEwVzMo by bdang (@bdang) on CodePen Link to comment Share on other sites More sharing options...
alig01 Posted December 5, 2023 Share Posted December 5, 2023 Hey, I played with a similiar effect a while back. See the Pen mdaeEmm?editors=0010 by alig01 (@alig01) on CodePen I'm not sure if this is the best approach, since it didn't make it into production so I stopped testing it. But it should for sure lead you into the right direction. Some more infos: difference: pageX and clientX, BoundingClientRect The key is to take the scrolling of the page into account. Hope this helps and good luck with your project. 4 Link to comment Share on other sites More sharing options...
Rodrigo Posted December 5, 2023 Share Posted December 5, 2023 Hi, You can use GSAP's Clamp utility method to prevent the circle from moving out of the bounds. Here is a super simple demo I whipped: See the Pen VwgqrGm by GreenSock (@GreenSock) on CodePen https://gsap.com/docs/v3/GSAP/UtilityMethods/clamp() Hopefully this helps. Happy Tweening! 3 Link to comment Share on other sites More sharing options...
ektorp Posted December 5, 2023 Author Share Posted December 5, 2023 @alig01 @Rodrigo Thank you both for your input and feedback. The getBoundingClientRect and GSAP’s clamp utility were both key points for this solution. Thank you so much for your help and assistance. 1 Link to comment Share on other sites More sharing options...
ektorp Posted December 11, 2023 Author Share Posted December 11, 2023 Hi @Rodrigo - Thanks again for your assistance with this issue. I've made some updates to have the element animate and ease into place. As you mousemove and mouseleave, everything moves nice and smooth. The only outstanding issue is on the mousemove event. On the initial mousemove event, the ball nicely animates into place. And this continues as you mousemove and mouseleave the ball. But once you come back to it and mousemove it again, the ball just jumps into place without the animation or easing. The user experience is not ideal. Is this an issue you can assist with? Again, your help and assistance is greatly appreciated. See the Pen BaMvmvr by bdang (@bdang) on CodePen Link to comment Share on other sites More sharing options...
Solution Rodrigo Posted December 11, 2023 Solution Share Posted December 11, 2023 Hi, Yeah because of the way quickTo works, you need to clear the last X/Y values in order start with the current ones, so you can add an onComplete callback in your mouseleave instance to flush those values using the invalidate method: let tX, tY; const setX = gsap.quickTo(".ball", "x", {duration: 0.5, ease: "power3"}); const setY = gsap.quickTo(".ball", "y", {duration: 0.5, ease: "power3"}); listener.addEventListener("mousemove", (e) => { tX = setX(clamperX(e.offsetX - dimensions.width / 2)); tY = setY(clamperY(e.offsetY - dimensions.height / 2)); }); listener.addEventListener("mouseleave", () => { gsap.to(".ball", { x: 0, y: 0, ease: "back.out", duration: 0.5, onComplete: () => { tX.invalidate(); tY.invalidate(); } }); }); That seems to work the way you expect. Hopefully this helps. Happy Tweening! 2 Link to comment Share on other sites More sharing options...
ektorp Posted December 11, 2023 Author Share Posted December 11, 2023 Thanks so much once again @Rodrigo ...your assistance is very much appreciated. 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