Page 1 of 1

custom eases through expressions

Posted: October 18th, 2007, 4:22 pm
by yuppster
Is there anyway to replicate custom eases through expressions?

For example, you can do this to animate opacity from 0 to 100 from 1 to 5 seconds.
easeOut(time,1,5,0,100);

But what if I wanted to put specific values for speed/influence?

Anyone?

Re: custom eases through expressions

Posted: October 18th, 2007, 11:08 pm
by Mylenium
yuppster wrote:Is there anyway to replicate custom eases through expressions?

For example, you can do this to animate opacity from 0 to 100 from 1 to 5 seconds.
easeOut(time,1,5,0,100);

But what if I wanted to put specific values for speed/influence?

Anyone?
Nope, ease is always hardwired. You could write a custom function though that evaluates for each keyframe...

Mylenium

Posted: October 19th, 2007, 9:20 am
by yuppster
Thanks for the response Mylenium. Can you elaborate on what you mean about a function that evaluates for each keyframe?

Posted: October 19th, 2007, 1:37 pm
by Atomic
What you need to do it add an expression that evaluates every frame.

I'm not sure how to set speed and influence, but here is the an example of the source.text property being updated every frame.

Code: Select all

thisFrame=timeToFrames(t=time+thisComp.displayStartTime,fps=1.0/thisComp.frameDuration,isDuration=false);
if (thisFrame==0){text.sourceText = 'Shaky';}
if (thisFrame==1){text.sourceText = 'Wake';}
if (thisFrame==2){text.sourceText = 'A Tire';}
if (thisFrame==3){text.sourceText = 'Tube';}
if (thisFrame==4){text.sourceText = 'Passing';}
if (thisFrame==5){text.sourceText = 'Through';}
if (thisFrame==6){text.sourceText = 'Your';}
if (thisFrame==7){text.sourceText = 'New ';}
if (thisFrame==8){text.sourceText = 'Blue';}
if (thisFrame==9){text.sourceText = 'Cube';}
This technique does produce "ugly" expression code but it does work.
Simply add what code you need in the if statement of a given frame.
You could also use greater than or less than to allow a single if statement to encompass a range of frames.

Code: Select all

if (thisFrame<30){text.sourceText = 'Shaky';}
if (thisFrame <60){text.sourceText = 'Cube';}
//etc...
This would update the text every second.

This was taken from a script posted here:
http://www.aenhancers.com/viewtopic.php?t=751

Posted: October 19th, 2007, 2:53 pm
by yuppster
Thanks Atomic, now I understand. So something like this works for me, albeit being "ugly" like you said and a bit of work. Just created the animation how I wanted and copied the values for each frame over. (Oh, and I noticed that Motion Blur breaks this expression, not sure why.)

Code: Select all

thisFrame=timeToFrames(t=time+thisComp.displayStartTime,fps=1.0/thisComp.frameDuration,isDuration=false); 
if (thisFrame==0){position = [113,270];} 
if (thisFrame==1){position = [214.2085,270];} 
if (thisFrame==2){position = [370.4263,270];} 
if (thisFrame==3){position = [460.2031,270];} 
if (thisFrame==4){position = [516.8243,270];} 
if (thisFrame==5){position = [556.21142,270];} 
if (thisFrame==6){position = [584.89936,270];} 
if (thisFrame==7){position = [606.19488,270];} 
if (thisFrame==8){position = [622.02218,270];} 
if (thisFrame==9){position = [633.60311,270];} 
if (thisFrame==10){position = [641.76502,270];} 
if (thisFrame==11){position = [647.10807,270];} 
if (thisFrame==12){position = [650.0744,270];} 
if (thisFrame==13){position = [651,270];} 
if (thisFrame>13) {position = [651,270];}
So that works for my situation, but out of interest still wondering if it's somehow possible to build an expression that can take speed/influence values. I know that the ease, easeIn, easeOut are hardwired and it can't be accomplished that way, but is it technically impossible for the code to figure them out - even if the math is complicated?

Posted: October 21st, 2007, 8:16 am
by Mylenium
yuppster wrote:So that works for my situation, but out of interest still wondering if it's somehow possible to build an expression that can take speed/influence values. I know that the ease, easeIn, easeOut are hardwired and it can't be accomplished that way, but is it technically impossible for the code to figure them out - even if the math is complicated?
It's possible, you just have to limit yourself to some rules like only working with linear temporal interpolation. Based on that you can easily cobble up some code. I also think you're not exactly looking to re-create a full interpolation algorithm, as I understand it you are just looking to adjust the steepness and rounding falloff of a given curve. Some rough ideas on how I would approach it:

- decide on which side of a keyframe you are by comparing time*0.5 with the next keyframe
- implement a rule for which fraction of this time slice is supposed to hold the actual ease routine time*0.5*x
- divide the segment into managable chunks (not necessarily frames) time*0.5*x/y to keep it halfway fast
- calculate the values based on valueAtTime(time*0.5*x/y)*z*formula where z is the actual index of the time slice and formula refers to your custom routine. The entire thing needs to be contained in a loop to get a result for every slice.
- if necerssary, use additional functions like .smooth() to make the result more pleasant

In mathematically correct terms you would have to use integration methods (+=, -=) as each new intermediate value should be based on the previously agrregated one, but I wouldn't use it if you can avoid it. It's a major performance hit.

Mylenium

Posted: October 23rd, 2007, 6:08 pm
by nab
Is there anyway to replicate custom eases through expressions?
Yes, there is.
As suggested above, you can write your own interpolation function that would calculate the intermediate values from the current key and the next one.
First you would have to retrieve the keys...

Here is an example that interpolates keys using cosine function (position expression):

Code: Select all

prop = thisComp.layer("LayerName").position;
t = time;

if (prop.numKeys)
{
	k1 = getPrevKey(prop, t);
	k2 = getNextKey(prop, t);
	t = linear(t, k1.time, k2.time, 0, 1);

	cosineInterpolate(k1.value, k2.value, t);
}
else
	value;
Functions are defined here (they have to be included in the expression).

Posted: October 24th, 2007, 6:00 am
by )orgen
that's great!...

I dont fully understand the code behind this, but is there any way to adopt these easing equations into one after effects compatible format?

http://www.robertpenner.com/easing/

Would it be possible for an equation like this to follow the motion path between the keyframes?

Posted: October 24th, 2007, 4:01 pm
by Colin Braley
Yes, all of these could definitely be coded into an AE expression...there are actually a ton of types of interpolation methods out there...spline based interpolation, polynomial based, lerp, cosine, etc. Maybe sometime in the next two weeks I'll get some time to code a few of these, I can see a few instances in which these would be useful. I don't know what type of time/motivation I will have, so who knows...
If you need a specific one coded, I bet you could find some example code (not written for AE) and I bet there are a bunch of people on here who are willing/able to translate it into something for use in an AE expression.

Posted: October 24th, 2007, 6:12 pm
by yuppster
Hey, thanks guys for all your responses.

Basically I'm trying to replicate keyframed animations exactly - completely in expressions. (So for Nab's code, I wouldn't need the getPrevKey and getNextKey functions. It'd be fed with my own time and value...values).

Ideally, there'd be a function that I could feed speed/influence values into (taken from the values in the "keyframe velocity" box of my original keyframes). I guess that'd be 8 values (incoming and outgoing speed and influence). Don't know if something like that is possible.

Re: custom easing

Posted: July 15th, 2008, 6:28 am
by lunelson
This is very interesting. I've been looking for something like this because I find the default easing to accelerate and decelerate too slowly on long moves.

Could the cosine based script above be modified for easeIn and easeOut versions?

I downloaded the actionscript from Robert Penner's site and I think the math he is implementing is very similar...just the AE method posted here has fewer variables:

Code: Select all

class com.robertpenner.easing.Sine {
	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	}
	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	}
	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	}
}
This is probably a quick hack for the code wizards here...anyone?

Re: custom eases through expressions

Posted: July 15th, 2008, 7:09 am
by lloydalvarez
Check out this script by Ian Haigh.

http://ianhaigh.com/easeandwizz/

-Lloyd

Re: custom eases through expressions

Posted: September 1st, 2008, 12:34 am
by )orgen
perfect...thanks Ian Haigh ;)