Jump to content
GreenSock

Rodrigo last won the day on January 20

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    3,199
  • Joined

  • Last visited

  • Days Won

    198

Posts posted by Rodrigo

  1. Hi @AnDinh and welcome to the GreenSock forums!

     

    I think the issue stems from something else in your setup. As you can see in this example the end value doesn't cause any issue whatsoever:

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

     

    If you inspect the element the values are the correct ones. This doesn't seem related to GSAP. Unfortunately I know nothing about THREE so I can't help you with that. Hopefully other users with more experience in it can chime in and spot the issue.

     

    Sorry I can't be of more assistance. Let us know if you have more questions.

    Happy Tweening!

  2. Hi,

     

    That's completely possible, not really easy but possible.

     

    For high performance canvas stuff I'd recommend any WebGL library that you can get familiar with. The most popular ones are PIXIJS and THREEJS, so you should take a look at those.

     

    As for examples I can't really recall anything like that TBH, maybe another user has seen anything similar and could recommend a link or example. My first try would be using the Modifiers Plugin:

    https://greensock.com/docs/v3/GSAP/CorePlugins/ModifiersPlugin

     

    Happy Tweening!

  3. Hi @coolDev and welcome to the GreenSock forums!

     

    That's indeed the expected behaviour. Unfortunately I don't know all the ins and outs of this process so I can't explain it to you. But it seems that ScrollSmoother is storing the ScrollTrigger progress and then re-applying it when the window resize is completed.

     

    Please stand by for a more official and complete explanation.

    Happy Tweening!

  4. Hi,

     

    The issue could stem from the fact that you have a duplicated set of buttons:

    <div class='selector-container'>
      <ul class='selectorX'>
        <li class='lists'>1</li>
        <li class='lists'>2</li>
        <li class='lists'>3</li>
        <li class='lists'>4</li>
        <li class='lists'>5</li>
        <li class='lists'>6</li>
        <li class='lists'>7</li>
        <li class='lists'>8</li>
      </ul>
    </div>
    <div class='selector-container'>
      <ul class='selectorX'>
        <li class='lists'>1</li>
        <li class='lists'>2</li>
        <li class='lists'>3</li>
        <li class='lists'>4</li>
        <li class='lists'>5</li>
        <li class='lists'>6</li>
        <li class='lists'>7</li>
        <li class='lists'>8</li>
      </ul>
    </div>

    That returns a index value that is double of the expected here:

    buttons.forEach(function (button, i) {
      button.addEventListener("click", () => {
        const target = i * 0.125;
        gsap.to(progressX, {
          value: target,
          duration: 1
        });
      });
    });

    That being said we're circling back to an issue that Cassie already mentioned and, for which, you were warned about: You're creating and updating different threads trying to get a faster response. That's not the way it works. We provide as much support as we can with the time resources we have. I was going to look into your other thread today and that is exactly what I did, so as you can see you got an answer and I pointed to an actual issue when I had the time to do it. This is related to this thread it seems:

     

    Also is worth noticing that most of the issues with this project stems from logic and copy/pasting something without knowing exactly how it works and without putting the effort of understanding the code. This last problem of a duplicated list of items is a clear proof of that. We understand the pressure of a deadline and the frustration of a project not working as such deadline approaches, but we can't share the responsibility of users getting in projects that exceeds their capabilities. I strongly recommend you to learn more about Javascript and web development in general, this youtube channel has great resources for that:
    https://www.youtube.com/playlist?list=PLWKjhJtqVAbleDe3_ZA8h3AO2rXar-q2V

     

     

    Happy Tweening!

    • Like 1
  5. Hi,

     

    Without a live minimal demo is really hard to help you with the issue you're having. We can't really debug a live site where we don't have any control over the code and we can't tinker with it. Please keep your demo as simple as possible, don't copy/paste your entire project, just a few divs to clearly illustrate the problem.

     

    Also you should definitely take a look at the Flip plugin, as I think it could become helpful in this scenario:

    https://greensock.com/docs/v3/Plugins/Flip/

     

    Happy Tweening!

  6. Hi,

     

    Just create another instance in the timeline and use the position parameter to set it's starting point:

    const timeline = gsap.timeline();
    
    // temp image movement
    timeline.to(`.${tempClassObj}`, {
      duration: .6,
      top: (boundRect.top - 22),
      left: (boundRect.left),
      height: boundRect.height,
      width: boundRect.width,
    })
    .to(".temp-image img", {
      duration: 0.6,
      scale: 0.95,
    }, 0)// <- Will start at the same time

    Hopefully this helps. If you keep having issues, please include a minimal demo in order to get a better look at what could be the problem.

    Happy Tweening!

  7. Hi,

     

    I can spot two issues in your setup, mostly on your onStop callback:

    onStop: (self) => {
      progressX.value = snap(progressWrap(progressX.value));
      gsap.to(progressX, {
        duration: 2,
        value: progressX.value
      });
      console.log(progressX.value, "progress");
      console.log(snap(progressX.value), "snap");
    }

    What happens here is that you're updating progressX.value in the first line (), then you tell to GSAP to tween the value property of progressX to it's current value, because by that time progressX.value was updated with this:

    progressX.value = snap(progressWrap(progressX.value));

    See the issue?

    On top of that if you add this to your callback:

    onStop: (self) => {
      progressX.value = snap(progressWrap(progressX.value));
      gsap.to(progressX, {
        duration: 2,
        value: progressX.value,
        onUpdate: () => console.log("stop update", progressX.value)
      });
      console.log(progressX.value, "progress");
      console.log(snap(progressX.value), "snap");
    }

    You'll see that sometimes the values in the onUpdate are negative when that particular tween starts, that's why is taking the long way around soto speak, because is going from a negative progress to a positive one.

     

    This seems to prevent the jump in the rotation:

    onStop(self) {
      // progressX.value = snap(progressWrap(progressX.value));
      target = snap(progressWrap(progressX.value));
      console.log("onStop init", target);
      gsap.to(progressX, {
        duration: 2,
        value: target,
        onUpdate: () => console.log("stop update", progressX.value)
      });
      console.log(progressX.value, "progress");
      console.log(snap(progressX.value), "snap");
    }

    Unfortunately it doesn't prevent the negative value, for that you'll have to review the logic in your onChange callback to prevent negative values.

     

    3 hours ago, FrEZ said:

    so then the onStop gets the progress value and I don't have to use onStopDelay that is inconsistent?

    I don't get what you mean that stop delay is inconsistent. How exactly? With the modifications I suggested for the onStop callback everything seems to work as expected (except for the negative values of course).

     

    Hopefully this helps.

    Happy Tweening!

  8. Hi @Koriane and welcome to the GreenSock forums!

     

    First thanks for being a Club GreenSock member and supporting GreenSock! 🥳

     

    What exactly do you have in mind? Have you created anything that resembles what you want to do. This could be a very deep topic to dig into with different alternatives.

     

    We have this example of route transitions using Next13:

    https://stackblitz.com/edit/nextjs-13cw4u

     

    Also I just updated our example using Flip in different routes:

    https://stackblitz.com/edit/nextjs-bti25c

     

    As you can see that example has a component that checks for route changes and creates a Flip animation for some elements in it without re-rendering. It might not be what you're looking for but without a minimal demo is really hard for us to know exactly what you're trying to do.

     

    Let us know if you have more questions.

    Happy Tweening!

  9. Hi @Moz and welcome to the GreenSock forums!

     

    Based on your description the only thing I can think of is using normalizeScroll in your ScrollTrigger setup:

    ScrollTrigger.normalizeScroll(true);

    Just call that at the start of your project or your top level entry file. That should prevent the browser's address bar from hidding/showing as you scroll which could be the cause of the issue you're having.

    https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.normalizeScroll()

     

    Happy Tweening!

  10. Hi @overdrivemachines and welcome to the GreenSock forums!

     

    Just create another Flip instance for the container:

    function toggleBlue() {
      const containerState = Flip.getState(".container");
      const state = Flip.getState(items);
      items.forEach((i) => {
        if (i.classList.contains("blue")) {
          i.style.display = flag ? "block" : "none";
        }
      });
      flag = !flag;
    
      Flip.from(state, {
        duration: 1,
        scale: true,
        ease: "power1.inOut",
        onEnter: (elements) =>
          gsap.fromTo(
            elements,
            { opacity: 0, scale: 0 },
            { opacity: 1, scale: 1, duration: 1 }
          ),
        onLeave: (elements) =>
          gsap.to(elements, { opacity: 0, scale: 0, duration: 1 })
      });
      Flip.from(containerState, {
        duration: 1,
        ease: "power1.inOut",
      });
    }

    Hopefully that's what want to do. Let us know if you have more questions.

    Happy Tweening!

    • Like 1
  11. 5 minutes ago, gauel said:

    I didn't even know i could nest timelines like that

    Timelines are just containers for animations and other timelines as well, which brings a lot of tools to the table for controlling and playing with them. Be sure to have a look at the docs:

    https://greensock.com/docs/v3/GSAP/Timeline

     

    Also take a good look at the position parameter since that gives you super powers to order and sequence your instances inside a timeline.

     

    Happy Tweening!

  12. Hi @gauel and welcome to the GreenSock forums!

     

    I would definitely use a single Timeline for each section and then add those to a master timeline and this master timeline should be the one controlled with ScrollTrigger. On that note I strongly recommend you to not use ScrollTrigger right at the start of your project, just focus on your animations, be sure that they work in the way you intend and once you're happy with that, you can add ScrollTrigger to the mix. This is because we've seen a lot of users add an extra layer of complications with ScrollTrigger when they run into enough issues with their CSS and GSAP animations.

     

    You can also mix the ScrollTo Plugin with ScrollTrigger with no issue at all, check this example:

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

     

    2 hours ago, gauel said:

    These are the things where I'm not so sure what would be the usual approach in such a complex solution. Specifically with the snapping and several timelines on the page.

    Complex projects require custom solutions and one of our mantras around here is test-test-test. Depending on where/when you want to snap your ScrollTrigger there are different solutions either using labels or progress (snap points). Be sure to check the documentation:

    https://greensock.com/docs/v3/Plugins/ScrollTrigger

     

    Also we have some starter templates for using GSAP with Svelte and SvelteKit:

    https://stackblitz.com/@GreenSockLearning/collections/gsap-svelte-starters

    https://stackblitz.com/@GreenSockLearning/collections/gsap-sveltekit-starters

     

    You can fork them and create a minimal demo if you want.

     

    Good luck with your project and if you have any GSAP related question let us know.

    Happy Tweening!

  13. Hi @ssaruh and welcome to the GreenSock forums!

     

    This is more related to the way the elements are animated. In this case you have to move each card it's own width times the card's index in the collection and the duration of each animation has to increase based on the same index. For that you can use function based values:

    let scrollTween = gsap.to(sections, {
      xPercent: (i) => -100 * i,
      duration: (i) => 0.5 * i,
      ease: "none", // <-- IMPORTANT!
      scrollTrigger: {
        trigger: ".container",
        pin: true,
        markers: true,
        scrub: 0.1,
        //snap: directionalSnap(1 / (sections.length - 1)),
        end: "+=3000 bottom"
      }
    });

    Unfortunately the container animation class toggle functionality goes a bit wonky and it doesn't work as expected:

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

     

    You'll have to come up with a different custom logic to toggle that class, based on the progress of the ScrollTrigger instance on scrollTween. I tinkered with it quite a bit and couldn't come up with something solid and I don't have a lot of time to go through this right now.

     

    Let us know if you have more questions.

    Happy Tweening!

  14. Hi @Mark Howells-Mead and welcome to the GreenSock forums!

     

    That's something you could achieve with ScrollTrigger and Observer:

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

     

    Unfortunately we don't have the time resources to build fully working demos for our users, so hopefully that codepen is enough to get you started. If you run into any issues or have any GSAP related question, let us know and remember to include a minimal demo that shows the problem you're having.

     

    I recommend you to take a look at the docs for more information:

    https://greensock.com/docs/v3/Plugins/ScrollTrigger

    https://greensock.com/docs/v3/Plugins/Observer

     

    Finally the collection of ScrollTrigger examples can provide some good starting points for your project:

    https://greensock.com/st-demos

     

    Happy Tweening!

  15. Hi,

     

    Is really hard for us to solve issues without a minimal demo. Please try to re-create what you have in the simplest possible way so we can have a better idea of the problem.

     

    What I can see from the code you shared is that you are adding extremely long delays (80 and 10 seconds) to your timeline and then in the timeline's instances you're passing just a string with a number which GSAP interprets as an absolute position, so all your instances are added at 1, 2 and 3 seconds but you add a delay of 80 in the timeline at the same position of the first instance.

     

    Take a deeper look at the docs for Timelines and the position parameter to better understand how it works:

    https://greensock.com/docs/v3/GSAP/Timeline

     

    Let us know if you have more questions.

    Happy Tweening!

  16. Hi Dayne,

     

    What you have to do is refresh ScrollTrigger after the accordion item has been animated not before or when it starts it's own animation. If you know how long it takes you can create a setTimeout or a GSAP Delayed call for that:

    this.accordions.forEach(accordion => {
      accordion.addEventListener('click', e => {
        setTimeout(() => {
          ScrollTrigger.refresh();
        }, time);// <- This time is in milliseconds 
    
        gsap.delayedCall(time, () => ScrollTrigger.refresh()); // <- This time is in seconds
      })
    });

    If you keep having issues let us know and please include a minimal demo. Is really hard for us to debug or pinpoint problems with a video and/or live site where we can't tinker with the code.

     

    Happy Tweening!

    • Like 1
  17. Hi,

    5 hours ago, Fabian W said:

    is it only for content present on the initiation of SmoothScroller?

    Honestly I couldn't tell you about that, it seems that this might stem from something else.

     

    What you could try is to refresh your ScrollSmoother instance after adding the new content:

    const smoother = ScrollSmoother.create({
      smooth: 4,
      normalizeScroll: {
        allowNestedScroll: true
      }
    });
    
    /* After Adding New Content to DOM */
    smoother.refresh();

    That should trigger a full refresh of both ScrollSmoother and the ScrollTrigger instance it uses.

     

    Let us know how it goes.

    Happy Tweening!

  18. Hi,

     

    I think that the issue could lie in the way you're setting up your code in your index.tsx file. As you can see this is exactly your HTML/CSS with an oversimplified JS and it seems to work on every screen size I tested from 1000px to 1920px width:

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

     

    In your sandbox example one of the widths where I see the issue is when the browser is around 1190px width. If you set the width of the result window in the codepen example close to that value you won't see the issue. Based on the codepen example is clear to me that GSAP is doing exactly what is supposed to and that this most likely stems from something else in your setup.

     

    My recommendation would be to simplify your code in the isomorphic effect as much as possible in order to see where this actually breaks.

    Happy Tweening!

  19. Hi,

     

    Just like @mvaneijgen I'm a bit confused about what you intend to do.

     

    1. Do you want to animate the opacity of each letter as the colored blocks are moving to the sides?
    2. Do you want to move the blocks completely to the sides and only when that animation is completed animated the text from opacity 0?

    Assuming that you're after the second option, here is a fork of your codepen:

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

     

    If this is not what you want to do, please be specific about your project's needs and the current issue you're having.

    Happy Tweening!

    • Like 1
  20. Hi,

    51 minutes ago, AndyWhite007 said:

    "Oops! Trial version of DrawSVGPlugin deployed"

    That warning is given when you either deploy something created with the Club Plugins using GSAP Trial or using the files from Codepen.

     

    I don't see any transaction regarding Club GreenSock in your account. Draw SVG is indeed a Club plugin, perhaps you are confusing registering an account in GreenSock with purchasing a Club GreenSock membership.

    1 hour ago, AndyWhite007 said:

    - for simple annimations (like making lines 'grow') then is there a simpler way without specialist / paid plugins? 

    I believe that you can use the stroke dash offset and dash array, but I'm not very familiar with that technique, you should investigate a bit:

    https://css-tricks.com/svg-line-animation-works/

     

    1 hour ago, AndyWhite007 said:

    I've 'got it working' by making the SVG in the HTML - but is there a better way - or should I keep everything external to the html? i.e. what's 'best practice' for this?

    SVG is valid markup and you shouldn't have any issues in modern brwosers by including it directly on your HTML code.

     

    Hopefully this helps. Let us know if you have more questions.

    Happy Tweening!

    • Like 1
×