After Effects: The Modulo Operator (%)

Contents Introduction Looping Expressions Example: Digital Clock Example: Analog Clock Conclusion Introduction The Modulo operator (written %), aka the remainder operator, is a useful part of expression making that isn't immediately easy to understand. So what does it do, and what is it used for? % is used to work out the remainder of an equation. Here is an example: 10 % 3 In this example, the expression will return 1. This is because when you divide 10 by 3, you get 3 remainder 1. This is very useful for creating loops when used on the time variable. Looping Expressions Most designers starting out with After Effects expressions will know the loopOut() expression. This allows us to loop keyframes in our property, using "cycle" (looping back from start to finish), "pingpong" (looping from start - finish - then backwards to the start again), "offset" (repeating the keyframes but offsetting the values each time to build the animation), or "continue" (uses the velocity from the last keyframe to continue the motion). This is very comprehensive, and covers everything you could need while keyframing animation. But, if you want to loop an expression, loopOut isn't a viable solution. There could be a few reasons for not wanting to use keyframes, but the main reason is if a value needs to be dynamic, and constantly updated. It is much easier to update an expression attached to a slider, than a set of keyframes. If the motion is continuous, then Linear or Ease would work just fine. But for complex animations that require a loop, we can use the modulo operator against time to achieve that loop. To understand how it works, copy and paste this expression into a text layer's Source Text property: Math.floor(time % 5) You will see the layer counts from 0-4 each second, looping back to 0 on every 5 second interval. This is because, as time moves, the remainder of our expression will change each second: Remainders over time 1 % 5 = 1 2 % 5 = 2 3 % 5 = 3 4 % 5 = 4 5 % 5 = 0 The Math.floor addition rounds the argument to return only whole numbers. From here, it is easy to see how this can be employed when needing to animate numbers between certain parameters. Example: Digital Clock Let’s use % to make a digital clock. The seconds need to count between 0 - 60, meanwhile the minutes need to count up at each interval of 60. Let's paste this into our text layer's Source Text property again: sec = Math.floor(time % 60); minute = Math.floor(time / 60); if (sec < 10) sec = "0" + sec; minute + ":" + sec Breaking the expression down, our sec variable will count from 0 - 60, while the minute variable will increase on every multiple of 60 (again, we use Math.floor to round out the numbers). The if statement that follows adds a 0 to the front of the sec variable if it is less than 10, ensuring that our seconds variable always has 2 digits (which could also be repeated for the minutes if desired). Then, it is just a case of stringing it all together with a time separator. If you need the counter to work independently of time, you can achieve the same effect by swapping time out with a slider, and animating its value. You can also make the time separator blink, using the modulo operator and the After Effects text expression selector. Go to your text layer, and add an opacity animation option to your text layer (if you're not sure how to do this, you can check out this article all about it. Then add an expression selector, and remove the range selector. Set the opacity within the animator to 0, and then add this expression to the amount property: //Digital Clock Divider Blink //Add to the expression selector minute = Math.floor(time / 60); minute < 10 && textIndex == 2 ? Math.floor(time*2 % 1.5) * 100 : minute >= 10 && textIndex == 3 ? Math.floor(time*2 % 1.5) * 100 : 0; I have written a conditional statement, based on the number of digits within the minutes variable not being fixed. First, I copy the minute variable from my source text property. Then, I used it to calculate my time separator's textIndex value. When there is 1 digit in the minute display, it will equal 2. When the minute display is over 10, then it will be 3. The conditional statement can also be written as an if statement, like this, to explain further what it is doing: if (minute < 10 && textIndex == 2) Math.floor(time*2 % 1.5) * 100 else if (minute >= 10 && textIndex == 3) Math.floor(time*2 % 1.5) * 100 else 0 If the minutes are under 10 and the textIndexequals 2, then Math.floor(time*2 % 1.5) * 100 affects the 2nd character in the text layer. This will make the letter flash (to a ratio of 2:1 on:off) thanks to the modulo operator. The Math.floor argument rounds the numbers, while the whole thing is multiplied by 100 at the end to toggle between the numbers 0 and 100, the range of our expression selector. Howev

Jan 20, 2025 - 12:13
After Effects: The Modulo Operator (%)
Contents
Introduction
Looping Expressions
Example: Digital Clock
Example: Analog Clock
Conclusion

Introduction

The Modulo operator (written %), aka the remainder operator, is a useful part of expression making that isn't immediately easy to understand. So what does it do, and what is it used for?

% is used to work out the remainder of an equation. Here is an example:

10 % 3

In this example, the expression will return 1. This is because when you divide 10 by 3, you get 3 remainder 1.

This is very useful for creating loops when used on the time variable.

Looping Expressions

Most designers starting out with After Effects expressions will know the loopOut() expression. This allows us to loop keyframes in our property, using "cycle" (looping back from start to finish), "pingpong" (looping from start - finish - then backwards to the start again), "offset" (repeating the keyframes but offsetting the values each time to build the animation), or "continue" (uses the velocity from the last keyframe to continue the motion). This is very comprehensive, and covers everything you could need while keyframing animation.

But, if you want to loop an expression, loopOut isn't a viable solution. There could be a few reasons for not wanting to use keyframes, but the main reason is if a value needs to be dynamic, and constantly updated. It is much easier to update an expression attached to a slider, than a set of keyframes.

If the motion is continuous, then Linear or Ease would work just fine. But for complex animations that require a loop, we can use the modulo operator against time to achieve that loop.

To understand how it works, copy and paste this expression into a text layer's Source Text property:

Math.floor(time % 5)

You will see the layer counts from 0-4 each second, looping back to 0 on every 5 second interval. This is because, as time moves, the remainder of our expression will change each second:

Remainders over time
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0

The Math.floor addition rounds the argument to return only whole numbers.

Image description

From here, it is easy to see how this can be employed when needing to animate numbers between certain parameters.

Example: Digital Clock

Let’s use % to make a digital clock.

The seconds need to count between 0 - 60, meanwhile the minutes need to count up at each interval of 60. Let's paste this into our text layer's Source Text property again:

sec = Math.floor(time % 60);
minute = Math.floor(time / 60);

if (sec < 10) sec = "0" + sec;

minute + ":" + sec

Breaking the expression down, our sec variable will count from 0 - 60, while the minute variable will increase on every multiple of 60 (again, we use Math.floor to round out the numbers). The if statement that follows adds a 0 to the front of the sec variable if it is less than 10, ensuring that our seconds variable always has 2 digits (which could also be repeated for the minutes if desired). Then, it is just a case of stringing it all together with a time separator.

GIF of a clock counting up

If you need the counter to work independently of time, you can achieve the same effect by swapping time out with a slider, and animating its value.

You can also make the time separator blink, using the modulo operator and the After Effects text expression selector.

Go to your text layer, and add an opacity animation option to your text layer (if you're not sure how to do this, you can check out this article all about it. Then add an expression selector, and remove the range selector.

Screenshot of the text layer in the AE project with the new animator property

Set the opacity within the animator to 0, and then add this expression to the amount property:

//Digital Clock Divider Blink
//Add to the expression selector

minute = Math.floor(time / 60);

minute < 10 && textIndex == 2 ? Math.floor(time*2 % 1.5) * 100 : minute >= 10 && textIndex == 3 ? Math.floor(time*2 % 1.5) * 100 : 0;

I have written a conditional statement, based on the number of digits within the minutes variable not being fixed. First, I copy the minute variable from my source text property. Then, I used it to calculate my time separator's textIndex value. When there is 1 digit in the minute display, it will equal 2. When the minute display is over 10, then it will be 3. The conditional statement can also be written as an if statement, like this, to explain further what it is doing:

if (minute < 10 && textIndex == 2) Math.floor(time*2 % 1.5) * 100
    else if (minute >= 10 && textIndex == 3) Math.floor(time*2 % 1.5) * 100
        else 0

If the minutes are under 10 and the textIndexequals 2, then Math.floor(time*2 % 1.5) * 100 affects the 2nd character in the text layer. This will make the letter flash (to a ratio of 2:1 on:off) thanks to the modulo operator. The Math.floor argument rounds the numbers, while the whole thing is multiplied by 100 at the end to toggle between the numbers 0 and 100, the range of our expression selector.

However, if the minutes are equal to or above 10 and the textIndex equals 3, the effect will then be applied to the 3rd character in the text layer instead. This accounts for the extra digit in the minutes display. If your minutes display will need to go past 99, another argument will need to be added to affect the time separator when it is in the 4th position.

However, if your minutes display is set to a constant number of digits, the statement becomes much simpler:

dividerIndex = 3;
textIndex == dividerIndex ? Math.floor(time*2 % 1.5) * 100 : 0

GIF of a digital clock with blinking time divider

And with that, you have a digital clock!

After displaying how the modulo operator helps create loops, we can now think about how to apply this to other properties.

Example: Analog Clock

Let's now make an analog clock. When the hands tick, it usually isn't one continuous motion, but instead something which stops and starts abruptly. This is the kind of loop the modulo operator can help with.

Let's go through the following expression we can paste into the rotation property of a clock hand layer:

//Second Hand Rotation
frames = thisComp.frameDuration;

loopTime = 1;
dur = frames * 6;
strength = 6;

counter = Math.floor(time/loopTime);
t = time % loopTime;

ease(t, 0, dur, strength * counter, strength * (counter + 1))

First, we set some variables. frames is how long a frame in our composition lasts, making it able to work across multiple framerates.

Set loopTime to how much time you want to loop. I want the loop to last a second, so I set it to 1. dur is the duration of the animation within the loop, so I set mine to frames * 6, making it last for 6 frames. strength is the change in value of the animation, and since I'm animating a clock hand, I set mine to 6, so the clock hand will make a full rotation in 60 ticks.

Next, I make a counter variable, which will help offset my values. I create this with Math.floor(time/loopTime), rounding the number with Math.floor and setting the speed of the counter to match the loops. Lastly, t is the variable we can use to time our expression driven animation. This is time % loopTime, so the time loops whenever it reaches the number stored inside loopTime.

After that, we can make our animation. I'm using an ease expression in this example. By setting the first argument to t, we remap our rotation value to our loop time variable. The next 2 arguments are 0 and dur, the start and end points of the animation. The last 2 arguments are strength * counter and strength * (counter + 1), the value of our rotation property. By multiplying the strength by the counter, we can offset the values each loop, ending on strength * (counter + 1), ready for the next loop.

GIF 01 of animated analog clock with a second hand ticking

The advantage of powering the motion via expressions rather than keyframes in this instance would be if you need to build a clock template for constantly changing times. The static values of the expression can be connected to sliders, making it much easier to update constantly.

You could use a more advanced expression or build your own function to make more bespoke animation:

//Second Hand Rotation
frames = thisComp.frameDuration;

loopTime = 1;
dur = frames * 6;
change = 6;

counter = Math.floor(time/loopTime);
t = time % loopTime;

function easeInOutBack (t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
}

easeInOutBack(clamp(t, 0, dur), change * counter, change, dur)

GIF 02 of animated analog clock with a second hand ticking

Lastly, you could create a variable to set the start value and use an if statement to skip the first iteration of the animation for the minute (and possibly hour) hands:

//Minute Hand Rotation
frames = thisComp.frameDuration;

loopTime = 60;
dur = frames * 6;
strength = 6;
startValue = 180;

counter = Math.floor(time/loopTime);
t = time % loopTime;

function easeInOutBack (t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
}

if (time < loopTime) startValue
    else easeInOutBack(clamp(t, 0, dur), (strength * counter) + startValue, strength, dur)

GIF 03 of animated analog clock with a second and minute hand ticking

From here, it is just a case of connecting a slider to our startValue variable. From there, you have an analog clock that can be updated by simply changing the value in the slider.

Conclusion

The modulo operator is very useful for creating loops to aid dynamic expressions, where other means do not fit the project's needs.

Try testing it out in some of your own projects!

Have any comments? Something not adding up? Let me know down below.