JanaB Posted August 18 Share Posted August 18 Hello, Would anyone have an idea how to control GLB model rotation on scroll? I'm trying to get the model to return to it's original position on scroll if and when it's been rotated. I've enabled rotation for screen 2 and 3 and if user rotates the model I'd like it to go back to original position that was set in timeline. It seems to be working fine when scrolling down, but when scrolling up it remembers the position it was manually rotated to rather than what's set in the timeline. I've tried using toggleActions for each timeline, but it was breaking everything even more. Any help would be appreciated! Here's the link to CodeSandbox . Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 18 Share Posted August 18 Hi @JanaB welcome to the forum! I'm getting a "Project not found" when opening the CodeSandbox link. If the issue persist on Codesandbox, we recommend using our Stackblitz starter templates. 1 Link to comment Share on other sites More sharing options...
JanaB Posted August 18 Author Share Posted August 18 Hi @mvaneijgen, Would GitHub link be of any help? I cannot seem to work out how to get it to Stackblitz. https://github.com/JanaBobulis/snap-scroll/tree/main/src https://https-github-com-jana-bobulis-snap-scroll-bl9t.vercel.app/ Alternatively I could paste part of ScrollTrigger code here? Link to comment Share on other sites More sharing options...
Cassie Posted August 18 Share Posted August 18 Hiya, can you replicate the issue with a normal rotation on a DOM element? i.e. Is this a scrolltrigger logic issue or is it an issue with three.js? Often people bring us demos with React and three.js and all sorts but it's actually just a simple logic/scrolltrigger syntax issue. This sounds like a scrolltrigger settings issue to me, especially if you're getting tangled with toggleactions. I'm afraid we struggle a little with github repos and live sites, it's a lot to sift through, so if you can simplify it down that would be amazing. If you try to apply the scrolltrigger logic to a DOM element and everything is working as expected then at least we know for sure it's a three.js thing and we know where to look. Maybe you could use this as a starting point? See the Pen MWBLwLX?editors=0110 by GreenSock (@GreenSock) on CodePen Link to comment Share on other sites More sharing options...
JanaB Posted August 21 Author Share Posted August 21 I've now changed it to cube model instead, hopefully this is helpful? - See the Pen vYvEmmL by janabobulis (@janabobulis) on CodePen I don't have a lot of experience with ScrollTrigger so maybe there's something I'm missing? It works as expected when scrolling down, but not when scrolling back up. Link to comment Share on other sites More sharing options...
Cassie Posted August 21 Share Posted August 21 Heya - so I've simplified it down and this seems to be working. Maybe just gently try layering back in and checking if and when the issue occurs. Pop back if you find the problem and we'll troubleshoot with you! See the Pen RwENLXg?editors=0010 by GreenSock (@GreenSock) on CodePen Note - I noticed you're using intersection observer which seems a little odd if you're already loading in ScrollTrigger. ScrollTrigger does everything intersection observer can do, but with less code and more performantly in a lot of cases. 2 Link to comment Share on other sites More sharing options...
JanaB Posted August 31 Author Share Posted August 31 Hi Cassie, Thanks so much for getting back to me and thanks for your suggestions re. intersection observer! It now looks very close to what I'm trying to achieve - one thing I cannot figure out is how to make the animation(timelines) look continuous. I've added camera.position to each one of those timelines as that helps with controls and resetting the position of the model if it's been rotated on screen 2 and 3. It's adding the new problem though - animation seems to restart each time it's scrolled rather than flowing smoothly. See the Pen yLGyZrQ?editors=0010 by janabobulis (@janabobulis) on CodePen Link to comment Share on other sites More sharing options...
Rodrigo Posted August 31 Share Posted August 31 Hi, The issue is that GSAP renders that instance immediately, so it takes the element from the value it has at that point. The thing is that at that moment the camera's position is 0, not 3 so it goes from 0 to 3. To prevent that you can tell ScrollTrigger to not render the animation at run time but when the scroll position reaches that point using immediateRender: false: gsap.to(camera.position, { x: 0, y: 0, z: 3, duration: 1, scrollTrigger: { trigger: "#screen2", endTrigger: "#screen3", start: "top top", end: "bottom bottom", immediateRender: false, // markers: true, id: 2, scrub: 1 } }); Finally it gets my attention that the previous animation has the same values so the camera position is not being updated at all. Just a comment that having this extra instance seems pointless, unless your real life scenario is different from the codepen example. Hopefully this helps. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
JanaB Posted September 1 Author Share Posted September 1 Thanks Rodrigo! I've added it back now. That brings me back to my initial problem with the model not rotating to it's original position. I've set controls.enableRotate for screen 2 and screen 3 so that when the model has been moved/rotated it would go back to it's original position on scroll. Unfortunately it's not returning to its original position on scroll. I've created a 'reset' button with the following code, to show what I'm after. This is rendered on click, but I'd like the same to be rendered on scroll. Is there a way to incorporate it with the timeline? let returnToOriginalDesktop = gsap.timeline({ duration: 2, paused: true, immediateRender: false }); returnToOriginalDesktop.to( camera.position, { x: 0, y: 0, z: 3.7, duration: 1 }, "<" ); document .querySelector(".reset-model") .addEventListener("pointerdown", function () { returnToOriginalDesktop.play(); returnToOriginalDesktop.restart(); }); You mentioned camera position values are the same and therefore they're not being updated. Is there another workaround for the same logic? Thanks! Link to comment Share on other sites More sharing options...
Solution Rodrigo Posted September 1 Solution Share Posted September 1 Hi, What you could try is that in your button event handler you can invalidate the timeline instance: https://greensock.com/docs/v3/GSAP/Timeline/invalidate() const tl = gsap.timeline({ scrollTrigger: { // all your ST config }, }); // Later on your code tl.invalidate(); Another option could be to manually refresh the particular ScrollTrigger instance and add invalidateOnRefresh in the ScrollTrigger config: const tl = gsap.timeline({ scrollTrigger: { // all your ST config invalidateOnRefresh: true, }, }); // Later on your code tl.scrollTrigger.refresh(); If this is not helping, please be super specific about what you're trying to do, kind of explain step by step the procedure of what you intend to do and what is your desired outcome, because right now is not 100% clear to me what you're trying to achieve here. Hopefully this helps. Happy Tweening! 1 1 Link to comment Share on other sites More sharing options...
JanaB Posted September 7 Author Share Posted September 7 Thank you, Rodrigo! First solution worked well for me. I've wrapped it inside onComplete. onComplete: function() { tl.invalidate(); } 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