On and off
expression

Math.floor(timeToFrames(time)/10)%2 ? 0 : 100

Undulations

Apply the following expression to the position property of an object:

xAmp = 3; //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]

Apply this expression to the rotation porperty:

xFreq = .3; //undulations per second
xSpeed = 150; //speed of wave (pixels per second)
damping = 15; //undulation damping factor

wl = xSpeed/xFreq; //wavelength (pixels)
phaseOffset = ((position[0]%wl)/wl)*2*Math.PI;
theta = Math.atan(Math.cos(2*Math.PI*xFreq*time + phaseOffset));
radiansToDegrees(theta)/damping;

Rotation Inertial

let amp = 2.0; //Sets the angle that the layer will rotate on the spring animation
let freq = 2.0; //Sets the velocity that the spring animation will have
let decay = 4.0; //How long the spring animation lasts
let rotateOnMovement = 42; //Maximum angle that the layer will rotate when it's moving
let useAxis = 0; // 0 will use the speed of the X axis and 1 will use the speed of the Y axis
let timeBeforeKey = thisComp.frameDuration/10;
let refValue = position;

if (refValue.velocity[useAxis] != 0) {
	linear(refValue.velocity[useAxis], -3000, 3000, -rotateOnMovement, rotateOnMovement);
} else {
	let n = 0;
	if (refValue.numKeys > 0) {
		n = refValue.nearestKey(time).index;
		if (refValue.key(n).time > time) { n--; }
	}
	if (n == 0) {
		t = 0;
	} else {
		t = time - refValue.key(n).time;
	}
	if (n > 0 && t < 1) {
		let v = refValue.velocityAtTime(refValue.key(n).time - timeBeforeKey)[useAxis];
		value - (v*(amp/100)*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t));
	} else {
		value;
	}
}

Inertial Bounce

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 = 4.0;
decay = 8.0;
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{
value;
}

Bounce Back

e = .7;
g = 5000;
nMax = 9;

n = 0;
if (numKeys > 0){
  n = nearestKey(time).index;
  if (key(n).time > time) n--;
}
if (n > 0){
  t = time - key(n).time;
  v = -velocityAtTime(key(n).time - .001)*e;
  vl = length(v);
  if (value instanceof Array){
    vu = (vl > 0) ? normalize(v) : [0,0,0];
  }else{
    vu = (v < 0) ? -1 : 1;
  }
  tCur = 0;
  segDur = 2*vl/g;
  tNext = segDur;
  nb = 1; // number of bounces
  while (tNext < t && nb <= nMax){
    vl *= e;
    segDur *= e;
    tCur = tNext;
    tNext += segDur;
    nb++
  }
  if(nb <= nMax){
    delta = t - tCur;
    value +  vu*delta*(vl - g*delta/2);
  }else{
    value
  }
}else
  value