Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
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)
Copy link to clipboard
Copied
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]);
}