Jump to content

Carl last won the day on September 11

Carl had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Carl

  1. Glad it helped and that it's working in your project. I very quickly did the css/html changes just to illustrate how it could work using what you already had. If I was to start from scratch I'd probably take more time making sure the css and layout made sense for what was needed for the animation effect, responsiveness, etc. Unfortunately, I just don't have the time to chase down additional css issues.
  2. Hi and welcome to the GreenSock forums, Thanks so much for the demo. It definitely helped me experiment with a solution. One way of doing this is to have 2 separate ScrollTriggers. One that pins the hero section and another that animates the bars. In order to do this I had to quickly reparent the bars in another div. I also messed around with some of the position values of the bars and durations slightly. https://codepen.io/snorkltv/pen/RwqNVEX?editors=0100 I'm sure it could use some tweaking, but hopefully you see that a big advantage of this setup is that you can adjust the end position of the pinned hero so that it can detach independent of the bars animating and you can play with the values a bit. Also, it will look better when the window is taller. In the vertically challenged embed above the effect gets a bit lost. For this type of effect there is nothing wrong with using different durations for the bar animations. Someday you may want to look into ScrollSmoother which has some very handy parallax capabilities built in. I'm calling this the Double ScrollTrigger Pin and Parallax. It may come to a CreativeCodingClub.com lesson someday soon
  3. No problem, I thought I'd be able to solve it as I was working on something very similar earlier today: https://codepen.io/snorkltv/pen/MWzWbbo?editors=0010 It looks like @Rodrigo came in with a working solution!
  4. Hi Tom glad you liked the video i can’t test now as I’m on my phone but try putting invalidateOnRefresh:true in the ScrollTrigger object and also try it with the tl.invalidate() removed too.
  5. First, most of the time if you want different animations for different screen sizes I would strongly suggest using scrollTrigger.matchMedia() as it allows you to create drastically different animations and layouts. In this case it seems you just need a bit of responsive flexibility. Again, function-based values and invalidating tweens on refresh can help greatly. here is a great explanation of function-based values in tweens: the demo below will the animation will reset itself when you resize so that the red boxes will all be pinned and moved across the screen as you scrub until the blue box comes into view. open in a new window and resize. https://codepen.io/snorkltv/pen/OJaLwgz?editors=0010 ScrollTrigger does a lot of highly optimized, amazing work under the hood so that things like this are seamless and painless. Hope this helps. Carl ps. If you really want to get into the finer points of GSAP and ScrollTrigger you may want to consider my GSAP Course Bundle. Also, if you do need tweens to be constantly changing their target value you may find the ModifiersPlugin of interest too
  6. Hello and welcome to the GreenSock forums. Thanks for the demo. For a single tween you can just use repeatRefresh on that tween. from the docs: Setting repeatRefresh: true causes a repeating tween to invalidate() and re-record its starting/ending values internally on each full iteration (not including yoyo's). This is useful when you use dynamic values (relative, random, or function-based). For example, x: "random(-100, 100)" would get a new random x value on each repeat. duration, delay, and stagger do NOT refresh. https://codepen.io/snorkltv/pen/BaGBYoo?editors=1111 you will note that the x value is function-based. on each repeat that getX function will run and return the most recent value of x. The tween will always repeat from 0 to the latest x value You can also set repeatRefresh:true on a timeline and all tweens will be refreshed when the timeline repeats.
  7. Thank you for the demo. I removed the drawSVG code and just added a little code to color each of the 5 paths a unique color https://codepen.io/snorkltv/pen/ExdBrYO It appears the paths have some odd gaps in them. The green path is part of the ear on the boy and then it's also most of the girl but her arm has multiple paths (blue and yellow). I'm not sure if this makes it somehow impossible for drawSVG to calculate stroke lengths and such, but my general advice is to start with much simpler paths. Draw them one at a time and test with DrawSVG often. DrawSVG handles multiple, continuous paths just fine. I don't think there was any problem with your actual code.
  8. Oh, and one very important thing to note about the Blobmixer site: they aren't scrolling the page. There is no scrollbar. They are using the mousewheel to control the progress of an animation.
  9. Hi @iDVB I don't have the time to try to figure it out, but I think it would be worth looking at the Inertia Plugin Investigate both demos with snapping enabled (not live snap) You'll see the elements you throw or flick will very naturally end at the proper snap location. A core feature of the Inertia plugin is to apply a velocity to something and over time it will naturally slow down. Inertia Plugin has features to track the currently velocity of things and allow you to create a new tween with that velocity passed in as the starting velocity. Also, if you fail to throw something hard enough it will naturally glide back to it's starting state. I think the key to what you want to do is to track the velocity of your scrolling and apply that to the progress() of an animation. The Observer plugin has functionality to track wheelspeed velocity. I'm guessing you could use that in conjunction with the Inertia Plugin https://greensock.com/docs/v3/Plugins/Observer/velocityY I think the tools are available here to accomplish your goals, but it will take some tinkering and perhaps a very different approach.
  10. Hi in the future it would really help if you could provide a minimal demo. #1) I am trying to get the height of the sections since the height varies. This is for the 'end' parameter in the ScrollTrigger. ScrollTrigger automatically measures the trigger and you have access to its "bottom" so you can just test when the bottom reaches a certain point. For instance if you want a section to end when its bottom reaches the top of the viewport you would just use end:"bottom top" (which is the default). If you want the measurement perhaps you just need element.offsetHeight. I log this out in the demo. #2 add and remove class names you can use classList.add() and classList.remove() you'll see in my demo I store a reference to className, previousClassName, and nextClassName so that each scrolltrigger can do stuff regarding the next and previous sections class names. Since you have sections with different heights it may be possible that multiple sections are visible fully at the same time. the way the demo is currently set up each section will set its className to the body when it enters the viewport in both directions. when it leaves the viewport in both directions it will remove its class as well https://codepen.io/snorkltv/pen/NWOBJde?editors=0011 notice when you got to the bottom of the page the body will be purple and just a little bit of the bottom of the pink section will be visible up top. if you scroll back up pink will come into view but the background won't become pink because the bottom of the pink section never crosses the top of the viewport. bottom of blue will come into view but since purple may still be a bit visible you won't see the background turn to blue until the purple class is removed (when purple top passes bottom of viewport). This may seem awkward but it's behaving as it is told and things like this only come up if you have many short sections. Hopefully this demo shows enough for you to tweak it to your needs.
  11. cool animation. I don't understand everything about the code, the problem, or the exact solution you need. But assuming the end goal is a seamless loop try updating your loop timeline like so const TRAIL_LOOP = gsap.fromTo( TRAIL, { time: 1.84 }, { time : 3.69, repeat: -1, ease: 'none', duration: 3, immediateRender:false } ) When it it first loads it will start somewhere around halfway through and then play through to a similar looking part of the loop. I got those mystery numbers by playing around with GSDevTools a bit on TRAIL. Since TRAIL doesn't repeat you can animate the time() instead of totalTime(), but it doesn't really make a difference. I got rid of what I thought might be the cause of some of the glitchiness by setting immediateRender:false on the fromTo tween. Again, not really sure of the exact particulars. Hopefully this helps somewhat.
  12. i was playing around with this last night and was kind of embarrassed with what I came up with. First, this highlight function adds or removes the active class function highlight(card, isActive) { if (isActive){ card.classList.add("isActive"); } else{ card.classList.remove("isActive"); } } Then I use this "wall of callbacks" to toggle the active class as the playhead passes through "the active zone". rawSequence.fromTo(item, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, zIndex: 100, duration: 0.5, yoyo: true, repeat: 1, ease: "power1.in", immediateRender: false, id: "currentItem" }, time) .fromTo(item, { xPercent: 400 }, { xPercent: -400, duration: 1, ease: "none", immediateRender: false }, time) //start wall of callbacks .call(highlight, [item, false], time+0.44) .call(highlight, [item, true], time+0.45) // this is the active zone .call(highlight, [item, true], time+0.55) .call(highlight, [item, false], time+0.56) each card animation is one second long so at exactly a time of 0.5 is when it is full scale and opacity. with the approach above I have one second of time from 0.45 to 0.55 where the active class is applied via the highlight callback. On either side of that range I have callbacks that remove the active class. https://codepen.io/snorkltv/pen/wvYzeYr?editors=0110 I initially tried to just set the active class at 0.5 exactly. It works fine, but with the easing it seems like you're kind of waiting for the animation to finish before it gets set. feel free to activate this chunk in the demo. .call(highlight, [item, false], time+0.49) .call(highlight, [item, true], time+0.50) .call(highlight, [item, false], time+0.51) again, I'm not super confident this is the most elegant solution but figured it might help you think of ways it could work. I imagine if you knew the direction the animation was being scrubbed you could determine whether or not the the active class should be applied or removed and avoid my brute force wall of callbacks. while I'm here I'd like to applaud at @geedix for supplying an answer that certainly works quite well.
  13. hmm, I don't think I understand fully because if you "still want to add fade in but without connecting it to scrub" my suggestion would just be to set scrub:false or don't set it at all. However, doing that I think it would kind of odd to have pinning set to true if the animation just runs on it's own. The user would then be scrolling without anything on screen moving or animating in any way. I'm a bit lost at what you want but perhaps a happy medium is having each line stagger in each of its words with a slight fade. Scroll slowly below: https://codepen.io/snorkltv/pen/NWOxYMe?editors=1010 The basic idea is that each line has it's own ScrollTrigger. Perhaps this will help.
  14. Thanks for the demo. If I understand correctly you can use a value very very close to 0 for the duration like duration: 0.0001 Your tween is being paused at a time:0 but you also have the first item in the stagger have a duration of 0 with unique start and end states. It's kind of a logical nightmare to handle, and GSAP most often handles it swimmingly. In your case a super low duration gives some amount of time between the start and end and yet will be virtually imperceivable. The solution from @mvaneijgen is very clever and works great too!
  15. Hi and welcome to the GreenSock forums, Thanks for the demo. It looks like you got the animation working nicely. Can you please clarify what you mean by "iterate a racetrack"? Do you want the animations for each track to play one after the other? Do you want multiple arrows on each track? Just try to be as descriptive as possible regarding the end result you are looking for. Thanks.
  16. Thanks for the great demo! I believe at one point the decision was made that if the playhead was sitting at a time where there was a callback that already fired and playback resumed then the callback wouldn't run again. It's one of those situations where you could argue both behaviors (fire again or don't) but there needed to be a consistent way for it to be handled. When the playhead lands on a callback and plays or reverses you can optionally set suppressEvents:false so that callbacks will fire (default is true). See the reverse() docs Since the playhead is already at the end of the animation in your example suppressEvents doesn't really apply (the playhead isn't landing there). The cleanest solution would be to force the playhead to instantly move to the end of the timeline from somewhere else and reverse with suppressEvents:false like so tl.time(0).reverse(tl.duration(), false); https://codepen.io/snorkltv/pen/abRdEMK?editors=0011
  17. Hi and welcome to the GreenSock forums. immediately after the last tween in your timeline add tl.reversed(true) or tl.reverse() this way the timeline will be in a reversed state before the first click which means it will play on the first click.
  18. I happen to have a lesson that uses a similar setup in my GreenSock course bundle. I keep things as minimal as possible with design so that my students can focus on the code and add their own flair. The main point of this setup is just to get one thing to expand/open when you click on it and close other open things. Flex-box handles "pushing things around" automatically which is a nice bonus. The code is fairly well commented. Perhaps this will help you with some of your project. https://codepen.io/snorkltv/pen/YzGpXWO * note: when an item is open you can close it using the "x" button OR you can click on another closed item.
  19. This is very nice effect. I could see myself using this in a tutorial sometime soon. in addition to what @Cassie suggested I would add that it would help to have a better understanding of what you know about GSAP and ScrollTrigger, as it could be a challenge if you are just starting with GSAP. Are you looking for us to give you the full solution or just help you with where you are stuck? The animation of the orange line could be done a few ways, perhaps an SVG stroke or a colored div moving inside another element with overflow hidden. If you inspect the page your referenced you will see that each of those sections has its own orange line that moves. I don't have a ton of time now to build this whole thing but I can give you this starting point: https://codepen.io/snorkltv/pen/XWxJqGQ?editors=1010 After you've read the ScrollTrigger Docs (watch the full video) ScrollTrigger Getting Started in 3 Easy Steps I'd encourage you try to wire the animation I provided to a ScrollTrigger. Fork the demo and post it here if you get stuck. hint: use scrub:true the repeat is only on the animation so you can see how it works.
  20. I'm sorry, what does "something goes wrong" mean? Sometimes we aren't seeing the same thing as you or know the expected results. please try to be more descriptive. thanks
  21. That extra space is probably due to the 3000px you have in your end value. Questions about this type of layout come up a bit around here. I'm in the process of making a lesson. The video in this tweet gives some background on the basic setup I added a little animation on the right in this updated (yet not finished) demo https://codepen.io/snorkltv/pen/MWPgoXV
  22. Nice job getting it set up. it looks like you were loading multiple versions of ScrollTrigger. As @mvaneijgen mentioned it looked like there were some issues with the external asset hosting earlier. This works at the time of posting https://codepen.io/snorkltv/pen/WNaewvB
  23. Thanks for looking and for the explanation. yup. the circle is inside the scrollbar element. the scrollbar element is being centered, but I expected that the circle would always have a native / starting y of 0 relative to its position inside its parent. I guess I haven't seen the size of the window impact transforms of child elements like this before.
  24. Thanks for the demo. I had some similar code laying around that made for an easy upgrade https://codepen.io/snorkltv/pen/PodyzXb once you undestand all the draggable values @mvaneijgen referred to you can do quite a bit with them. The normalize() utility function makes it easy to get the percent from the minY, maxY, and current y values https://greensock.com/docs/v3/GSAP/UtilityMethods/normalize() ISSUE I hit a weird snag with your original demo in that it seems draggable is reporting unexpected minY and maxY values. It appears the position and margin css setting you were using were causing them to be set to minY:1 and maxY:251. @GreenSock please look https://codepen.io/snorkltv/pen/wvEYzgy?editors=0111 EDIT: it seems to get the weird values you have to view the pen in its own larger window. very strange EDIT 2: works fine in firefox. issue seen in Chrome and Safari