Jump to content

Search In
  • More options...
Find results that contain...
Find results in...


  • Posts

  • Joined

  • Last visited

Everything posted by jh3y

  1. That's awesome @GreenSock πŸ™ I think we're at a point where we can say this one has been answered πŸ™Œ Here's where I got to. Again, you're a hero! https://codepen.io/jh3y/pen/WNRvqJP
  2. jh3y


    I have minted and sold an NFT πŸ‘€ But, I did so through Rarible which only comprised of submitting the GIF/Video. Purely for experiment. But, who knows in the future. Not sure how different file types will pan out. Many people do things like have the NFT as GIF/Video but then offer unlockables on the side. For example, I think Beeple distributes pieces of the work in perspex frames with what is sold.
  3. Hey @GreenSock πŸ‘‹ Appreciate this a lot! πŸ™ I'll make some time to go through it and swing my article in this direction πŸ‘ I had built it up around the idea of taking three timelines and tacking them onto a main timeline. But, that can get confusing and looping over the elements three times is more intuitive once that timeline concept is in place. That's how I'll swing the direction shift I think 😁 Again. I appreciate this a lot. Looking forward to getting this one written up and sent off. Thank you for all your help. I still have a feeling I'll be posting in this thread again though πŸ˜… I did have one idea which I have only pseudo-coded in my head. Would it be possible to use a Draggable proxy and drag the time? I imagine so, right? That would be cool. I imagine it will be a case of putting a threshold on how much distance correlates with the time scrub πŸ€”
  4. Hey @GreenSock πŸ‘‹ That's fine! Thank you for the heads up. It's more relief that you can see a solution πŸ˜… I'll happily wait on that haha. I'm interested to see how I've broken the navigation buttons too. I think it's linked to this. But the way I've tried making them has perhaps made it more prominent. I have some other GSAP content to make in the mean time πŸ‘
  5. Hmm. I've tried a couple of things here @GreenSock πŸ€” But to no avail. Perhaps there's a trick to stopping the snap from going into a loop or I'm missing a piece of logic. I noticed also in this demo you posted previously, I can get it to sit in an infinite loop where it rocks the scroll position. https://codepen.io/GreenSock/pen/qBqEZKg I have this issue in my demo too. The other issue I have though is that my buttons don't work for wrapping which is strange because the logic is the same from what I can see. Unless I'm missing a line somewhere. https://codepen.io/jh3y/pen/gOLQLYW
  6. I mean, I state that I usually use a `ref` pattern. But, I always use a ref pattern. I threw a concept demo for it together maybe yesterday though to see how it might look. I think for those comfortable, it's not necessary. It's using the DOM afterall. The rule, keep a handle on your state updates. That said, although some are comfortable, it doesn't mean that everyone is comfortable. And for convenience things, a lot of people reach for tools like Framer arguably because of that. They have a component that they drop in, throw some props on, and they're done. It's easy to take a skillset for granted and assume others have that same skill. But, if conveniences were offered to users, it would perhaps act as a gateway for those who want to explore more advanced GSAP usage who then look further at using refs more extensively. An example library that does this, React and ThreeJS. We could write all our ThreeJS code ourselves in an effect. However, React Three Fiber exists with convenience hooks and components to create meshes, etc. I guess what I'm getting at is that I wouldn't dismiss providing things like that for users if it were a stepping stone to using GSAP more extensively. Of course, only my thoughts and observations. As mentioned above. `innerRef` or `ref` depending on your Styled Components version should get the job done. I'd be happy to look at a demo if you have one though πŸ‘ It should work the same as a normal element. const Spinner = styled.div` height: 25vmin; width: 25vmin; border-radius: 50%; border: 2vmin solid hsl(90, 80%, 60%); border-left-color: transparent; border-right-color: transparent; ` const App = () => { const spinnerRef = useRef(null) useEffect(() => { gsap.to(spinnerRef.current, { rotation: 360, repeat: -1, ease: 'none' }) }, []) return ( <Spinner ref={spinnerRef}/> ) } https://codepen.io/jh3y/pen/oNYQVrP
  7. The only issue with using regular CSS selectors is that you can get caught out if your components share classnames/attributes. With regards to refs, according to the docs, the callback ref gives you finer control over when to set the ref for an element. However, I've yet to find an instance where I've needed this for GSAP. I usually use a ref pattern. I have been playing with proof of concept pieces for how to create convenience components for React && GSAP πŸ‘ The issue faced is how/what would be the nicest way to expose GSAP in React whilst still providing all the benefits. I think timelines could likely still live in effects. But, there are some different directions it could go in. Custom hooks, <GSAP.div yoyo duration={2}/>, <To scale={2}><div/></To>.
  8. Oh wow. These libraries look great! Thanks for sharing @Shrug Β―\_(ツ)_/Β― πŸ™ I imagine something like that could work. It was when I was making this pen. https://codepen.io/jh3y/pen/gOLjyrm The original path for the 'stache would've been cool to rig to a path that I could've morphed and had the 'stache path follow if that makes sense? Instead I opted to dig in a little more with working on path manually. But I thought I'd ask if anyone had seen/done this kind of rigging πŸ‘ Hadn't seen or heard of this one before. Looks like a great tool to check out πŸ‘
  9. Looks like I've got hung up on the original issue @GreenSock hahaha πŸ˜… Next/Prev buttons with this method. I have snapping in place. But, I can't get past an iteration with this method for some reason. I'm sure I'm missing something straightforward. I'm determined to get a draft of this article complete this week! https://codepen.io/jh3y/pen/WNoYoMY This works fine until I try to wrap πŸ€” Then it gets caught understandably I guess in an infinite loop. Is there a way to get out of the loop? My snap is set up based on the amount of elements which seems to work until I try scrubbing with the buttons. NEXT.addEventListener('click', () => { const DESTINATION = SNAP(SCRUB.vars.totalTime + (1 / BOXES.length)) scrubTo(DESTINATION) }) PREV.addEventListener('click', () => { const DESTINATION = SNAP(SCRUB.vars.totalTime - (1 / BOXES.length)) scrubTo(DESTINATION) }) I guess that's one issue I've not sussed out yet. It has the ability to get stuck in a loop of wrapping when progress is 1. Would it make sense to change the conditionals slightly?
  10. This one's fantastic! πŸ‘ https://codepen.io/osublake/pen/vKdGAy I was thinking the other day about how to approach a certain demo and wondered, would it be possible to do rigging with GSAP? As in mapping one path to another. This demo kinda reminded me of it. I can imagine something like that would be very hard to calculate but wondered if there were any good examples in the wild. For example, if this demo was one polygon rigged to the underlying path.
  11. Yep! Exactly that πŸ’― Thrilled we're on the same page. This is quite the thread πŸ˜… I can totally mention that optimization though. I think that's the part I originally struggled to visualise. Where that chop gets calculated. Now, I've been practicing the technique in the wild some more, it's kinda sunk in. I figured that might be what I needed to do. It's a real cool technique and definitely feels like unlocking a superpower when you start doing these "meta" things.
  12. Hey @GreenSock πŸ‘‹ Ahh, that's perfect. Thanks! Makes a bunch of sense. That's my bad on leaving it as `repeat: -1` on the shifts. Completely right that it wouldn't make sense there πŸ‘ That was the 17th part and I'd likely got a little flustered putting it together. That z-index part and positioning makes complete sense too. Looking at it again, not sure what I'm thinking there πŸ‘πŸ˜… I likely needed to step back for a moment! Do you think it makes sense to approach the scroll in this way? As in stacking the three timelines? I've found this maybe a little easier to incrementally build up to for people. I will revisit the original approach again though and see if I can break that down and relate it too πŸ‘ This is all really useful. Thank you again Jack for all the help with this! πŸ™ Κ• β€’α΄₯β€’Κ”
  13. No problem at all! I'm going to take another look at the original method too and see if I can break it down again. I'll also get the snapping back that way too. I was intrigued to know if this way was also possible though πŸ€” As always, big thanks in advance with this.
  14. Hey @GreenSock Bringing the thread back to life! πŸ˜… I'm trying to write up the article for this at the moment. Not going to lie, this is one of the trickiest articles I've tried to write. Happy to send you a draft link for it. Would be good to get your eyes on it. Anyway. I've got to a point where I'm explaining hooking up ScrollTrigger without the looping. I'm trying to make the technique as "verbose" as possible. The technique I'm using is adding a tween three times to a timeline and replaying a window of that timeline. But, when I hook this up to scroll I get a flicker if I try scrolling back up quick from the end. https://codepen.io/jh3y/pen/jOVzExq I'm not 100% sure what's causing that. Any ideas? Or is this a drawback of trying to go about doing it this way? I'm thinking this might cause more issues when it comes to wrapping , etc. I notice that this way, I've also made a mess of the snapping πŸ€” Perhaps I need to go back to the drawing board and find a better way of explaining the original approach. I felt like doing the three timelines was a good way to explain it and then introduce the padding/overlap concept once the idea has sunk in. I'm trying to find a "nice" way of explaining building the loop and why it's done the way it is instead of cutting out a section of a repeated timeline. If you get a chance to check this out, thanks in advance!
  15. Hey @GreenSock! Yeah, that clears some things up. I think the best way for me to try and fully have a handle on this is to start writing up the article for it. I think it might be neat for me to create a non-looping version too using the same technique. That will likely make it easier to see the progression from having the scroll to adding the overlap. One thing with your new snapping version. If you scroll it to "0", it'll infinitely bounce slightly. Or, at least did for me above.
  16. Hey @GreenSock! I think we're starting 2021 off great with an attempt for longest thread πŸ˜… I think I get the overlap. Perhaps my wording wasn't quite right again. I had a play around with overlaps and manually adjusting the spacing, etc. I think typing out the calculations and their values may help me understand it a bunch more. I've been messing with unpausing the timeline and slowing down Raw here https://codepen.io/jh3y/pen/WNoNoLZ And now I'm going to walkthrough as I understand it. For example, with 50 cards, an overlap of 10 and a spacing of 0.1. https://codepen.io/jh3y/pen/zYoYoaM Loop time: (50 + 10) * 0.1 + 1 = 7 Start time: 50 * 0.1 + 0.5 = 5.5 Then the LOOP tweens RAW to a time and duration of time: 7 duration: 1.5 That first part is responsible for moving the items from right to left. To a time of 7 equates to the 70 cards in this case which may be coincidence. As a loop time for 30 cards would be. (30 + 10) * 0.1 + 1 = 5 Maybe not then. That number is equal to (Cards + (2 * overlap))? But, the start time would be at the 55th position in the tween. Minus the overlaps that would mean showing the 45th card and up? Why a duration of 1.5 though? https://codepen.io/jh3y/pen/zYoYoaM I could adjust that to offset the positioning, etc.? That first part of the loop goes from the first overlap to card 20. That first part of the loop using a duration of 1.5 with a time of 7 means we go from position 45 to 20. But, I'd have assumed it would be travelling only 15 places not 25. https://codepen.io/jh3y/pen/BaQapXq Then we set `fromTo` to Raw Go from `time` time: 10 * 0.1 + 1 = 2 to time: 5.5 duration: 5.5 - 2 The time is moving to the start position from 20 positions in? Is there a reason for being 20 positions in? In this case, that's 2 lots of overlap but I'm not sure why that works. The extra + 1 on times. In this case it shows 0,1,2,3,4 then jumps to 20 which makes sense. The .5 gives us those 5 starting positions. The tween goes from card 20 to card 5. That little bit of wrap. https://codepen.io/jh3y/pen/bGBGgaK I think I get the concept of the overlap. I think it's the Math part that lets me down a little here with wrapping my head around the different calculated times/duration πŸ˜… Also, the way loop works. The way it's split into this `to` and `fromTo`. The durations having + 1 on them or being split in a particular way. The `to` and `fromTo` are tweening a different end of the raw timeline. Then when pushed together they do this: https://codepen.io/jh3y/pen/poNoejo If I'm right in thinking it's because logically looking at it. The to is handling our start position + the second overlap and the the fromTo handles the first part of the loop and the first overlap. But, the missing "Eurekah" I think for me is the Math of the time linking to the duration. Although, the raw time is explicitly set above actually so that means we are going. I read the LOOP as: 5.5 > 7 > 2 > 5.5 > 5.5 > 7 > 2 > 5.5 > 5.5 > 7 etc. Which I think... makes sense? That leaves me to think about the durations. We know that Raw's stagger gives 8. 70 * 0.1 + 1. Is that that +1 in our durations for padding out the duration of the movement? LOOP has durations of (7 - 5.5) and (5.5 - 2) 1.5 and 3.5. I think I'm trying to sus what these are tied to to and then I'm pretty much there 🀞 The scrub part I think makes sense to me. I needed to reference the docs for `totalTime` to see that it's a method for scrubbing the playhead to a certain spot πŸ€¦β€β™‚οΈ Another huge response I'm sorry. I'm adament I'm going to learn this. You're right. It's advanced, but, it's cool! And it will be an awesome thing to have in my toolbelt. I think I'm getting there with the understanding. It's thinking on the meta level πŸ˜…
  17. Hey @GreenSock πŸ‘‹ I've sat down to try and get my head around things 😁 It might take me a couple of rounds to fully get the picture accurately in my head. My goal though, is to make this easier to understand for people. If I can make it make sense to people who've barely used GSAP, that's a huge win! With that in mind. I'm going to fire out some random notes I took from reading your response. Yep. We're "Meta GSAP" πŸ˜… 3x The way the gap is covered is based on the overlap defined and the amount of items available. In our example, 10 because `Math.ceil(1/0.1)`. With a number of items as low as 5, the spacing would need to be increased or the overlap reduced? Because you need enough elements to wrap the front and back at the right time. And that's how the RAW timeline works because the modulo grabs the overlaps and tacks them onto the loop? The loop's job is to move the playhead on raw. And because raw infinitely repeats and our scrolling increases the `totalTime`, it'll keep moving the playhead? Raw.time sets that center point for us I think I need to spend more time looking at what loopTime, start, etc. are doing with regards to the fromTo on raw. But, a high level explanation is that. It's still that code snippet I posted before that I need to get my head around for the timing. ScrollTrigger part. '+=3000' could be whatever we want in reason? I think the wrapping part I understand. I like how that and the next/prev part are done. It's neat. The actual movement with ScrollTrigger. Is that because increasing/reducing `totalTime` affects the playhead position of the loop? Or is it because the scrub keeps tweening the time up and down of the loop incrementally/decrementally? Yeah, the way it's all done on one makes a lot of sense. I can feel the performance difference between the two. It's noticeable. The obsession is appreciated. I'd rather do it right than get it out the door quick and hit hurdles later. Yep, I got that `yoyo` part. Don't think I worded myself very well. Working on it! Oof. A lot to digest πŸ˜… Sorry if I sound like a broken record with some of them pointers. I'm keen to make something visual to help people out with this. Heck, I understand it better than I did at first glance. Progress is being made! Thanks again for all this. I really appreciate your help.
  18. A lot of fun 😁Experimented with the opacity and dropped another `fromTo` to offset it slightly https://codepen.io/jh3y/pen/VwmZppG
  19. @GreenSock I love it! 😍 https://codepen.io/jh3y/pen/xxRKggV I've gone through the code and retyped it to walk through. I think I understand most parts. Very clever! πŸ‘ I'm looking to write this up/make a video on it at some point. It would be cool to show the evolution of implementing it. Of course, I'll be crediting this forum heavily πŸ˜… I love the solution you've presented because it's GSAP'ping GSAP if I'm understanding it right which I think is brilliant. I've made some notes and things I've tried to understand. I'm more than happy with an ELI5 on some of these if you're able to. I'd love to properly understand it. I love this kind of thing as it gives me something new to dig into/challenge myself with understanding. - raw timeline powers card appearance. This is neat. Although my "Map" approach worked, this is more GSAPPY and accurate. If we wanted to offset the scale, etc. We'd introduce another `fromTo` with a `yoyo` and maybe a reduced duration with a delay/position? - Wrapping. This part seems straighforward. If we go forward, increment, if we go backward, decrement. Keep going backwards and we keep counting down from 10. The iteration is used for accuracy with the scrub? - The main mechanism. I think this is something I need to type out to clarify my thinking which could be off πŸ˜… We use scrollTrigger to update the totalTime of the scrub. And that puts the loop playhead into different positions which in turn updates the position of the raw timeline? There's a bit to swallow there πŸ˜… - The overlap part. I'm not 100% sure about how this works. This part I probably need a little ELI5 on as well. It's mainly this part. The overlap adds extra time playing the raw timeline which makes it loop round better. And that's because inside there would be a wrap in either direction? LOOP .to(RAW, { time: LOOP_TIME, duration: LOOP_TIME - START, ease: 'none', }) .fromTo( RAW, { time: OVERLAP * SPACING + 1 }, { time: START, duration: START - (OVERLAP * SPACING + 1), immediateRender: false, ease: 'none', } ) Sorry if these are obvious questions. I'd love to get a proper handle on this before attempting to write about it. Think it's a real cool thing to show. The idea behind building something like this was to use it to showcase the CodePen on my site with 😎
  20. Ooo, that works seamlessly πŸ‘ Thank you @GreenSock I did change the demo a little to use a single tween. Then I use function based values to map how each visible element should appear. I'll see if I can fit that in πŸ€“ This is really cool. Thanks for taking another look at it. Yeah, this sort of thing I love digging into! https://codepen.io/jh3y/pen/YzGmNLL
  21. Yeah, that's what I was doing and it works for the most part if I disable `snap`. I did see that demo and also referred to how we used it for the DJ scratching demo. It was more curiosity for this one. I think I'm going to keep it as non-infinite and start it at an offset. Thanks again.
  22. Ahh. That's great! Thanks. I did wonder if doing a little subtraction was the answer. But, I think I was subtracting from the whole thing which wouldn't work πŸ€¦β€β™‚οΈ Ooo. I like that utility method approach. That's not one I've seen/tried. Thank you. I'll try that πŸ‘ One other question/clarification. I'm not sure if this is possible. I tried some "Hacky" ways to try and get it there. But, is there a way to get infinite scrolling working with something like this using `onLeave` and `onLeaveBack`? with `snap`. I figure that would be hard because `snap` effects the progress and then it ends up jumping back and forth between the first and last getting caught in a snap loop. It's not a requirement for this, more so a curiosity of how to do it. I'm making some materials around making this and I can start the scroll at the mid-point so it starts with things on either side πŸ‘
  23. Hey y'all! I'm messing around with this horizontal scrolling demo where I'm using ScrollTrigger and setting the body width to an excessive width. The effect works as expected when scrolling (I've not styled things up yet, POC πŸ˜…). But, I want to add "Next/Previous" buttons to the UI and I can't see what obvious thing I'm missing πŸ€¦β€β™‚οΈ "Previous" works as expected. But, "Next" is never able to reach the last item. I'm assuming I'm not doing something quite right in `SCROLLER.scroll` at Line ~#150. Or, my `start` and `end` isn't quite right? Could even be how I'm determing which item is the "Current" one. For that, I'm using `Math.floor(mapRange(0, 1, 0, CARDS.length, self.progress))`. And the snap "seems" to work. Anyone able to point out what obvious thing I'm missing? πŸ™πŸ˜…