- February 22, 2021 at 10:45 am
For several projects I’ve worked on in the past I have noticed that an optimal outcome for an animation would be if it consisted of two parts: One part ‘generative’ i.e. expression-based, and one part ‘set’ i.e. keyframe-based. A balance between generated animation and fixed animation, and being able to transition between the two.
A simple example would be an animation where 2D-squares for one part of an animation ‘float around’ (e.g. by applying mapped noise()-input to their position-/size-/rotation-parameters) – stop and move into a set position (determined by keyframes) – and after a while are ‘released’ and start ‘floating’ again (based on the same expression as earlier).
I was wondering what an effective/good way of to achieving such a result would look like. Is it possible to transition between expressions and keyframes for an animation? I am aware that it’s possible to convert an expression to keyframes, but this seems a rather brute way of achieving what I’m hoping to achieve. I’m wondering if there is a different way.
Any help would be much appreciated. I’m sorry if this is an easily answered question, I haven’t been able to find much about this online, despite it seeming to be a fairly logical way of animating. Thanks a lot in advance. 😄
- February 22, 2021 at 11:19 am
Good question! I am very interested in a solution like that as well.
A thought, maybe it’s possible to transition the noise generated movement of the cubes to the keyframed position/movement with a slider control?
- February 22, 2021 at 11:29 am
First method that can work is with a simple if/else statement. i.e.: if time is smaller than keyframe’s time apply expression, else apply keyframes value.
Second method would be just like Dan said, link the expression to an expression controller and keyframe the controllers.
Let me know if it answers your question!
- February 22, 2021 at 12:26 pm
Thanks a lot for your input Yoan!
Your first mentioned solution sounds logical. I have two questions about it:
1. Within expressions: how do you indicate which values (either the expression- or keyframe-based) the property should adhere to? I have never applied that method before. Could you show me an example of what such an expression would look like?
2. Using that method: would it be possible to exercice control over the transition between the last ‘generated’ position value, and the new ‘set’ (keyframed) position value? The way you describe it makes it sounds as if the shape only switches between which ‘source’ the values come from (either an expression or a keyframe), but that there isn’t any interpolation between these two values. I’m hoping that it’s possible to apply different kinds of easing when switching between these sources.
Secondly: If you’re willing to elaborate on Dans solution a little bit more, which you mentioned should also work, I would really appreciate it. I can see the logic in it, but can’t wrap my head around how that would work, for I’ve also never applied sliders or slider controllers much in my AE projects.
Looking forward to your answers. Thanks a lot again! 😃
- February 22, 2021 at 1:37 pm
For example, paste the below keyframes on a layer.
Using a slider will allow you to crossfade manually (with keyframes) between the results of an expression (in this case simply a wiggle), and the pure keyframes
Adobe After Effects 8.0 Keyframe Data
Units Per Second 24
Source Width 1
Source Height 1
Source Pixel Aspect Ratio 1
Comp Pixel Aspect Ratio 1
Frame X pixels Y pixels Z pixels
0 705.165 668.574 0
20 865.165 668.574 0
40 865.165 508.574 0
60 705.165 508.574 0
80 705.165 668.574 0
100 865.165 668.574 0
120 865.165 508.574 0
140 705.165 508.574 0
160 705.165 668.574 0
linear(effect("Slider Control")("Slider"),0,100, value, w);
End of Expression Data
Effects Slider Control #1 Slider #2
End of Keyframe Data
- February 22, 2021 at 1:48 pm
I love this kind of stuff! For me, it usually comes down to the linear() or ease() expressions. These are range mapper expressions. The setup looks generally like this:
linear([input value], [range start value], [range end value], [result value 1], [result value 2])
1) Using Time as the input value
2) An opacity change happens between 1 second and 3 seconds
3) The opacity change needs to be from 0% to 100%
linear(time, 1, 3, 0, 100)
For your random position scenario, your expression might look like this:
var timeStart = 4; // There is random motion before this time
var timeEnd = 6; // The random motion has settled by this time
var temp = time; // Try using a slider with keyframes set to the values of timeStart and timeEnd
var pos1 = wiggle(1, 400); // The random motion
var pos2 = value; // This is the value of the position if the layer didn’t have the expression
ease(temp, timeStart, timeEnd, pos1, pos2) //
Ask questions about this if you don’t get it yet. Linear() and ease() are so important to my workflows that I want to help you understand them!
- February 22, 2021 at 2:57 pm
Oh yes how did I ever forget about the linear() and ease() functions! These are life savers!
- February 23, 2021 at 7:34 am
Wow, I’m learning a lot here! Really cool to see different ways to solve this issue.
As usual I took the low tech approach (which I guess doesn’t work in as many cases). I separated the dimensions of the Position and pasted this on the X Position that already had some keyframes, on a layer with a keyframed slider control.
transform.xPosition + ((wiggle(1,250)-transform.xPosition)*effect(“Slider Control”)(“Slider”))
It works, but it’s not pretty. 😂
- February 23, 2021 at 10:45 pm
When you click to make a new expression, the expression box is populated with an expression that means “use current keyframes”
One easy way to do exactly what you describe is to add your expression to the current parameter value. Even if there are keyframes it works. Also if you edit the value or keyframe, you are editing it before the expression (it shows value after expression). Remember with 2 dimensional or 3 dimensional parameters arrays you need to use vector math or operate on each part separately.
I commonly will animate a parameter 0-1 or 0-100 then multiply it by a constant in the expression. In this way one animation could drive the fade for items with different transparency levels.
All the best
Log in to reply.