Jump to content


Setting bezier progress at anchor points

Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

To give a quick summary, I want to be able to set the progress/time at which a bezier path will hit each anchor point while keeping both the path and speed/progress smooth, i.e.:

var bezier_path = [
  {x:0, y:0, progress:0},
  {x:0, y:80, progress:0.1},
  {x:80, y:80, progress:0.5},
  {x:80, y:0, progress:0.6},
  {x:0, y:0, progress:1}


Essentially what I'm trying to do is the same as @danehansenfrom 2013 if it gives you any inspiration:


  • As you can see in the CodePen, the main method I've tried is correlating the x, y, and progress properties of a bezier tween. The x and y properties tween the moving element and the progress property tweens the parent timeline. Unfortunately it appears that including x and y values in the timeline tween breaks the tween.
  • Hence, I've played with BezierPlugin.bezierThrough to calculate the correlated bezier and then seperate the object properties out for the element and timeline tweens. Unfortunately, TimelineMax.to() with bezier:{} doesn't accept this form of input.
  • I've thought about using CustomEases but unless I know at at what time/progress a bezier anchor point will be reached this is not possible.


See the Pen agNNKZ by WD40andTape (@WD40andTape) on CodePen

Link to comment
Share on other sites

Are you trying to make the black dot go to each colored dot in a linear or a curved path? I'm trying to figure out why you're using BezierPlugin. 


First, a few notes about why your current codepen wasn't working:

  1. It doesn't make sense to "correlate" the progress in there. correlating is for positional values like x, y, z or top, left where the measurements must factor in them all. Like the distance between two points is the diagonal between the x,y and x,y points. So don't add "progress" in that list.
  2. You mixed x, y, and progress in every object in the bezier, thus you were literally telling GSAP to try setting a "progress" value on the element itself (along with x and y). Obviously the DOM element doesn't have a "progress" value, so that won't work :)
  3. Again, you were telling GSAP to set "x" and "y" properties of a timeline (along with progress). Timelines don't have x or y properties, so that can't work. 
  4. The progress value was animating correctly through each of those values, but they're weighted. In other words, think of an array of x,y points, some of which are very close together and some of which are far apart, and you ask BezierPlugin to animate an object along a path through those points - typically you wouldn't want it to split up the time EQUALLY between each point because that'd make it go really slow between the close points, and really fast between the far-apart points. See what I mean? So BeizerPlugin does a bunch of work to smooth all that out for you. Therefore, when you animated through the progress values, the same thing happened which is what made it SEEM linear. It was doing its job :) It sounds like you were expecting it to split the time equally. 

If I understand your goal correctly (and I probably don't), it's definitely a non-trivial task but it's doable. You could plot a path (like an SVG) using the progress value and maps it to the proportional spot on the timeline, smooth it (to prevent jerky changes in speed) and feed that into a CustomEase. It's definitely beyond the scope of the free help we offer in these forums. If you still need help and would like to chat about hiring us on a consulting basis to help knock this out, feel free to PM me. Or perhaps someone else here wants to chime in with an answer (which would be great). 


Good luck with the project!

  • Like 4
Link to comment
Share on other sites

Thank you very much to both @mikel and @GreenSock for your help - I really appreciate this community.


I figured out a solution! Hopefully it's useful to somebody in the future and you get a better idea of what I was after from this CodePen.

  • I am still using correlate as I need the tweened progress value to be synchronized with the position. However, I am now using a dummy object so that I don't try to set impossible properties of the DOM element/timeline.
  • In order to convert from the bezier progress value to a CustomEase I sample a number of points from the bezier tween. Perhaps there's a cleaner way to do this? Or to create a smoother CustomEase, as right now it's linear?
  • Another problem is that sometimes progress doesn't increase monotonically, i.e. sometimes if it needs to move too slowly between two points it will start moving backwards for a short distance.

See the Pen dBprjz by WD40andTape (@WD40andTape) on CodePen

Link to comment
Share on other sites

Glad to hear you got a solution. 


Unfortunately, that solution isn't at all what I was suggesting, and there seem to be some issues with the theory and math in there but I just don't have the time to troubleshoot it all or deliver a smoothed-out one. This is definitely beyond the scope of the kind of GSAP-specific help we offer in these forums. If you still need some help on a consulting basis, feel free to PM me. Or maybe someone else has time to dig in and craft a solution for ya. Congrats on getting this far, though! I know it's a tricky challenge :)

Link to comment
Share on other sites

No problem at all @GreenSock. I will continue to post here in case anyone can give me any pointers or in case someone needs to do the same in the future as to me it seems relatively fundamental to keyframing.


I have improved my previous solution. I am using two (slightly simplified) functions taken from BezierPlugin to estimate the length of each bezier segment. From this I know the progress at which each anchor will be hit. Hence, I can create a CustomEase to adjust these times to my target times.


As it stands, the main thing that needs improving is smoothing on the speed. You can see commented out in the CodePen that I have tried to convert and feed a BezierPlugin.bezierThrough into CustomEase instead of individual points. Unfortunately this was causing problems of rapid accel/decelerations and overshooting at times - I think this is maybe just the nature of BezierPlugin's 'thru' type.


See the Pen dBOzPJ by WD40andTape (@WD40andTape) on CodePen

  • Thanks 1
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.