Bastien Delmare

Digital Art Direction & Motion Design

WORK
BLOG
ABOUT
CONTACT

Expressions are the best tool to enhance your animations

Hey there! Today I’d like to share with you my favorites Adobe After Effects expressions. Your expressions add value to your work. It automates the way you animate your assets, it makes calculation and solves algorithms for you.

How do I integrate an expression ?

Simply go to the property you want to animate and Alt+Click the clock! A text area appears, here is your expression editor area!

My favorites expressions

Math.round

When you need to round an expression, exemple : a slider effect on an animated text (I did a tutorial on this function, go check it out!).


Math.round('what you need to round');

Bounce effect

When you need to round an expression, exemple : a slider effect on an animated text (I did a tutorial on this function, go check it out!).


n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}
}
if (n == 0){
t = 0;
}else{
t = time - key(n).time;
}

if (n > 0 && t < 1){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
amp = .05;
freq = 5.0;
decay = 10.0;
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{
value;
}

Loop effect on a composition

http://www.nabscripts.com/expressions/controle_1.html
First, enable the timeline remapping in Time > Enable timeline remapping, extend the composition far enough, then apply the expression (Alt/click on the property clock in question).


loopOut("cycle",1);

Wiggle

You can apply this expression to a lot of different property, for example: position, scale, opacity, rotation and others…


wiggle(a,b);

This expression will be wiggling from “a” to “b”. You’ve got to replace those two values by numbers. For example “0” and “100” on the opacity property if you wanna make a random effect from 0 to 100%.

+

Apply the following expression to a property to start wiggling it at time 2 seconds and stop wiggling it at time 4 seconds:


timeToStart = 2;
timeToStop = 4;
if ((time > timeToStart) && (time < timeToStop))
{
  wiggle(3,25);
}
else
{
  value;
}

How to make wiggle expression looping ?

Interesting thing to know if you wanna make the wiggle expression looping ! Read this article from motionscript.com. Thanks to Florian for the contribution :-).

freq = 1;
amp = 110;
loopTime = 3;
t = time % loopTime;
wiggle1 = wiggle(freq, amp, 1, 0.5, t);
wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime);
linear(t, 0,  loopTime, wiggle1, wiggle2)

Nice expressions for position property (emanuelecolombo.it)

Here is a pretty good set of expressions, very usefull, by Emanuelecolombo.it!

Inertia – Position & Rotation & Scale (by emanuelecolombo.it)


n = 0;
if (numKeys > 0)
{n = nearestKey(time).index;if (key(n).time > time){n--;}}
if (n == 0) {t = 0;} else {t = time - key(n).time;}

if (n > 0){v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
amp = 3;
freq = 2.0;
decay = 3.0;

value + (v/100)*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);}else{value;}

Bounce – Position (by emanuelecolombo.it)


var p = 0.8;		// period for elastic
var a = 50;			// amplitude for elastic
var s = 1.70158;	// overshoot amount for "back"

function outBounce(t, b, c, d, a, p) {
	if ((t/=d) < (1/2.75)) {
		return c*(7.5625*t*t) + b;
	} else if (t < (2/2.75)) {
		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
	} else if (t < (2.5/2.75)) { return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; } else { return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; } } function easeAndWizz() { var n = 0; if (numKeys > 0) {
		n = nearestKey(time).index;
		if (key(n).time > time)	{ n-- }
	}

	try {
		var key1 = key(n);
		var key2 = key(n+1);
	} catch(e) {
		return null;
	}
	
	// determine how many dimensions the keyframes need
	var dim = 1; // It's gotta have at least ONE dimension
	try {
		key(1)[1];
		dim = 2;
		key(1)[2];
		dim = 3;
	} catch(e) {}

	t = time - key1.time;
	d = key2.time - key1.time;

	sX = key1[0];
	eX = key2[0] - key1[0];

	if (dim >= 2) {
		sY = key1[1];
		eY = key2[1] - key1[1];

		if (dim >= 3) {
			sZ = key1[2];
			eZ = key2[2] - key1[2];
		}
	}

	if ((time < key1.time) || (time > key2.time)) {
		return value;
	} else {
		val1 =  outBounce(t, sX, eX, d, a, p, s);
		switch (dim) {
			case 1:
			     return val1;
			     break;
			case 2:
			     val2 = outBounce(t, sY, eY, d, a, p, s);
			     return [val1, val2];
			     break;
			case 3:
			     val2 = outBounce(t, sY, eY, d, a, p, s);
			     val3 = outBounce(t, sZ, eZ, d, a, p, s);
			     return [val1, val2, val3];
			     break;
			default:
			     return null;
		}
	}
}

(easeAndWizz() || value);

Elastic – Position (by emanuelecolombo.it)


// some defaults
var p = 0.6;		// period for elastic
var a = 140;			// amplitude for elastic
var s = 1.70158;	// overshoot amount for "back"

function outElastic(t, b, c, d, a, p) {
	if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
	if (!a || a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b); } function easeAndWizz() { var n = 0; if (numKeys > 0) {
		n = nearestKey(time).index;
		if (key(n).time > time)	{ n-- }
	}

	try {
		var key1 = key(n);
		var key2 = key(n+1);
	} catch(e) {
		return null;
	}
	
	// determine how many dimensions the keyframes need
	var dim = 1; // It's gotta have at least ONE dimension
	try {
		key(1)[1];
		dim = 2;
		key(1)[2];
		dim = 3;
	} catch(e) {}

	t = time - key1.time;
	d = key2.time - key1.time;

	sX = key1[0];
	eX = key2[0] - key1[0];

	if (dim >= 2) {
		sY = key1[1];
		eY = key2[1] - key1[1];

		if (dim >= 3) {
			sZ = key1[2];
			eZ = key2[2] - key1[2];
		}
	}

	if ((time < key1.time) || (time > key2.time)) {
		return value;
	} else {
		val1 =  outElastic(t, sX, eX, d, a, p, s);
		switch (dim) {
			case 1:
			     return val1;
			     break;
			case 2:
			     val2 = outElastic(t, sY, eY, d, a, p, s);
			     return [val1, val2];
			     break;
			case 3:
			     val2 = outElastic(t, sY, eY, d, a, p, s);
			     val3 = outElastic(t, sZ, eZ, d, a, p, s);
			     return [val1, val2, val3];
			     break;
			default:
			     return null;
		}
	}
}

(easeAndWizz() || value);

Back – Position (by emanuelecolombo.it)


// Ease and Wizz 2.0.1 : outBack : All keyframes
// Ian Haigh (http://ianhaigh.com/easeandwizz/)
// Last built: 2010-10-09T13:35:40+11:00
// some defaults
var p = 0.8;		// period for elastic
var a = 50;			// amplitude for elastic
var s = 1.70158;	// overshoot amount for "back"
function outBack(t, b, c, d, a, p) {
		if (s == null) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
function easeAndWizz() {
	
	var n = 0;
	if (numKeys > 0) {
		n = nearestKey(time).index;
		if (key(n).time > time)	{ n-- }
	}
	try {
		var key1 = key(n);
		var key2 = key(n+1);
	} catch(e) {
		return null;
	}
	
	// determine how many dimensions the keyframes need
	var dim = 1; // It's gotta have at least ONE dimension
	try {
		key(1)[1];
		dim = 2;
		key(1)[2];
		dim = 3;
	} catch(e) {}
	t = time - key1.time;
	d = key2.time - key1.time;
	sX = key1[0];
	eX = key2[0] - key1[0];
	if (dim >= 2) {
		sY = key1[1];
		eY = key2[1] - key1[1];
		if (dim >= 3) {
			sZ = key1[2];
			eZ = key2[2] - key1[2];
		}
	}
	if ((time < key1.time) || (time > key2.time)) {
		return value;
	} else {
		val1 =  outBack(t, sX, eX, d, a, p, s);
		switch (dim) {
			case 1:
			     return val1;
			     break;
			case 2:
			     val2 = outBack(t, sY, eY, d, a, p, s);
			     return [val1, val2];
			     break;
			case 3:
			     val2 = outBack(t, sY, eY, d, a, p, s);
			     val3 = outBack(t, sZ, eZ, d, a, p, s);
			     return [val1, val2, val3];
			     break;
			default:
			     return null;
		}
	}
}
(easeAndWizz() || value);

Squash & Strech – Scale (by emanuelecolombo.it)


freq = 2;
amplitude = 40;
decay = 1.0; 
t = time - inPoint;
x = scale[0] + amplitude*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
y = (1/x)*10000;
[x,y]

Undulation (by emanuelecolombo.it)


xAmp = 40; //height of undulations (pixels)
xFreq = .3; //undulations per second
xSpeed = 150; //speed of wave (pixels per second)

wl = xSpeed/xFreq; //wavelength (pixels)
phaseOffset = ((position[0]%wl)/wl)*2*Math.PI;
y = xAmp*Math.sin(2*Math.PI*xFreq*time + phaseOffset);
value + [0,y]

Jumpy Wiggle (by emanuelecolombo.it)


fps=5; //frequency
amount=25; //amplitude
wiggle(fps,amount,octaves = 1, amp_mult = 0.5,(Math.round(time*fps))/fps);

Grid (by emanuelecolombo.it)


columns = 10; //number of columns in grid
tHold= .2; //hold time (must be less than tmin)
tMin = .5; //minimum cycle time (can't be zero)
tMax = 1; //maximum cycle time
gap = this_comp.width/columns;
origin = [gap,gap];
xGrid = columns - 1;
yGrid = Math.floor(this_comp.height/gap) - 1;
start = 0;
end = 0;
j = 1;
while (time >= end){
  j += 1;
  seedRandom(j,true);
  start = end;
  end += random(tMin,tMax);
}
targetX = Math.floor(random(0,xGrid)); 
targetY = Math.floor(random(0,yGrid)); 
seedRandom(j-1,true);
x = random(); //this is a throw-away value
oldX = Math.floor(random(0,xGrid)); 
oldY = Math.floor(random(0,yGrid)); 
if(targetX == oldX && targetY == oldY){
  origin + [oldX,oldY]*gap;
}else if (time - start < tHold){
  origin + [oldX,oldY]*gap;
}else{
  deltaX = Math.abs(targetX - oldX);
  deltaY = Math.abs(targetY - oldY);
  xTime = (end - start - tHold)*(deltaX/(deltaX + deltaY));
  yTime = (end - start - tHold)*(deltaY/(deltaX + deltaY));
  if (time < start + tHold + xTime){
    startPos = origin + [oldX,oldY]*gap;
    targetPos = origin + [targetX,oldY]*gap;
    easeOut((time - start - tHold)/xTime, startPos, targetPos);
  }else{
    startPos = origin + [targetX,oldY]*gap;
    targetPos = origin + [targetX,targetY]*gap
    easeIn((time - start - tHold - xTime)/yTime, startPos, targetPos);
  }
}