classikd

Use css position in onUpdate callback

Recommended Posts

Hello,

 

 

I would like to make a half circle navigation, for that i made each nav item following a bezier curve, check its left position in the onUpdate callback, and stop it if its limit was reached.
My problem is that the items do not stop exactly where they should stop.

You can see the console.logs i put for the 3rd item to understand. (also look the css inline, this element should stop exactly at left:50%)
Here is the codepen : https://codepen.io/classikd/pen/Zwrrzg


I wouldn't have this problem if there were more "OnUpdate" executions, but I think I am going in a  bad direction..

I also tried to achieve that with time calculation instead, but as i want the item's easing not to be linear it was too difficult for me to find the exact moment they should stop 😕

Please how would you solve such a thing, do you have any solution ?


Thank you a lot.

 

Share this post


Link to post
Share on other sites

Yeah, I definitely wouldn't do it that way. Are you wanting it to use top and left percentage values for responsiveness? If so, that's fine, but it won't be as performant as using x/y transforms. 

 

Anyway, there are a few ways to do this that I can think of:

  1. Create the same tween for each element (as it looks like you're doing), but pause it and then use another tween to tween its progress to whatever value you need. For example, if the middle one is 50% through the tween, animate the progress to 0.5. That way, you can use any easing you want.
  2. Do math. I'd visualize the center of rotation, draw a line outward to the element and imagine animating its rotation and plot the x/y coordinates (or percentages in this case) using Math.sin() and Math.cos(). You can put it in a container element and then counter-rotate the inner element the other direction to make it look like it's not rotating at all (almost like a carousel). This will let you get EXACTLY what you want. So you'd use GSAP to animate the rotation value(s). 

I hope that helps!

  • Like 2

Share this post


Link to post
Share on other sites

Thank you for your answer Jack !

Yes I use top and left percentage values for responsiveness.
As i am bad at mathematics I am not able to try your second method, but i tried the first one.

Here is a codepen: https://codepen.io/classikd/pen/JxLWej

 

You can see in the console that I give a good progress value for each timeline, but unfortunately they are not equidistant :X

How to explain that ? I put linear easing everywhere... i really don't understand

Share this post


Link to post
Share on other sites

Aha, I see the issue. It's actually plotting things exactly where they should be, but if your container isn't exactly square, things will get "scrunched". It's just a logic thing. Imagine a circular clock, and cut it in half so you only see 9 O'clock through 3 O'clock. Now squish it vertically so that it's 1/4th as tall (but stays the same width). See how the angles to 10, 11, 1, and 2 O'clock all get weird? They're no longer equally-spaced. 

 

Simplify it further - imagine a 90-degree angle and then draw a line out to 45 degrees and plot the point on a circle. If your circle had a radius of 100, then the x and y coordinates of that 45-degree angle would be x:70.7, y:70.7. Now if we squish it in half vertically, the x coordinate DOESN'T CHANGE! So now y is 35.35 and x is 70.7 which is a very different angle to the center. See what I mean? 

 

There's no way to use percentage-based values to make this responsive the way you're asking for. It's logically impossible. You'd literally need to re-rerun calculations on every resize to plot the angles appropriately according to the new width/height ratios. 

 

Does that make sense? 

  • Like 3

Share this post


Link to post
Share on other sites

Thanks a lot Jack you helped me so much.

I heard you and I gave up the others methods that i tried above,  you made me understand and so I made it with a different approach:

Here is a codepen: https://codepen.io/classikd/pen/LqdQWb

I could have spent days on it, you saved my life !

Thanks again !!!

Share this post


Link to post
Share on other sites

Excellent, I'm so glad it helped and that you figured out a solution. Thanks for sharing. 

  • Like 1

Share this post


Link to post
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.