Update: Oscillate is now a preset and part of Conigs Mixtape! Download it today!

There’s many occasions I just need a certain parameter in After Effects to go between two values. There’s several ways to do this (including keyframing), but one of the go-to methods is using the Math.sin() expression to get a nice sine wave. But for whatever reason, I always end up reminding myself the correct way to write out Math.sin( Math.PI * 2 * time * frequency ) * amplitude in my expression. I also wanted a bit more options. Sure cosine is easy (Math.cos()) but what about a triangle wave? Or Sawtooth?

So I wrote up a function to paste into an expression to give me many options. The image above shows some example usage, but here's the complete rundown…

oscillate("wave-type", frequency, amplitude, time)

"wave-type"

A string or integer defining the type of wave to produce. Why the option to use numbers? Maybe you want to use some other code to determine the type of wave. Using a number just makes that easier. In general use, the strings are just easier to remember.

  • "sin" or "sine" or 1 (default)
  • "cos" or "cosine" or 2
  • "square" or 3
  • "saw" or "sawtooth" or 4
  • "tri" or "triangle" or 5

frequency

Number of full waves per second. Defaults to 1.

amplitude

The height of the wave above or below 0. Defaults to 1.

time

The value to drive the wave. Defaults to time, but it could also use any other variable. Consider using the layer’s x position to drive the function on its y position.

Defaults

All the parameters are optional in the function. Using just oscillate() will give you a sine wave with a frequency and amplitude of 1 over time. Or fill in all the parameters to get exactly what you want. However, the parameters must be given in order. So if you just want to change the amplitude, you'll need to include the wave-type and frequency before it.

The Code

And finally, here’s the code. Paste this into your expression (usually at the end), and you can call oscillate() to get a nice oscillation.

/*
oscillate(wave-type, frequency, amplitude, time)

Returns value along time axis of different wave types or false if error.
All arguments are optional. Function defaults to Sine wave over time with frequency and amplitude of 1.
*/
function oscillate(w,f,a,t) {
    //Defaults
    if(!arguments[0]) w="sin";
    if(!arguments[1]) f=1;
    if(!arguments[2]) a=1;
    if(!arguments[3]) t=time;

    try {
        w=w.toString().toLowerCase();
        x=t*f;  

        switch(w){
            case "1": case "sin": case "sine":
                return Math.sin(2*Math.PI*x)*a;
            case "2": case "cos": case "cosine":
                return Math.cos(2*Math.PI*x)*a;
            case "3": case "square":
                return Math.floor(Math.sin(2*Math.PI*x))*a*2+a;
            case "4": case "saw": case "sawtooth":
                x=x*f+f/2;x<0?adj=a:adj=-a;
                return ((x%f)/f)*a*2+adj;
            case "5": case "tri": case "triangle":
                x=x*f-f/4;x<0?adj=a:adj=-a;
                return (Math.abs(((x%f)/f)*a*2+adj)-a/2)*2;
            default:
                return false;
        }
    } catch(e) {return false}
}