Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How to loop an expression in After Effects?

New Here ,
Mar 07, 2022 Mar 07, 2022

I've got a simple expression to ease between two colors on a rectangle. How can I get this expression to loop repeatedly? I know that to use the loop() function, I need to have keyframes set, but I want to make multiple copies of this layer that all have random offsets and colors. Is there maybe a better way to accomplish this? I've attached my code below.

 

var colors = ["E6E8BF", "DDDA00", "F27900", "DD1D00"];
var rgbColor1 = hexToRgb(colors[effect("Color 1")("Slider").value]);
var rgbColor2 = hexToRgb(colors[effect("Color 2")("Slider").value]);
ease(time, 3, 4, rgbColor1, rgbColor2);

 

 

TOPICS
Expressions , Scripting
1.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 07, 2022 Mar 07, 2022

You can divide time into segments using a modulus (time % 5 or whatever) and then play around with running it back and forth or simply calculate segement ID. If a segement is an odd multiple (1,3,5 etc.) it plays forward, if it's even it plays backwards. This can again easily be figured out using a modulus of 2 (% 2). Ultimately the code for the time calculations could be something like that:

 

mDur=5;

mID=Math.floor(time/mDur)+1;

 

tStart=mID*mDur;

tEnd=(mID+1)*mDur;

 

if (mID % 2 == 0)

{ease(time,tStart,tEnd,colorA,colorB}

else

{ease(time,tEnd,tStart,colorA,colorB};

 

Mylenium

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 01, 2022 Jun 01, 2022

It's been a while, but I did eventually figure it out. I've done my best to comment and explain code in the files. There's also a file with the final comp attached. Hope this helps someone!

 

Setup

  • 3x Slider effects
    • Color 1 (an integer from 0 to 3)
    • Color 2 (a second (unique) integer from 0 to 3)
    • Duration (a float between 0.4 and 1) (other values tended to break the expression, not sure why)

 

Expressions

For Fill Color:

/* color variables */

//array of colors to choose from
var colors = ["E6E8BF", "DDDA00", "F27900", "DD1D00"];
//the two values pulled from the slider values. converts each of the slider values (int 0-3) to an rgb color value.
var colorA = hexToRgb(colors[effect("Color 1")("Slider").value]);
var colorB = hexToRgb(colors[effect("Color 2")("Slider").value]);

/*time variables*/

//pulls duration of each "segment" from slider
var segmentDuration = effect("Duration")("Slider").value;
//for each time value, compute the associated segment number (id)
var segmentId = Math.floor(time/segmentDuration);
//find segment id at time = 3 (the time this particular animation starts. adjust to your needs)
var segmentIdThree = Math.ceil(3/segmentDuration);
//start and end times for the current segment
var tStart = segmentId * segmentDuration;
var tEnd = (segmentId + 1) * segmentDuration;

//check if segment start time is greater than beginning of animation
if (tStart > 3) {
    //double check segment id to make sure we aren't in the middle of a segment that begins before time = 3
	if (segmentId >= segmentIdThree) {
        //depending on the alignment of the segments with the start time, either animate from A to B or B to A.
        if ((segmentIdThree + 1) % 2 == 0) {
            if (segmentId % 2 !== 0) {
				ease(time, tStart, tEnd, colorA, colorB);
			} else {
				ease(time, tStart, tEnd, colorB, colorA);
			}
        } else {
            if (segmentId % 2 == 0) {
				ease(time, tStart, tEnd, colorA, colorB);
			} else {
				ease(time, tStart, tEnd, colorB, colorA);
			}
        }
    //set to colorA if start time is greater than 3 but the next full segment has not started yet
    } else {
        colorA;
    }
//set to colorA before animation start time
} else {
    colorA;
}

 

For Color 1 slider:

//pick a random number from seed and don't change with time
seedRandom(10843929 + thisLayer.index, true)
//pick an integer 0-3
Math.floor(random() * 4)

 

For Color 2 slider:

//pick a random number from seed and don't change with time
seedRandom(129338 + thisLayer.index, true)
//first try int 0-3
var randOne = Math.floor(random() * 4);

//if value of first try int is equal to color 1's int, offset by random amount depending on value (don't want to index out of bounds)
if (effect("Color 1")("Slider").value == randOne) {
	if (randOne == 3) {
		randOne - 2;
	} else if (randOne == 0) {
		randOne + 1;
	} else {
		randOne + 1
	}
//otherwise, return the original pick
} else {
	randOne;
}

 

For Duration slider:

//pick a random number from seed and don't change with time
seedRandom(4957313 + thisLayer.index, true)
//pick a float 0.4-1
random(0.4, 1)

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 14, 2022 Oct 14, 2022
LATEST

This is OP on a different account (I no longer have access to the original account), but I wanted to also add this expression that I wrote based off Mylenium's answer for pulsing a circle on beat with the music.

 

I used a BPM to ms calculator here to calculate the time between each beat (in this case, 0.444ms) and aligned the first beat exactly with the beginning of the project.

 

// set segment duration
segmentDuration = 0.444;
segmentId = Math.floor(time/segmentDuration);
// length of pulse (how long until it returns to 100% [0.1 worked well for my use])
length = effect("Length")("Slider").value;

// set start time based on segmentId
tStart = segmentId * segmentDuration;

// if segment is multiple of 4 or 0, be larger, otherwise pulse 50%
if (segmentId % 4 == 0 || segmentId == 0) {
    easeOut(time, tStart, tStart + length, [175, 175], [100, 100]);
} else {
    easeOut(time, tStart, tStart + length, [150, 150], [100, 100]);
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines