Um...it's on codepen, so you can look at the source and
see how it works...just click the Change View button. It's using a CSS animation on an infinite loop, translating down and back (keyframe at 50% time with translateY(200%)) using the CSS ease-in-out transition. It's a 1-second cycle, with each ball delayed by 0.1 seconds.
So it's not actually a sine curve, it's a cubic bezier. AFAICT the control points for ease-in-out are (0, 0), (0.42, 0), (0.58, 1), (1, 1). It's a bit of a nuisance to animate in one dimension (i.e. y as a function of x) using a 2D Bezier curve (in which both y and x are a function of a parameter t which goes from zero to one). So I'd just use a sine curve with a one second period and a one-tenth second offset: it will be easier.
To elaborate on what Princessa said: y = halfHeight * sin(2*PI * (elapsed_seconds - delay_seconds)/seconds_per_cycle)
Or in this case: y = halfHeight * sin(2*PI * (elapsed_seconds - 0.1*index))
If you want to animate with the Bezier, I've usually converted the curve to a series of line segments using the algorithm in Zhang and Ma's 2006 paper, which looks a bit scary at first glance but isn't that much code (
my demo here). Or you could maybe solve for the y value for each x value with Newton's method or something? Bezier curves can turn back on themselves, so in general you'd have to watch out for that.