Jump to content
Search Community

Cassie last won the day on April 16

Cassie had the most liked content!

Cassie

Administrators
  • Posts

    4,919
  • Joined

  • Last visited

  • Days Won

    174

Community Answers

  1. Cassie's post in looping circle does not give the desired effect was marked as the answer   
    Hiya! Welcome to the forums, nice work trying to convert this over.

    A couple of things.

    1) You're calling clear and creating new circles in the update function of a tween currently, that's great. That update will be called every 'tick' of the gsap engine, so on each tick you're clearing the canvas and drawing new circles. Perfect. But you've also added a call to this function into gsap's ticker, so you're also creating a WHOLE new tween on every tick, that new tween is then creating new circles on every tick. 🫠 Ticker inception, ticks all the way down, too much stuff happening. That's where the jankiness is coming from! Easy mistake though.

    2) Once that's sorted, maybe just tweak the timing and the ease, that might help make things feel more smooth and less rushed.


    See the Pen bGQOoKa?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Hope this helps!
     
    Have fun and happy tweening
  2. Cassie's post in How to programmatically end a ScrollTrigger instance before the `end` value is actually reached. was marked as the answer   
    Hi there! I'm getting an import error on your demo I'm afraid.

    It also seems like there's quite a lot going on here. Maybe you could break down your requirements a little and make a small vanilla JS demo with the bare essentials needed for us to understand the problem you're trying to solve.
    This is raising flags for me, observer doesn't need a scroll distance as it's all event driven
     
     
    Are you maybe trying to swop between observer triggered sections and normal scroll-triggered sections? If so maybe this demo will be helpful?  


    See the Pen oNQPLqJ by GreenSock (@GreenSock) on CodePen
  3. Cassie's post in Help with clipping paths and MorphSVG was marked as the answer   
    No worries! The docs are always a good source of info. Sometimes trying to extrapolate out from demos can get a bit confusing. Also if you feel like something's too complicated - it probably is. 

    So now that's out of the way - Clip path wise, the GSAP stuff stays the same but the SVG markup changes ✨ Nice and simple

    See the Pen Jjeeqvo by GreenSock (@GreenSock) on CodePen


    This is an evergreen article  https://css-tricks.com/masking-vs-clipping-use/

    And dev reference here!
    https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath

    If you have questions I'm happy to answer them ☺️
  4. Cassie's post in Pinned Section Inside Pinned Section was marked as the answer   
    Hi Matthew!
     
    You're nesting ScrollTriggers here which is a common mistake

    You can add scrollTriggers into timelines or tweens, but you can't add then to a timeline AND a tween in that timeline.
    You'll end up with conflicting logic. Tweens within a timeline are controlled by their position on the timeline and the timeline's playhead position. You can't tie the timeline itself to scroll and then also try to control a child tween independently with a different scroll relationship. Which one is the tween meant to listen to, the timeline's ScrollTrigger or it's own ScrollTrigger? They'll be fighting over control.
     
    let sectionFour = gsap.timeline({ scrollTrigger: { trigger: '.section.four', start: 'top bottom', end: 'top top', markers: true, id: "inner" } }); sectionFour.fromTo('.section.four .imgs', { autoAlpha: 1, }, { autoAlpha: 1, duration: .3, ease: 'Power4.easeInOut', scrollTrigger: { trigger: '.section.four .imgs', start: "top 120px", end: end + 'px', pin: true } });
    Nested pinning is also not supported. So you'll have to rethink a little.
    I'm not 100% on what your goal is but my advice would be to position the inner children of section 4 absolutely and then use a timeline to animate between them?

    Maybe something like this is a good starting point?


    See the Pen yLQxOOd?editors=0010 by GreenSock (@GreenSock) on CodePen
  5. Cassie's post in Loop text horizontally with scrollTrigger was marked as the answer   
    Hi there, you may be overcomplicating this if you just want the text to scroll a little bit along the x axis?
     
    Here's a super simple example

    See the Pen jOQzeEq by GreenSock (@GreenSock) on CodePen
     
    or maybe?

    See the Pen QWOYQab?editors=0010 by Spyropoulos (@Spyropoulos) on CodePen
     
    That horizontalLoop helper is great but sometimes it's best to start with the most basic implementation and then layer on complexity as and when you need it.

    Hope this helps
  6. Cassie's post in How do I correct an error?(message 1: GSAP target not found warning. 2: GSAP target undefined not found.) was marked as the answer   
    Hi there!
     
    You're right in that you're targeting a null element.

    The only way I can advise you to fix this is by stepping through your JS code slowly and console logging out your elements. It's likely you have a spelling error or some logic somewhere
     
    let el = document.querySelector('.bad') console.log(el) // returns null // trying to tween an element that doesn't exist gsap.to(el, { rotation: 360 }) // error // "GSAP target null not found. https://greensock.com"
    This isn't an issue with GSAP itself, it's due to passing GSAP an element that doesn't exist, so you'll need to fix the issue elsewhere in your code.
     
     
  7. Cassie's post in ScrollTrigger outside ScrollSmoother not working properly was marked as the answer   
    Heya! The first and main thing to note is that ScrollSmoother's 'scroller' is the wrapper element and your trigger will need to be within that element in order to fire. As it's a fixed element you can't do that as the fixed elements need to be positioned outside of the scroller. Which you've done.
     
    <body> <div id="smooth-wrapper"> <div id="smooth-content"> <!--- ALL YOUR CONTENT HERE ---> </div> </div> <!-- position: fixed elements can go outside ---> </body> But because of this you'll need to set things up differently. Here's a simple example of using the main scroller's minimum and maximum scroll values instead.


    See the Pen ZEmxGXr?editors=0010 by GreenSock (@GreenSock) on CodePen


    Hope this helps!
     
  8. Cassie's post in Random Floating Blobs Optimization was marked as the answer   
    Hi there, that blobby filter is fun, but unfortunately SVG filters are notoriously bad for performance.

    It's not your GSAP code, it's a browser rendering thing. You've hit the bottleneck and I'm afraid there isn't really anything that can help aside from 'don't do that' 😕

    If I were you I'd look at doing this in canvas? It'll be a bit more complex though I'm afraid.

    Sorry to be the bearer of bad news
  9. Cassie's post in "Draw" dashed line on scroll with an image was marked as the answer   
    Sure thing,
     
    Here you go, using a timeline is helpful, the main issue you had was that you were using different eases and start positions.
     
    You need both tweens to start at the same time, end at the same time and have the same easing in order to be in synch.
     

    See the Pen ExOwQLV?editors=1010 by GreenSock (@GreenSock) on CodePen
  10. Cassie's post in Issue with gsap Shockingly green install on Stackblitz was marked as the answer   
    Hiya! I would suggest using the trial package on stackblitz - especially is it's a public project. You don't want to be putting that tgz file out where the public can see.

    https://www.npmjs.com/package/gsap-trial

    Does this solve the issue for you?
  11. Cassie's post in Trouble with initial CSS value and invalidateOnRefresh was marked as the answer   
    Hiya!
     
    Thanks for the clear demo. You're just missing one little bit of the puzzle


    See the Pen XWyaazO?editors=0110 by GreenSock (@GreenSock) on CodePen
     
    Do the calculations with functional values instead of just setting it in the CSS. Then when GSAP runs refresh on resize it will run that function and update everything. Hope this helps!
  12. Cassie's post in Disabling scrollTrigger onLeave and re-enabling onLeaveBack was marked as the answer   
    Heya! 
     
    So scrub and toggleActions can't be mixed together out of the box because they do different things. You'd end up with conflicting logic.

    Scrub ties an animation to the scroll progress whereas toggleActions determines which animation control method is called at a specific point.
     
     
    So let's break this requirement list down.
     
    Scrubbed, onLeave, the animation should stop, when going up the animation shouldn't reverse. on leaveBack, re-enable the animation as at  the beginning, so that scrolling down again would animate.
    So if I understand correctly, you only want the animation to scrub through in one direction? 

    If so, you can disable a scrolltriggered animation in a callback, but by doing so you'd be removing the callbacks associated with that scrolltrigger, so you couldn't enable it again. So to get around that we can use two separate scrollTriggers, one to handle the callbacks and one to handle the animation. Then in the callbacks, we can enable and disable the animation scrollTrigger.

    Something like this?


    See the Pen Rwqozzx?editors=1011 by GreenSock (@GreenSock) on CodePen


    Hope this helps! 💚
  13. Cassie's post in Smoothscroller effect after certain scrolling position, not before was marked as the answer   
    Hiya!
     
    Thanks for the clear demo and explanation! (and for supporting club GreenSock!)
     
    Something like this maybe? Use a standalone scrolltrigger to pin and then a tween afterwards to move the text?


    See the Pen gOQWXbO?editors=0010 by GreenSock (@GreenSock) on CodePen
  14. Cassie's post in Need help staggering in triangles in SVG was marked as the answer   
    Hiya!
     
    you just had you selectors muddled,
     
    you were hiding the parent in the CSS and trying to show the children in the tween. Try this instead
     
    #triangles-pattern path { opacity: 0; height: 100vh; }  
  15. Cassie's post in Can someone help me understand the conversion between a timeline length and pixels? was marked as the answer   
    Heya @darkus

    Sounds like you're getting the hang of it, but here's a visual. Say you had the following timeline which is scrubbed over 1000px. It's 3 seconds long so let's split it into thirds.
     
    ScrollTrigger.create({ animation: tl, start: 'top top', end: '+=1000', scrub: true, }); tl.to('.one',{ duration: 1, rotate: 360 }) .to('.two',{ duration: 2, rotate: 360 })  
    The first tween would last 1/3 of the distance ( 333.33px ) and the second would last 2/3 of the distance ( 666.66px )
             one                         two
    |__________|____________________|
           1/3                           2/3
     
    Let's add a delay - now the timeline is 4 seconds long - let's split it into quarters.
     
    ScrollTrigger.create({ animation: tl, start: 'top top', end: '+=1000', scrub: true, }); tl.to('.one',{ duration: 1, rotate: 360 }) .to('.two',{ duration: 2, rotate: 360 }, '+=1')  
    The first tween would last 1/4 of the distance ( 250px ) then there would be a pause for 1/4 of the distance (250px) then finally the second tween would play for half of the distance (500px)
     
           one                 pause                      two
    |__________|__________|____________________|
           1/4                  1/4.                        1/2

    Aka, there's no set pixel to second conversion, the amount of scroll distance a tween takes up is dependant on how long it is in relation to the overall timeline. Think of time as ratios.

    Mathematically 
     
    (tween duration / timeline duration) * scroll distance scrubbed = (scroll distance covered by tween)
    (2.5 seconds / 5 seconds) * 500 pixels = 250 pixels 

    ---

    Hope this helps!

    fyi - the default tween duration is 0.5s if not specified. Also, if you have easing curves that aren't linear applied they won't map over linearly to the scroll progress.
  16. Cassie's post in GSAP MotionPath Circular Animation was marked as the answer   
    Hiya, thanks.
     
    So they're currently positioned visually on the path, but the motionPath plugin doesn't know where that is, it's not a specific point along the motion path, it's just a place in the SVG. One way would be to set the position using the motion path plugins start and end values, maybe something like this could work?


    See the Pen KKrNOed?editors=1011 by GreenSock (@GreenSock) on CodePen
     
    Not sure what you mean by this, but maybe the previous example solves this?

    Hope this helps? 💚
  17. Cassie's post in Horizontal Scroll Issue with section in between others sections was marked as the answer   
    Hi there!
     
    xPercent means 100% of that elements width. In your case you need the image to move by 100% of it's own width, minus the width of the screen. 

    Here's the magic incantation
    .to(".longImg", { xPercent: -100, x: () => window.innerWidth, duration: 2 })  
    It's important when using functional values that measure screen size that you invalidate those values if the user resizes their browser and changes the size of the screen.
     
    let scroll = gsap.timeline({ paused: true, invalidateOnRefresh: true })


    See the Pen zYMogZo?editors=0010 by GreenSock (@GreenSock) on CodePen


    Hope this helps! 💚
  18. Cassie's post in Vue - Sharing the timeline between multiple components was marked as the answer   
    Heya!
     
    I did a test and it's removed. Here you go


    See the Pen GRwjWgP?editors=1111 by GreenSock (@GreenSock) on CodePen
  19. Cassie's post in Initially paused timeline will not play; button click tl.play() doesn't play was marked as the answer   
    Hi there!
     
    If you pass the timeline in to GSDevTools you get a 2second animation controllable by devTools.

    If you comment out dev tools then the click event successfully plays the tl.

    You can't have both together as they conflict. 


    See the Pen oNQLmMx?editors=0010 by GreenSock (@GreenSock) on CodePen


    I don't get 2:50, but I do get 2:10 if I remove the paused and GSDevTools is controlling the global timeline. Not entirely sure why, tagging in @GreenSock for this one.
  20. Cassie's post in Issues with Gsap animations using Nextjs 13.4.5 (Production mode only) was marked as the answer   
    Hi there!
     
    This is just a flash of unstyled content, it happens in most sites with above the fold 'entrance' animations as the HTML and CSS are parsed before the JS
     
    This is far more apparent with next than React because React (if you're doing stuff client side, loads errrything with JS, so you don't get the brief moment where HTML and CSS are there but JS isn't) Whereas Next server side renders all the markup and then layers in JS.

    It's not really a problem, in all honestly it's far better to get content served fast and then have JS kick in, Next's time to first paint is far better than normal React. You just have to develop above the fold animations with this in mind. Old school thinking!

    i.e. Set up the initial states in the CSS
     

    See the Pen wvQKOJa by GreenSock (@GreenSock) on CodePen


    It's important to provide a fallback for cases where the JS doesn't load. I usually use a no-js class on the body and a little CSS animation, but you could also use a noScript tag. I've always been unsure whether style tags in noScript are valid or not? Can anyone clarify that? 

    Usually you won't see the flash if your network is fast enough, but here's a little video showing the flash with a slow network connection. Kapture 2023-06-14 at 09.11.39.mp4    
     

    Here's some stack overflow answers
    - https://stackoverflow.com/questions/4454551/check-if-javascript-is-enabled-with-php/9503382#9503382
    - https://stackoverflow.com/questions/218162/embedding-extra-styles-with-noscript
  21. Cassie's post in transformOrigin position was marked as the answer   
    I find dev tools pretty handy to figure out this sort of thing, easier to tweak and replay and scrub through slowly until you find the right combo - also adding a little outline so you can see where the shape's boundary box is.

    If you have a specific question, feel free to ask!


    See the Pen GRwZyyo?editors=0010 by GreenSock (@GreenSock) on CodePen
  22. Cassie's post in use easeParams on gsap 3 was marked as the answer   
    Heya - yep, there was a syntax change, see the thread.  ✨
     
     
  23. Cassie's post in pause timeline every second was marked as the answer   
    Heya!

    You can do this
     
    var master = gsap.timeline(); master.add( tl.tweenFromTo("myLabel1", "myLabel2") ); master.add( tl.tweenFromTo("myLabel2", 0) );
    from the docs - https://greensock.com/docs/v3/GSAP/Timeline/tweenFromTo()
  24. Cassie's post in Background sprite speed vs duration was marked as the answer   
    Heya!
     
    Always nice to see club GSAP folks in here 💚 Thanks for the support.
     
    How about something like this?
     

    See the Pen mdQJQxJ?editors=0010 by GreenSock (@GreenSock) on CodePen
  25. Cassie's post in Scrolltrigger Snap Not Working as Expected with Animations was marked as the answer   
    Heya!
     
    So the snap points are different once you've added pinning. The duration that you are 'on' the first panel is shorter as it pins immediately on load whereas the others need to be scrolled to and then pinned.

    I like using snap arrays, you can log the progress value in an onUpdate callback and then build out an array that's specific to your use case with those points.


    See the Pen GRwJOmJ?editors=1111 by GreenSock (@GreenSock) on CodePen
     
    Some other notes.

    - always include a trigger in your scrolltriggers or it defaults to body, this was causing issues in your previous pen
    - use markers to check where the start and end points are, if you'd done that you would have seen they were off (because the trigger container was incorrect)
    - with ScrollSmoother the scrollSmoother.create call always needs to be before your scrolltriggers, first in the code file.
    - ScrollSmoother-wise you also need to define a content container, or minimum requirement, you can just add a container with an id of smooth-wrapper.
     
    like so -
     
    <body> <div id="smooth-content"> <!--- ALL YOUR CONTENT HERE ---> </div> </body>
    Hope this helps!
×
×
  • Create New...