airbnb / lottie-web

Render After Effects animations natively on Web, Android and iOS, and React Native. http://airbnb.io/lottie/
MIT License
30.54k stars 2.87k forks source link

Why all the values inside animated keyframe object for opacity are of array type? #791

Open sasmaster opened 6 years ago

sasmaster commented 6 years ago

For example: "i" and "o" contain "x" and "y" properties,which are of array type.Why it should be array?What is the case when it may contain more than single value?

In comparison to that,if I take "p" property ,it has "i" and "o" as objects with "x" and "y" value properties. Could you explain the reason behind such a design? Thanks.

bodymovin commented 6 years ago

After effects has multidimensional properties. Some of them are spatial and some are not. The spatial properties have a single easing value for all dimensions. But non spatial properties have different easing for each dimension.

sasmaster commented 6 years ago

How opacity is multidimensional property? Can you give an example for such a setup in aftereffects?

On Dec 30, 2017 00:15, "hernan" notifications@github.com wrote:

After effects has multidimensional properties. Some of them are spatial and some are not. The spatial properties have a single easing value for all dimensions. But non spatial properties have different easing for each dimension.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354506679, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgKLwotNqJIBEHX7mX8uGBbIOgaTLks5tFWR2gaJpZM4RPJ7H .

bodymovin commented 6 years ago

I didn't realize your question was only about opacity. Originally I changed properties of one dimension to arrays so they all would have the same interface and I kept it like that

sasmaster commented 6 years ago

Yes,but note that when opacity is not animated, its values are not of array type.I mean, if there is no reason for property to be of array type, maybe it shouldn't be of array type? It adds overhead to parsing those values.

On Dec 30, 2017 02:04, "hernan" notifications@github.com wrote:

I didn't realize your question was only about opacity. Originally I changed properties of one dimension to arrays so they all would have the same interface and I kept it like that

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354514765, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgNfoQ-VhTSDjUDekl99N1hEo0UR9ks5tFX37gaJpZM4RPJ7H .

bodymovin commented 6 years ago

@sasmaster yes, absolutely. Originally it made sense because any interpolated property would be handled by the same class regardless of the number of dimensions it has. If single dimension properties weren't arrays, they would have to be handled by a different class or using a specific condition.

sasmaster commented 6 years ago

Sorry again for bothering, here is another case I don't understand:

Animated scale property (3d layer) exports easing In and out like this:

                                                  ```
                                                  "i": {
                            "x": [0.833, 0.833, 0.833],
                            "y": [0.833, 0.833, 0.833]
                        },
                        "o": {
                            "x": [0.167, 0.167, 0.167],
                            "y": [0.167, 0.167, 0.167]
                        },

How is that possible for easing X or Y values to be multi-dimensional? I mean, the easing code used by Lottie BezierEaser.js ( taken from Mozilla  nsSMILKeySpline)also doesn't handle such a case ). Can I just discard 2 extra values per array? 
bodymovin commented 6 years ago

for non spatial properties like scale, each dimension has it's own easing curve. So to interpolate scaleX you need to use o.x[0], o.y[0], i.x[0], i.y[0] scaleY: o.x[1], o.y[1], i.x[1], i.y[1] scaleZ: o.x[2], o.y[2], i.x[2], i.y[2]

but for spatial properties like position, there is only one easing curve for all dimensions.

sasmaster commented 6 years ago

Hmm, now I see what you mean. Didn't realize it was possible to setup in AE. Thanks.

On Dec 30, 2017 20:25, "hernan" notifications@github.com wrote:

for non spatial properties like scale, each dimension has it's own easing curve. So to interpolate scaleX you need to use o.x[0], o.y[0], i.x[0], i.y[0] scaleY: o.x[1], o.y[1], i.x[1], i.y[1] scaleZ: o.x[2], o.y[2], i.x[2], i.y[2]

but for spatial properties like position, there is only one easing curve for all dimensions.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354560942, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgAyM7yRjnvSFeB3jb2l75eadMUU3ks5tFoAfgaJpZM4RPJ7H .

sasmaster commented 6 years ago

Is the cubic interpolation factor [t] accurate in Lottie? I am comparing intermediate position of a layer along a single curve and I see this:

while the start and end positions (t = 0 , t =1) are pixel perfect,there is noticeable offset in between during the motion.Now ,to make sure I didn't make mistake in my code (writing c parser),I tried to verify with built in player in the bodymovin extension.And I see the same bug. I believe that [t] is calculated with some acceleration (or "easing" if you wish) on AE side.Is it expected behavior on Lottie side? With linear interpolations I don't see similar issues.

Thanks.

On Sat, Dec 30, 2017 at 9:54 PM, Michael IV explomaster@gmail.com wrote:

Hmm, now I see what you mean. Didn't realize it was possible to setup in AE. Thanks.

On Dec 30, 2017 20:25, "hernan" notifications@github.com wrote:

for non spatial properties like scale, each dimension has it's own easing curve. So to interpolate scaleX you need to use o.x[0], o.y[0], i.x[0], i.y[0] scaleY: o.x[1], o.y[1], i.x[1], i.y[1] scaleZ: o.x[2], o.y[2], i.x[2], i.y[2]

but for spatial properties like position, there is only one easing curve for all dimensions.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354560942, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgAyM7yRjnvSFeB3jb2l75eadMUU3ks5tFoAfgaJpZM4RPJ7H .

bodymovin commented 6 years ago

it should be. Can you share a reduced .aep where it's different between AE and the web player?

sasmaster commented 6 years ago

Yep, I will tomorrow. Also there is a bug in extension's preview window. Its size doesn't match the size of the composition.

On Dec 31, 2017 23:34, "hernan" notifications@github.com wrote:

it should be. Can you share a reduced .aep where it's different between AE and the web player?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354624707, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgEIh1oa4N48UZZjS89YSwpGN5J4mks5tF_4AgaJpZM4RPJ7H .

sasmaster commented 6 years ago

Well,it was apparently my mistake.I completely ignored the non - uniform motion speed issue related to curves. Now added curve split as Lottie does,the values start looking sane.

On Sun, Dec 31, 2017 at 11:34 PM, hernan notifications@github.com wrote:

it should be. Can you share a reduced .aep where it's different between AE and the web player?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354624707, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgEIh1oa4N48UZZjS89YSwpGN5J4mks5tF_4AgaJpZM4RPJ7H .

bodymovin commented 6 years ago

Nice. Regarding the preview window, it's intentional, so you can see how it behaves inside a fluid container.

sasmaster commented 6 years ago

Hi Again. Do I get the following right? You ignore "to" and "ti" tangents for orientation and interpolate its x,y,z linearly?

I was testing orientation and it was wrong when animated. Then I found this part in your sources:

if(data.or.k[0].ti) { var i, len = data.or.k.length; for(i=0;i<len;i+=1) { data.or.k[i].to = data.or.k[i].ti = null; } }

Could you please comment on this thing?

Thanks.

On Mon, Jan 1, 2018 at 7:19 PM, hernan notifications@github.com wrote:

Nice. Regarding the preview window, it's intentional, so you can see how it behaves inside a fluid container.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354664656, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgGLBAkC-45Ec_Joecy_C2Wdbd4Irks5tGRO0gaJpZM4RPJ7H .

bodymovin commented 6 years ago

yes, it's being ignored for now. I have to look into it. Not sure if it needs to be implemented actually.

sasmaster commented 6 years ago

Thank you for your quick response. I have been messing with orientation now for several hours and while start and end transform looks correct,those in the middle don't . I tested in Lottie player (bodymovin extension) and I see it also doesn't interpolate orientation right. Here are 2 screenshots ( discard scale because the windows are not of the same size)

This is wrong one (lottie preview) wrongl

And this is correct one (AE viewport) rightl :

All of the intermediate frames between 2 keyframes look wrong.

Can you confirm it is supposed to be like that? I notices that AE does some tricky interpolation of orientation. All 3 components depend on each other. I tried to convert to quaternion and doing linear interpolation,but it didn't work.(not sure they use quaternions,looks more like euler angles) Need to investigate how they do that.

Thanks.

bodymovin commented 6 years ago

can you share the .aep so I can take a look?

sasmaster commented 6 years ago

Here it is: TestOrient folder.zip

sasmaster commented 6 years ago

Yeah,it must be SLERPed with quaternions. I just tried to convert start/end rotation to quaternions and SLERP between those.Looks ok.

bodymovin commented 6 years ago

Nice, I'll have to learn about quaternions then. I've never worked with them yet. Any helpful resource you can share?

sasmaster commented 6 years ago

Well,for you to fix it on your side,I suggest not to mess with raw math stuff,otherwise you can just type "quaternions" and google will spit tons of info. Add to you math lib a quaternion class (or whatever it is called in js)) and spherical linear interpolation method (aka SLERP).Also you will need conversion methods from quaternions to matrix or euler angles.

What I did was (Per orientation animation segment):

  1. Convert start orientation to quaternion.

  2. Convert end orientation to quaternion.

Use SLERP to interpolate,which looks like this quat res = slerp(quat1,quat2,t);

Then convert resulting quaterion either to rotation matrix (again,find some math lib and grab it from there)

Or you can convert that quaternion to euler angles and use those to transform your matrix. I am sorry,I am C/C++ guy and couldn't suggest you js lib,but i am sure there are plenty in the web. I personally use glm math library for C++. It has all that tricky stuff inside.

On Wed, Jan 3, 2018 at 1:20 AM, hernan notifications@github.com wrote:

Nice, I'll have to learn about quaternions then. I've never worked with them yet. Any helpful resource you can share?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-354901748, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgNnzShFt3SSQy-CnMbSVMVxGI_gEks5tGrnSgaJpZM4RPJ7H .

sasmaster commented 6 years ago

Hi Again. Could you please explain briefly the following text layer properties?

"j" , "tr" , "ls" , "fc" , "t"(which is part of t["d"]["k"]["0"] obj)

Thanks!

sasmaster commented 6 years ago

well , "fc" is probably color?

Could you shed some light on text's "m" object props ?

Thanks.

bodymovin commented 6 years ago

"j" is justify "tr" tracking (letter spacing) "ls" textDocument baselineShift (offset in the y direction) "fc" fill color "t" is the keyframe time. If you don't have keyframes, there will only be one and it's value will be "0"

sasmaster commented 6 years ago

And "m" stuff?

bodymovin commented 6 years ago

the "m" are in After Effects the "More Options" group. Where two properties are getting exported: "Anchor Point Grouping" ("g") and "Grouping Alignment" ("a") first one is a drop down second one is a two dimension property that can have keyframes.

thanks for the quaternions info by the way. I'll loon into it this weekend

sasmaster commented 6 years ago

You're welcome.Thanks for explanations. I have a question regarding camera's point of interest.I see you store it in "a" node. And it has curve tangents data. Do you use those when animating camera point of interest ,or discard as in the case with orientation? Thanks.

bodymovin commented 6 years ago

Hi, for the camera's POI, it respects it's spatial curves correctly.

sasmaster commented 6 years ago

Hi again. I am testing some project with your latest version. I think there is a bug in JSON. I have an animated scale property,which gets occasionally numbers for "i" and "o" greater than 1.Which doesn't make sense IMHO.For example,I am getting numbers for x,y like 49.31 or 53.418 . It happens when keyframe type is EasyEase. Could you please check it? And the result of it that animation is always finished between two keyframes.I also checked in preview window.Looks wrong. Thanks!

bodymovin commented 6 years ago

Can you share the .aep? I'm trying it right now and it seems fine.

sasmaster commented 6 years ago

Here you go. That's the text layer. BM version 5.1.3 TextScalaBug folder.zip

bodymovin commented 6 years ago

Hi, there is an old problem when interpolating between two keyframes with the same value. I haven't figured out yet how to export it correctly, but if you set the third keyframes to 100.1%, everything should work fine. Regarding values above 1, it's fine, since the easing curve can have the control points outside the 0,1 range.

sasmaster commented 6 years ago

Sorry, didn't understand what you mean by " but if you set the third keyframes to 100.1%, " .Regarding spline easing, that's incorrect. The original c++ class from Mozilla, which I also use, and upon which your BezierFactory is based clearly states that inputs must be in range 0 - 1 .which really makes sense because the easing function returns eased time based on normalized range. You can see that in nsSMILKeySpline.h (just Google for it).at the moment when the upper limit is great than 1 ,the easing function return time which is the end of the interpolation. Hence we can see no animation at such a keyframe .Also, it can't be no bug because those numbers don't make sense compared to similar properties from adjacent keyframes. Regards, Michael.

On Jan 10, 2018 14:37, "hernan" notifications@github.com wrote:

Hi, there is an old problem when interpolating between two keyframes with the same value. I haven't figured out yet how to export it correctly, but if you set the third keyframes to 100.1%, everything should work fine. Regarding values above 1, it's fine, since the easing curve can have the control points outside the 0,1 range.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-356590282, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgEzLkc5zPKU9v_6hNkKkP8iXfbOaks5tJK8BgaJpZM4RPJ7H .

bodymovin commented 6 years ago

In your .aep you have 4 keyframes, the second and the third keyframe have the same value "100%, 100%" Eased interpolation between two keyframes with the same value won't be exported correctly. So you need to set one of them to a different value than the other one, for example 100.1%

Regarding the 0,1 range, perhaps I'm not being clear. The input you pass to the function cannot exceed the 0-1 range indeed. But the curve can be built with your control points outside the 0,1 box Try moving the control point in this site. http://cubic-bezier.com/

sasmaster commented 6 years ago

Ok,got you regarding the keyframes values.But regarding the easing - you probably don't get me.

Please read here:

https://github.com/mozilla-services/services-central-legacy/blob/master/content/smil/nsSMILKeySpline.h

And I am not talking about Bezuer curve control points (tangents) but about easing control points.Which are also defined by SVG standard on top of which the above mentioned class based as well. Here ( https://www.w3.org/TR/2001/REC-smil-animation-20010904/) it is explicitly stated:

//Start of citation keySplines = ""A set of Bezier control points associated with the keyTimes list, defining a cubic Bezier function that controls interval pacing. The attribute value is a semicolon separated list of control point descriptions. Each control point description is a set of four floating point values: x1 y1 x2 y2, describing the Bezier control points for one time segment. The keyTimes values that define the associated segment are the Bezier "anchor points", and the keySplines values are the control points. Thus, there must be one fewer sets of control points than there are keyTimes.

The values must all be in the range 0 to 1.

//End of citation

So a value for easeIn or easeOut, specified in json's "i" and "o" nodes and it is greater than 1, doesn't make sense mathematically.That's because the advancement along the curve is being evaluated based on time (t) which is 0 < t < 1. And easing control points are points inside that time span,hence they can't be out of [0,1] range. You can also see this if you debug interpolation values that jumps abruptly to the last value inside the list if timings generated by your BezierFactory. Are values of 53.418 and 49.31 generated by AfterEffects?

Regards,

On Wed, Jan 10, 2018 at 3:01 PM, hernan notifications@github.com wrote:

In your .aep you have 4 keyframes, the second and the third keyframe have the same value "100%, 100%" Eased interpolation between two keyframes with the same value won't be exported correctly. So you need to set one of them to a different value than the other one, for example 100.1%

Regarding the 0,1 range, perhaps I'm not being clear. The input you pass to the function cannot exceed the 0-1 range indeed. But the curve can be built with your control points outside the 0,1 box Try moving the control point in this site. http://cubic-bezier.com/

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-356595664, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgArRzzrFqCDTEitPlauUCe9b_sT1ks5tJLSUgaJpZM4RPJ7H .

sasmaster commented 6 years ago

But I think I understand where is the problem on your side.Please take a look at the animation graph of Scale in the text layer (what I sent you):

fsd You see,the two points at the bottom are keys for two key frames ,each of them is 100,100 scale.But as you can also see,they are connected with bezier, and not with straight line.Which means the interpolation is done along bezier.But BodyMovin exports these keyframes without tangents just like a linear interpolation.That's also the reason there is no visible animation between these two keyframes because in linear interpolation you get nothing between identical values.

bodymovin commented 6 years ago

yes, and that's also why the bezier easing in these cases have control points that exceed the 0,1 range. Values are connected by a straight line and the bezier curve is a function of time that returns the multiplier applied to the straight line between the two scale values. The BezierFactory indeed does not return an "eased" time. Since keyframes in AE have "influence" and "speed", and not easing control points, this is what I could come up with to convert them for now. As a consequence, I can't interpolate correctly between same values.

sasmaster commented 6 years ago

Hmm, now I see what you mean. And adobe docs don't shed light on how to deal with such a curve?

On Jan 11, 2018 01:01, "hernan" notifications@github.com wrote:

yes, and that's also why the bezier easing in these cases have control points that exceed the 0,1 range. Values are connected by a straight line and the bezier curve is a function of time that returns the multiplier applied to the straight line between the two scale values. The BezierFactory indeed does not return an "eased" time. Since keyframes in AE have "influence" and "speed", and not easing control points, this is what I could come up with to convert them for now. As a consequence, I can't interpolate correctly between same values.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/airbnb/lottie-web/issues/791#issuecomment-356766648, or mute the thread https://github.com/notifications/unsubscribe-auth/AAawgDe9iX_MVVcgNdYq87-Eq5cox6unks5tJUE3gaJpZM4RPJ7H .

sasmaster commented 6 years ago

But have you tried to do cubic interpolation on scale too? I tried to plug values from scale curve into cubic bezier interpolator,and the values look almost fine. I say "almost" because the steps were off,but that could have happened because I didn't break the curve to segments as it is done for position animation.

AnishGG commented 5 years ago

yes, it's being ignored for now. I have to look into it. Not sure if it needs to be implemented actually.

@bodymovin, Is lottie still ignoring the "ti" and "to" values? If yes, are the "i"Bezier curve interpolation in value and "o"Bezier curve interpolation out value, the only parameters to calculate the curve? I mean are these the ease-in and ease-out parameters as can be seen here. Any help would be highly appreciated. ^_^ Thanks in advance!