Jump to content
GreenSock

akapowl last won the day on January 25

akapowl had the most liked content!

akapowl

Moderators
  • Posts

    1,939
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by akapowl

  1. Welcome to the GreenSock forum, @oveRuns7777. Maybe that's just a typo on your end? You are missing a closing bracket. ScrollTrigger.matchMedia({ "(min-width:1184px": () => { // <--- you have this ... ScrollTrigger.matchMedia({ "(min-width:1184px)": () => { // <--- should be this ... Also, ScrollTrigger.matchMedia() is deprecated if I recall correctly. You'll probably want to have a look at the newer gsap.matchMedia() https://greensock.com/docs/v3/GSAP/gsap.matchMedia()
  2. Welcome to the forum @agsymonds If I understand you correctly, the advanced stagger object has you covered. Does that work like you imagined? https://greensock.com/docs/v3/Staggers [I justed increased the stagger value a bit in this demo to make the randomness more apparent.] // simple ... stagger: 0.1, ... // advanced ... stagger: { each: 0.1, from: 'random' } ... https://codepen.io/akapowl/pen/NWBOxjR
  3. Posting your question once is enough, @Juan Munoz But I'm not sure what exactly you mean by 'responsive', as the example I posted above, should be fully working after resizes and there is nothing in it that would need recalculation of any sort. It would be best to add a minimal demo alongside your question, to make it easier to understand. Thanks.
  4. Once you have a proper layout set up, the GSAP side of things could look something like this; gsap.to(".theContentYouWantToTweenOn", { y: () => { return -(document.querySelector('.theContentYouWantToTweenOn').scrollHeight - window.innerHeight) }, ease: "none", scrollTrigger: { trigger: ".someWrappingElement", start: () => "left left", end: () => "+=" + document.querySelector('.theContentYouWantToTweenOn').scrollHeight - window.innerHeight, pin: true, pinSpacing: true, scrub: true, horizontal: true, invalidateOnRefresh: true } }); It's pretty much similar to what you can see with fake-horizontal-scrolling tweens in vertical scrolling scenarios, like the one shown below, except for all the x-related values being exchanged with y-related values and vice versa; additionaly you'll want to set horizontal to true on your ScrollTrigger, when you are moving in a native horizontal scrolling environment. Once you have tried something yourself, we'll be happily helping with the GSAP side of things you tried out and got stuck on - but again, please keep in mind, that these forums are not intended for requests á la 'please give me an example for how to do this effect'. https://codepen.io/akapowl/pen/dyvygmj
  5. Hello weinde, you are calling a function without passing any of the parameters neccessary for that function's logic to be processed, that's why you get that error. But also, nowhere does your code include anything related to GSAP, except for you registering the ScrollTrigger plugin. These forums try to stay focussed on GSAP specififc questions. If you have any of those, we'll be happy to help, but we can not provide general JavaScript or in your case also jQuery consulting.
  6. https://imgur.com/a/0IBWb7T Works just fine for me. Maybe you need to resize your viewing-window and reload, to make sure locomotive-scroll actually uses the transform-smooth-scrolling ? ...because as already mentioned, it will revert back to native browser scrolling when loaded below a certain window width. Which is also why you should not remove this line pinType: document.querySelector(".App").style.transform ? "transform" : "fixed" because that line makes sure that when locomotive-scroll reverts back to native browser scrolling, ST will use position fixed for the pinning. As your scroller is not the body, otherwise it will be using 'transform' by default, which will make your pins appear rather jittery when locomotive-scroll reverts back to native browser scrolling. Edit: My demo actually still does have some issues - with regard to things not working quite right on resize - but for the time being I don't have time to tinker with this some more.
  7. Well, as with everything, the devil is in the detail, which is why it is very hard to give general recommendations for a more complex scenario like yours. Since you are concerned about things not working when reloading the page when it's scrolled down, you might want to reconsider the general approach of how you implement the change of the backgroundColor, too, because the way you are doing it in the demos you posted, things will not work as you might intend in that case. One logical problem is the following: You are changing the playstate of pre-built timelines with.to() tweens in callbacks of ScrollTriggers, when the page is loaded at the very bottom, ScrollTrigger will make sure that those callbacks get called. So now you have multiple tweens being called quickly one after the other, which are all tweening on the same property of the same element, so you are creating conflicting tweens. When you scroll back up then, the .to() tween is supposed to be reversed, but it will probably reverse back to the color that it was at the time when that tween was being created - which very likely is not the color you'd expect but some value of a color in between all those colors. Creating your tweens upfront can be quite the tricky scenario to begin with, when you are going to tween on the same property of the same element with multiple different instances. So one way you could prevent all those logical hurdles, would be to create the tweens in the callbacks directly instead of pre-building them. Then you could either use .fromTo() tweens to make sure you always tween from one specific color to another specific color, when the callback runs, or .to() tweens with overwrite set to 'auto' to prevent conflicts I mentioned above. In this pen with the lottie-scrolltriggers handling the pinning themselves, things seem to work fine even if I create those ScrollTriggers before all the lottie-scrolltriggers, but your mileage may vary. https://codepen.io/akapowl/pen/gOjKLqy
  8. It's actually really hard to replicate in the first place because when refreshing the page, it doesn't always stay at the position it was before. Your latest demo for instance works fine for me every time - but I can see it starts up top when reloaded and then jumps to the position it was before later on. How about these two pens? (both are on the latest version - best fork them and view in codepen's debug mode) This one sort of represents your scenario - for each section there's one instance created for pinning the wrapping container and then later the LottieScrollTrigger instance for the animation triggering on the child of the container - I can recreate the issue you described there - all positions of the animation-triggering shift for me when reloaded at the bottom of the page e.g. https://codepen.io/akapowl/pen/jOpKqXW If on the other hand I only use the LottieScrollTrigger for both, pinning and triggering of the animation, I can not replicate the issue any more. Does that work for you, too, or can you still replicate that behaviour with this pen? https://codepen.io/akapowl/pen/abjKZwa
  9. Out of curiosity I was tinkering a bit and I noticed some differences in behaviour in between versions of GSAP/ScrollTrigger but I'm actually not sure if things that occured for me are those that you are mentioning. Could you check if this version of your codepen does behave any different for you? It is reverted back to GSAP and ScrollTrigger 3.11.1 https://codepen.io/akapowl/pen/VwBdKvv
  10. Hi there. Your ScrollTrigger is set to end 10,000 pixels after it starts - but since you are not pinning anything, you will never actually have that much height to scroll through on your page. So you might want to change something with that regard. In this fork of your pen you can see that ScrollTrigger actually works just like you tell it to, if there is enough scrollable space; I just set a min-height to the body to demonstrate that. https://codepen.io/akapowl/pen/dyjKGVX Consider having another look at the ScrollTrigger docs - with regard to end it might also be helpful to have a look at endTrigger. https://greensock.com/docs/v3/Plugins/ScrollTrigger Also it sounds to me, that you actually want two tweens of a timeline to trigger at the same time, so you might want to have a look at how to use the position parameter of tweens on a timeline.
  11. Usually it is best to create your ScrollTriggers in order of the appearance of the elements on the page. ScrollTrigger needs to process the page from top to bottom, so ScrollTriggers further down the page have information about what is going on above, as layout might have been shifted before, which they need information about in order to calculate correctly, where to trigger. Imagine you have a forEach loop creating a bunch of ScrollTriggers for multiple sections on your page. Then, in your code after that forEach loop, you create a ScrollTrigger that is pinning something in between those sections - that pinning will cause the positioning of the elements that come later on, to shift. But since you have already created the ScrollTriggers for some of those elements further down the page before you created the pinning ScrollTrigger, and now in hindsight due to the pinning their position on the page gets shifted down, the calculations made by ScrollTrigger for those elements will not be correct anymore. See the problem? Of course often times it is more convenient to use loops and quickly itterate over multiple elements, but that often is where problems can occur, and that's what .sort() / refreshPriority are there for to help out with. Now again, I'm not saying that this is the cause of your issue - just wanted to give you a heads up on that, because it should be something to be aware of, when constructing your JS like you are.
  12. Hello @Palke - welcome to the GreenSock forum. I myself can not replicate the behaviour you mentioned with the instructions you gave - on Windows 11 neither in the latest Firefox, Chrome or Opera - so this might be something browser or OS specific. I think, adding some information about the browser and OS you are using might help the Admins find out what's causing that.
  13. Sorry, but no, I can't do that - that is a bit too much of a favour to ask. I'd keep it with what Cassie suggested; start with a blank canvas, add things to it piece by piece, test test test, and when things break, you will have a better angle on what might have caused it. Creating ScrollTriggers out of order of their appearance on the page (like especially inside forEach loops creating pinning ScrollTriggers) can become very tricky quite quick. I suspect, in a complex scenario like that, you might have have to consider the use of refreshPriority and/or .sort() in one way or another; but that is just a suspicion from a quick glance, nothing I can guarantee. https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.sort()
  14. Hey all. I think, using the string syntax for start / end with only one parameter, like you do throughout your codepen demo, @Gigi1303, is actually not valid ( as in e.g. start: "top" for instance ) and is bound to lead to problematic behaviour. You can use a singular value as a number (not in string form) and it will translate to the absolute scrollposition on the page or as a relative value in case of the end, like "+=100%". But other than that, when you use the string syntax, you are supposed to give two parameters, as in "top top" with the first referring to the element and the second referring to the viewport (as explained in the ScrollTrigger docs). Maybe try and change that in combination with the other suggestions you've already gotten, and see if it helps. For confirmation, here is @GreenSock mentioning this in one other thread (among many):
  15. You can find it in that other thread I mentioned earlier.
  16. Alright, I see. Then you'll probably need some sort of calculation anyway. Just for inspiration, here is an alternative. I make use of the endTrigger here, so I can use one trigger-element for the start and another trigger-element for the end. Also I get the values directly in the start function, so there's no need to re-populate any variable on resize. The calculation there is based on the padding of the section plus the offsetHeight of the subtitle + the 32px you mentioned you wanted in between the pinned elements. As a sidenote: I had to add a fixed height to the h2, as your h2s are empty and things got a bit wonky when pinning the intro element. Maybe this will help somehow. https://codepen.io/akapowl/pen/gOjzmmX endTrigger String | Element - The element (or selector text for the element) whose position in the normal document flow is used for calculating where the ScrollTrigger ends. You don't need to define an endTrigger unless it's DIFFERENT than the trigger element because that's the default.
  17. Update: I also tried to make an example that is a bit more condensed, to make it at least a little bit easier to see through what's going on there. @Rodrigo would you mind having a look at this if you find the time, to see if this is somewhat acceptable from the React side of things? https://codesandbox.io/s/gsap-scrolltrigger-with-locomotive-scroll-in-react-ux8nlv Worth mentioning on the side: Since elements and even whole sections kept disappearing on me when scrolling, I added a suggested sort of workaround to that known locomotive-scroll issue to the end of the styles.css
  18. So, @Pollux Septimus, I've had some more tinkering with this, and I think I've come to a working outcome ( but since I am not too familiar with React in particular, I give no guarantee that this is the holy grail when it comes to this). Point 3) of what I mentioned still stands - do not use locomotive-scroll's data-scroll-section attribute for the reasons mentioned. Point 1) looks like it boils down to the double-rendering in React's Strict mode from v18 upwards - so just like you do with GSAP's .context(), you will need to do some sort of clean-up to prevent multiple instances of loco-scroll to be created. So now I added return () => { locoScroll.destroy() ScrollTrigger.removeEventListener('refresh', lsUpdate); } to the end of the useEffect of your custom useLocoScroll hook. Point 2) can apparently not really be avoided, but React offers you some way to workaround the problem that this boild down to. The way I understand things, you probably shouldn't be using a useEffect but rather a useLayoutEffect for your custom hook: taken from here: https://kentcdodds.com/blog/useeffect-vs-uselayouteffect Those things changed, I landed on this, which appears to be working just like intended. Does that work better for you? https://codesandbox.io/s/st-loco-react-dtw1q4
  19. I was just tinkering with the custom hook solution by the other user, and think I found all the causes of problems now - am just about to reply there with the sandbox I've landed on. Give me a second.
  20. Hello all, I hate to be the party-pooper and if I am wrong with this, or out of line, I beg your pardon, but I just wanted to mention that using the approach in the thread, that @Rodrigo mentioned might not be the best idea, since it appears to be rather problematic for a couple of reasons mentioned in this other thread by the same user from a couple of days later. Now again, I really don't want to call out anybody, but I also wouldn't suggest their approach as a solution (at least for the time being), so I thought this was worth mentioning. Might be worth also making a note of that in the thread where the use of that hook is suggested?
  21. Hello. That is the case, because you populate your variables with the relevant values once on load, and then always work with the same variables without ever updating their values. If you want things to be recalculated on resize, you will need to get the relevant values again on resize (best on the revert event of ScrollTrigger) and repopulate your variables. Here's an example for that - although I'm not sure this is what you really want as those values for the start can become (or in some cases depending on window/image size already are) contradicting to the end of 'bottom bottom' you have there, which will be reached before the start in a vast majority of cases, the way I see it. So maybe explain what it is you are trying to achieve, and we can see if there is a better way to do it !? https://codepen.io/akapowl/pen/VwBXWOm
  22. Sorry, but I don't have the time to wade through all that logic, especially since I can't even imagine what outcome you expect and your initial setup in combination with the elements then suddenly jumping off-screen before tweening in, doesn't make that much sense to me. Also it is quite a bit out of scope from what to expect from this forum, please see the Forum Guidelines. From what it looks like to me, you are creating your timelines upfront and then only adding more and more tweens to them when calling your functions - not sure how much that does affect things, but that doesn't look quite right to me. I'm also not sure you need functions to begin with; couldn't you just create your timelines upfront and iterate through those pre-made timelines in your logic. For your convenience, here is a rather simple example with the logic transfered to click-events rather than scrolling. https://codepen.io/akapowl/pen/OJwvXYz
  23. As you can see from the logs I added in the onUp and onDown callbacks, Observer's onUp works just fine - what fails is your custom logic. You are getting an error in console that points you to what is wrong funcs[index] is not a function If you log out the different indexes you are working with, you will notice that you are pointing towards an item of an array with a negative value for the index in multiple occasions, and arrays inherently do not have / work with negative indexes. So you will need to rework your logic with that regard, to make it work. BTW, you have a typo in your Observer: targer --> target https://codepen.io/akapowl/pen/poZLjpZ Edit: One suggestion I have is taking a look at GSAP's utility methods. Here is an example of how you could e.g. use .wrap() to wrap around your variable value to the last one in your array, if it becomes negative. Click anywhere on the body in this example to decrease the variable I'm working with by 1. https://codepen.io/akapowl/pen/QWBmjJB ... the wrapping also works in the positive direction, btw. https://codepen.io/akapowl/pen/QWBmyLJ
  24. Welcome to the GreenSock forum. First off, I would suggest having a look at ScrollTrigger's normalizeScroll function, which should help with what you are trying to achieve. But as an answer with regard to your scenario: Since your body is not going to be the scroller element anymore in a case as such, you will probably have to define the current element that is now your scroller. This is from the docs: scroller String | Element - By default, the scroller is the viewport itself, but if you'd like to add a ScrollTrigger to a scrollable <div>, for example, just define that as the scroller. You can use selector text like "#elementID" or the element itself. If neither of the suggestions does help in your case, please provide a minimal demo that showcases your issue. I'd also suggest reading up on those threads if you want to stick to your solution as it comes with some side-effects that you might want to consider.
  25. Hello there. So, if you don't want the confetti to play for a certain duration of time, don't make it request a new animationFrame depending on wether a certain amount of time has passed - but instead make it dependent on wether a certain scenario is the case / condition is met. You could e.g. set up a boolean variable (playConfetti in this case below) and toggle that variable to true/false depending on wether you enter or leave the section. When you enter the section, also call the function that plays the confetti - inside that function call the requestAnimationFrame only when the playConfetti variable is true (checked with the if condition that earlier had the check on the time passed, in your demo). Something like this maybe: https://codepen.io/akapowl/pen/NWByZqg
×