ncla Posted January 18, 2022 Share Posted January 18, 2022 This seems to be a regression when going from 3.7.0 to 3.8.0 version. To reproduce, just scroll past the second spacer swiftly. You should see that the blur animation is stuck in time and the debug markers are removed. See the Pen eYGoRmw by ncla (@ncla) on CodePen Link to comment Share on other sites More sharing options...
_Greg _ Posted January 18, 2022 Share Posted January 18, 2022 1 hour ago, ncla said: debug markers are removed. You set once: true so the ScrollTrigger will kill() itself as soon as the end position is reached once Why did 1 hour ago, ncla said: blur animation is stuck I don't know. I see that after kill - blur for #spacer2 is not equal 0 its sometimes 0.01px, sometimes 2.0331px... its like random, I don't know hot to fix it 1 Link to comment Share on other sites More sharing options...
Carl Posted January 18, 2022 Share Posted January 18, 2022 the team will have to comment on whether it's a bug or not, but in case it helps anyone, having scrub:true (not a number) seems to make it work properly. adding fastScrollEnd:true did not seem to have any impact. when scrub is a number it means the animation has to catch up to the scroll position with a slight ease. I guess in some ways it makes sense that since the animation is killed instantly when you leave (before it is finished catching up) you are seeing it in this "stuck" state. Link to comment Share on other sites More sharing options...
OSUblake Posted January 18, 2022 Share Posted January 18, 2022 As @_Greg _ pointed out, using once will kill it, but maybe the threads linked in this post can help you out. Link to comment Share on other sites More sharing options...
GreenSock Posted January 18, 2022 Share Posted January 18, 2022 Yep, that's because once: true will kill it as soon as you reach the end scroll position, and you've got a delayed scrub value which means the animation is likely in the process of being scrubbed at that point and is killed. I've added code to the next release to allow the scrub to finish in that case - you can see that in this fork: See the Pen GRMLYzW?editors=0010 by GreenSock (@GreenSock) on CodePen But in the meantime, you can simply remove the once: true and do this instead: onLeave: self => self.getTween().eventCallback("onComplete", () => self.kill(false)), Better? 3 Link to comment Share on other sites More sharing options...
ncla Posted January 19, 2022 Author Share Posted January 19, 2022 Thanks everyone for the replies and ideas. Probably should have been clearer in my initial post (sorry about that) because I just wanted to bring a potential bug to attention quickly, but yes, indeed, I want animation to happen only once, with scrubbing that has custom delay, and only in forward direction. 17 hours ago, GreenSock said: But in the meantime, you can simply remove the once: true and do this instead: onLeave: self => self.getTween().eventCallback("onComplete", () => self.kill(false)), Better? This does work but only if if you are going forward direction. If you position your scroll after the trigger, refresh, and scroll upwards, it will be animating backwards. This is not an issue with the original Codepen approach because upon page reload it "skips" the animation because scroll position is past trigger area. As a workaround I ended up with something ridiculous like this. onComplete callback on Tweens does not provide scroll progress/direction, which made things quite wrangled for inexperienced me. The rather forceful delayed self.kill with setTimeout is there for when onLeave gets triggered on page load. const CharacterTween = gsap.from("#character", { filter: "blur(20px) grayscale(30%)", opacity: 0, autoRound: false, lazy: false }); const CharacterScrollTrigger = ScrollTrigger.create({ animation: CharacterTween, trigger: "#character", start: "top 70%", end: "bottom 80%", scrub: 0.45, onLeave: self => { if (self.progress === 1 && self.direction === 1) { self.getTween().eventCallback("onComplete", event => { self.kill(false) }) try { setTimeout(() => { self.kill(false) }, 500) } catch (e) { console.error(e) } } }, }); CharacterTween.eventCallback("onComplete", function() { CharacterTween.kill(false) CharacterScrollTrigger.kill(false) }); Let me know if you know a better way than this one. Thanks! Link to comment Share on other sites More sharing options...
OSUblake Posted January 19, 2022 Share Posted January 19, 2022 If you don't want it play backwards, you can do something like this. Basically animate the progress yourself. let tl = gsa.timeline()... ScrollTrigger.create({ trigger: ".foo", onUpdate: ({ progress }) => { if (progress > tl.progress()) { gsap.to(tl, { ease: "power3", overwrite: true, progress }); } } }); Link to comment Share on other sites More sharing options...
GreenSock Posted January 19, 2022 Share Posted January 19, 2022 4 hours ago, ncla said: This is not an issue with the original Codepen approach because upon page reload it "skips" the animation because scroll position is past trigger area. If Blake's suggestion doesn't deliver what you want, can you please provide a minimal demo that shows the negative behavior you described (you said the current demo works fine). That'd really help us craft a solution for your particular use case/context. 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