Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Looking to make complex curves #24

Closed
lukebatchelor opened this issue Jul 1, 2016 · 11 comments
Closed

Looking to make complex curves #24

lukebatchelor opened this issue Jul 1, 2016 · 11 comments

Comments

@lukebatchelor
Copy link

lukebatchelor commented Jul 1, 2016

First of all, this is an awesome library! I spent a long time looking for implementations a couple of weeks ago and didn't find this.

I'm looking at using this for some animations we are working on where we have some complex animation curves and I was wondering if you might be able to confirm if my idea should work, and also whether you might like it as a PR for this repo.

So, what we need is a way to specify curves with multiple control points and still interpolate from 0 -> 1.

This one, for example, does 80% of its movement in the first 20% of time and the final 20% in the last 80% of time.

The curve for the first bit is [0.23830050393398, 0, 0.25586732616931, 0.79011192334632] and the second is [0.21787238302442, 0.98324004924648, 0.58694150667646, 1].

What I'm planning is something taking a list of points and control points and be able to use them as if they were one curve:

var curve = [{
    cp: [0.23830050393398, 0, 0.25586732616931, 0.79011192334632],
}, {
    cp: [0.21787238302442, 0.98324004924648, 0.58694150667646, 1],
    p: [0.2, 0.8] // first curve will finish at [0.2, 0.8], rest of the curve follows the cp above
}];

var easing = cubicBezier(curve);

easing(0); // = 0
easing(0.2); // = 0.8 because we are at the end of the first curve
easing(1); // 1

So, the first curve would go from 0 -> 0.2, you would take the values from the curve and times them by 0.2 (because a 1 from the first curve would put you at 0.2 on the total curve). The second curves values would be 0.2 + 0.8*secondCurve.

I imagine it would work that, a single control point wouldnt need a p value because it would go from 0 -> 1 as normal, for two onwards you have p to tell you where the last curve finished.

So my two questions, does this work out mathematically as far as you can tell? And would you like a PR when I try this later?

Thanks again

@gre
Copy link
Owner

gre commented Jul 1, 2016

I don't think it should be in bezier-easing as it would complexify the library (that solve the problem just for one segment).
I've written another library that uses bezier-easing, and probably do what you want: https://github.com/gre/ipo

@gre
Copy link
Owner

gre commented Jul 1, 2016

(btw i will later release a new ipo version that just make a function, like in latest bezier-easing. instead of the o.get(x) API)

@lukebatchelor
Copy link
Author

Awesome, thanks! 😄

@gre
Copy link
Owner

gre commented Jul 2, 2016

i've released ipo v2 , should have better perf because it uses later bezier-easing.
also adopt the same functional style.
cheers

@gre gre closed this as completed Jul 2, 2016
@lukebatchelor
Copy link
Author

Ah, so I've just realised my original idea was wrong.

For anyone that sees this later, there is a difference between a series of independent bezier curves and a single complex curve that has multiple control points. What I didn't consider was that the control points affect both the next part of the curve and the previous one.

It looks like your library is exactly what I need.

I might have a couple of questions about it, but I'll direct them to the other repo.

Thanks again!

@gre
Copy link
Owner

gre commented Jul 4, 2016

you mean the constraint that a given x have one and only one y=f(x) representation? (like a math function)

To guarantee this, we just need the handles P1 and P2 x coordinates to be contained inside the [P0, P3] x coordinates.

It's an invariant that is in bezier-easing so you shouldn't be able to express such a case with bezier-easing / ipo.

@gre
Copy link
Owner

gre commented Jul 4, 2016

screen shot 2016-07-04 at 10 54 03

and in this extreme case we just have a near asymptote on x=0.5 but the curve is not "going back" because the handles x can only be inside [0.0, 1.0].

@lukebatchelor
Copy link
Author

lukebatchelor commented Jul 4, 2016

tl;dr ignore, my previous post completely, I was wrong

Apologies again, I'm slowly wrapping my head around this I think. Just don't want to leave incorrect information on here.

So I'll document what I was doing and how I understand it now.

I started with a curve in AfterEffects that looked like this.

I found and modified a script I found to export the curves as something more usable by css/webanimations api. They produced something like this.
.

I animated this using the webanimations api polyfill and was able to confirm that it was frame for frame correct with what I had in AE.

The way this was set out and the way you use cubic-beziers in css had me thinking that bezier curves work a point on the graph (x as time, y as the value), and two control points that start at that point and move somewhere else, and that those control points affect the next segment of the curve.


I thought that, this point here sort of mapped to

"transform": "translateY(-160px)",
        "easing": "cubic-bezier(0.21787238302442, 0.98324004924648, 0.58694150667646, 1)",
        "offset": "0.2"

I realise now that they way it works here (and in css easing functions) is that you define a point ([0,0] for example) and the two control points for the curve. One of these control points affects the the beginning of the line, the other affects the end.

This actually makes so much more sense now I think about how you use it for css animations.
You define the point you are at (a keyframe) and the easing function for how you want that value to change in between this and the next keyframe.

If this correct, then my previous post saying

there is a difference between a series of independent bezier curves and a single complex curve that has multiple control points

Was completely wrong. It most certainly is a discrete set of bezier curves.

edit Just say your reply @gre, I probably confused this a lot with my first explanation. I wasnt looking at the discrete values at a given X, just confused about where the control points are.

What tool are you using to play with the curves by the way?

Thanks again!

@gre
Copy link
Owner

gre commented Jul 4, 2016

@gre
Copy link
Owner

gre commented Jul 4, 2016

I was thinking making ipo-editor when I made ipo but unfortunately didn't found the time. maybe I'll do it later in the month.

@lukebatchelor
Copy link
Author

You've been an awesome help, thanks heaps @gre!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants