Jesper Hustad .com

Bouncing DVD logo expression in After Effects

This is our goal:

Create an expression

Add the element you want bouncing around to your composition Find the position property (shortcut is P) Hold Alt/Option and click the stopwatch to create an expression

Paste in the code

Copy Paste this code into the expression window that appears
Customize your effect with the first three variables (v, i, o)

// customize speed, position and offset here
var v = 400;     //velocity
var i = [0,0];   //initial position
var o = 0;       //time offset
var fc = 1       //frame count (for spritesheet)

var f = (time+o) * v                  //function
var t = [i[0]+f, i[1]+f];             //time x/y
var d = thisLayer.sourceRectAtTime(); //dimensions
var s = transform.scale;              //scale
var lh = d.height*(s[0]/100);         //layer height
var tlw = d.width*(s[1]/100);         //true width
var lw = Math.floor(tlw/fc);          //layer width
var w = thisComp.width - lw;          //screen width
var h = thisComp.height - lh;         //screen height

// cycle count in x and y
var c = [Math.floor(t[0]/w), Math.floor(t[1]/h)];

// position in cycle for x and y
var p = [t[0] % w, t[1] % h]

//     cycle isOdd ? inversed : original      
var x = c[0] %2==1 ? w - p[0] : p[0];
var y = c[1] %2==1 ? h - p[1] : p[1];

var bc = (c[0]+c[1])%fc;   //bounce count
var fo = bc * lw;          //frame offset

[x + tlw/2 - fo, y + lh/2]

Custom start position

Create a null that will hold our starting position and open it's position property. Select the square brackets and parent it to the nulls position. Now if you move the Null around at 0 seconds the logo will follow.

Color change on bounce

Since After Effects expressions can not remember state this is tricky. Start by adding the Color Balance (HLS) effect to the logo.
Same as before add an expression by holding Alt/Option on the effects hue property. Copy paste this code, where the last part has been altered to work with hue.

Note that this doesn't work with our custom start position! More on this bellow.

// REMEMBER TO MATCH BOTH EXPRESSIONS! 
var hueShift = 50; //hue shift
var v = 400;      //velocity
var i = [0,0];    //initial position
var o = 0;        //time offset

var f = (time+o) * v                  //function
var t = [i[0]+f, i[1]+f];             //time x/y
var d = thisLayer.sourceRectAtTime(); //dimensions
var s = transform.scale;              //scale
var lw = d.width *(s[1]/100);         //layer width
var lh = d.height*(s[0]/100);         //layer height
var w = thisComp.width - lw;          //screen width
var h = thisComp.height - lh;         //screen height

// cycle count in x and y
var c = [Math.floor(t[0]/w), Math.floor(t[1]/h)];

var bounces = c[0] + c[1];
(bounces * hueShift) % 360

Keeping both expression in sync

If you change any property in one expression you must do the same for the other! If initial position is paired to the null for position, it must also be done for Hue.

Pro tip: Apply the Slider Control effect to your element and rename it to velocity slider. Pair the velocity property (i) for both expression to the slider, now the speed is always in sync.

Change image on bounce

⚠️ This is hard to implement and very easy to mess up. ⚠️
I made this at the request of Benedetta Anghileri.

First create an image containing all the logos.
Search spritesheet online for more info, this online tool makes one for you.
Remember that every image needs to be the same size (x, y).
Here is an example spritesheet:

In the first position expreesion there is a variable for the number of logos/frames in your spritesheet.
var fc = 6 //frame count (for spritesheet)

How to switch between logos
Apply the transition effect Linear Wipe from the effects panel twice (so that you have two).
For the second linear wipe effect change wipe angle to 270.
For the second linear wipe effect create an expression for the Transition Completion variable like so:

// Second (Linear Wipe 2) expression
var fc = 6 //frame count
100-(100/fc)-effect("Linear Wipe")("Transition Completion")

For the first linear wipe effect apply this expression to the Transition Completion variable.

// First (Linear Wipe) expression
// REMEMBER TO MATCH VARIABLES FOR ALL EXPRESSIONS! 
var v = 400;     //velocity
var i = [0,0];   //initial position
var o = 0;       //time offset
var fc = 6       //frame count (for spritesheet)

var f = (time+o) * v                  //function
var t = [i[0]+f, i[1]+f];             //time x/y
var d = thisLayer.sourceRectAtTime(); //dimensions
var s = transform.scale;              //scale
var lh = d.height*(s[0]/100);         //layer height
var tlw = d.width*(s[1]/100);         //true width
var lw = Math.floor(tlw/fc);          //layer width
var w = thisComp.width - lw;          //screen width
var h = thisComp.height - lh;         //screen height

// cycle count in x and y
var c = [Math.floor(t[0]/w), Math.floor(t[1]/h)];

var bc = (c[0]+c[1])%fc;   //bounce count

(bc/fc) * 100

Remember to match the variable fc for all the 3 (position, wipe 1, and wipe 2) expressions!
I know there are many steps to making this work, but i couldn't find any simpler ways to implement spritesheets.
If you have more experience in After Effects expressions please comment with an easier way to do this.

When does it perfectly loop?

Click this link for a CodePen with some javascript code that finds the next loop frame and a timestamp. You will need to manually put in your data points so it isn't perfect. Unfortunately i couldn't find an easy way to do this in After Effects because it crashes. If anyone knows a way to run a resource intensive expression once please share!

Enjoy the nostalgia

Now you have your very own bouncing logo effect, taste that sweet sweet nostalgia!.