Jump to content
Search Community

Relative values not working as expected

jakob zabala test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

So I am using relative values yPercent:"+=80" to move my 3 bubbles based on which the user chooses to reveal or not. They work fine sometimes but after playing around with it a bit, they start to act in strange ways, am I missing something in my method?

 

If this is not clear or something I made too complicated please let me know! thanks for the help ;)

See the Pen vYmmyqO by jaykobz (@jaykobz) on CodePen

Link to comment
Share on other sites

25 minutes ago, jakob zabala said:

after playing around with it a bit, they start to act in strange ways, am I missing something in my method?

Can you please be more specific? What does "act in strange ways" mean? 

 

And is there a way you can provide an even more simplified minima demo? Like...do you really need almost 200 lines of JS to demonstrate the issue? 

 

My guess is that this is just a logic issue with the code - keep in mind that animations record their starting/ending values the first time they render, so if you've got another tween that's in the middle of animating yPercent animating to 700, so perhaps it's at 410% and then another tween renders for the first time that's animating it to yPercent: "+=80", that means it'll lock in its start as 410% and end as 490%. So if you set up your animations with relative values like that and then the user moves their mouse around and clicks around quickly, the start/end values may not be what you THINK they are. Not a bug with GSAP - just a logic flaw in your code.

 

If my theory is correct, there are multiple solutions:

  1. Don't use relative values.
  2. Force the start/end values to get locked in right away by jumping to the end and then back to the start when you first create the animation. Like timeline.progress(1).progress(0). 
  • Like 1
Link to comment
Share on other sites

Hi Jack,

Hi Jack,

 

Thanks for you response, I apologise for the never ending lines of JS.  I cleaned up the code so Its only about 70 lines now (3 timelines). And the "act in strange ways" refers to the unexpected overlapping. I used relative values, because I otherwise did not know how to shift down the bubbles dynamically. I am not sure how to implement your second solution but it sounds like what I need.


The way my JS is set up is to have the first bubble push the 2nd and 3rd bubble down each by 80% relatively. The second bubble to push the 3rd down by 80 relatively as well. 
 

The problem is: the bubbles expand and contract PROPERLY the first round of clicking it, but then, expanding the second bubble a second time creates the third bubble to be misplaced. 

How should this logic be set up, I still don’t get why this logic is flawed

 

OR

 

Is there a way to animate so I can increase the percentage relatively to where it was at the start.

 

Thanks for the help!

 

See the Pen abWWJPy by jaykobz (@jaykobz) on CodePen

Thanks for you response, I apologise for the never ending lines of JS.  I cleaned up the code so Its only about 70 lines now (3 timelines). And the "act in strange ways" refers to the unexpected overlapping. I used relative values, because I otherwise did not know how to shift down the bubbles dynamically. I am not sure how to implement your second solution but it sounds like what I need.


The way my JS is set up is to have the first bubble push the 2nd and 3rd bubble down each by 80% relatively. The second bubble to push the 3rd down by 80 relatively as well. 
 

The problem is: the bubbles expand and contract PROPERLY the first round of clicking it, but then, expanding the second bubble a second time creates the third bubble to be misplaced. 

How should this logic be set up, I still don’t get why this logic is flawed
 
OR
 
Is there a way to animate so I can increase the percentage relatively to where it was at the start.
 
Thanks for the help!
Link to comment
Share on other sites

  • Solution

Yep, it's definitely a logic issue in your code. You've got things set up so that certain values must be dynamic (like yPercent of the 3rd SVG might be 0, or 80 or 160 depending on the state of the other SVGs) but you're baking a single set of values into one timeline for each. 

 

Open #2 and that timeline will set #3 to be yPercent 80. Fine. Looks good the first time. But if you close it, then open #1 and then open #2 again, that plays that timeline that sets yPercent of #3 to 80 but now it should be 160. Again, remember that the start/end values get recorded on the first render of a tween and if you replay that timeline it doesn't then re-record things because that wouldn't be a true replay. You can invalidate() to force it to re-record, but it looks like you're also using a .from() tween in your timeline so that's gonna cause logic issues. Remember, .from() uses the CURRENT values as the end, so whenever those values are when you invalidate() and run again will be locked in as the end values so in your case height may be 0, for example. Again, this isn't a bug in GSAP at all - it's a logic thing.

 

In my opinion, it'd be much cleaner to structure things differently. Since you're doing the same animation for each, you can use a simple loop and do write the code once. Use classes inside each <svg> so that you can grab the appropriate one each time through the loop (don't have #rect1, #rect2, #rect3... just use .rect and a scoped selector). This way all your animation code is centralized and easily edited. Plus you can drop in as many new <svg> elements as you want and they'll all follow the same pattern. No need to write a new timeline for each new event listener, blah, blah. Here's an example: 

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

 

Click around as much as you want. Always works. Right?

 

I hope that helps!

  • Like 1
Link to comment
Share on other sites

Wow! You went above and beyond to explain it and implement a completely new system. Yes, loop is much much better. My JS skills are not quite there but it all makes sense and definitively scalable this way, thanks for showing... it works great on the codepen. One problem I am having now is I am getting an error from webpack. 

 

This is what is showing up for the line 8 in your code, it dosn't like gsap.utils.selector??
TypeError: gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector is not a function 

I can't thank you enough for the help on this!!!

  • Like 1
Link to comment
Share on other sites

6 hours ago, jakob zabala said:

This is what is showing up for the line 8 in your code, it dosn't like gsap.utils.selector??
TypeError: gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector is not a function 

That just means you have an outdated version of GSAP. We added gsap.utils.selector() in 3.7.0, and we're up to 3.7.1 now. I'd strongly recommend updating. :)

 

6 hours ago, jakob zabala said:

I can't thank you enough for the help on this!!!

You're welcome! Glad to hear it helped. 

  • Like 1
Link to comment
Share on other sites

Hey Jack,

I have another question about gsap. Is there a way to do this hover around animation using gsap ? I want to convert this animation the way you set out the foreach loop and apply to multiple elements. 

   //Moving Animation Event
   hoodie1.addEventListener("mousemove", (e) => {
     let xAxis = (window.innerWidth / 2 - e.pageX) / 90;
     let yAxis = (window.innerHeight / 2 - e.pageY) / 80;
     card1.style.transform = `rotateY(${xAxis}deg) rotateX(${yAxis}deg)`;
   });

See the Pen OJmxJVL?editors=1010 by jaykobz (@jaykobz) on CodePen

Link to comment
Share on other sites

Heya Jakob!

So you're saying - "hey GSAP, give me all the elements with a class of 'card-right', loop over them and for each loop assign that element to the variable cardlargeRight so I can do stuff to it"

So you already have that card accessible through that variable name. There's no need to do another querySelector to get the card
 

gsap.utils.toArray(".card-right").forEach(cardlargeRight => {
    
      let cardRight = cardRight.querySelector(".card-right");
}


Also the following querySelector is very muddled. You're trying to find all elements with a class of card-right within an element stored in a variable called cardRight (which doesn't yet exist) and then you're attempting to assign them that same variable you're querying inside. Pretty inception worthy. 🤯

My advice would be to take it a little slower with JavaScript, get stuck in to the MDN web docs and make sure you take the time to look over each line and consider what it's doing.

See the Pen 9b0cb24de4d3577b103267ae9a3d2ca9?editors=0011 by cassie-codes (@cassie-codes) on CodePen

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...