ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Using sliders to change time of opacity shifts

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Luke McKinney
Using sliders to change time of opacity shifts
on Sep 20, 2019 at 5:37:20 pm

So I'm currently self learning expressions and a lot of what I've been able to pull off is by copy/pasting code and trying to modify it for my needs.
I have a pretty complex problem and have achieved results good enough for this one project but would love to create a template so I could repeat this easier in the future.
What is going on is I have 5 video layers. When triggered using a checkbox the top layer will shift from 100% opacity to 0%. The on and off times are determined with two sliders. I'm needing to change the "flicker" speed during the clip which is why I decided to build this all around sliders. I've built a ton of code into this thing and I'm really looking for 1 - a more elegant solution for this workflow and 2 - a code that won't leave opacity gaps in the composition since the only way I could figure this out is by referencing previous frames which doesn't always work when you shift the keyframes.
I know I probably haven't included enough information but any leads/help would be greatly appreciated.

Also, a disclaimer, I'm not 100% sure that all of this code is correct or even what a couple parts of it do.

//The code from the Main video layer named "PJ";
A = thisComp.layer("Master Controller").effect("Cycle in Seconds")("Slider");
B = thisComp.layer("Master Controller").effect("Frame Rate Adjusted")("Slider")*thisComp.frameDuration;

((time-inPoint)%A &lt;= B) ? 100 : ((thisComp.layer("Master Controller").effect("On / Off")("Checkbox")-1)*-100);

// This is the code from the video layers directly under "PJ";

frameRate = thisComp.layer("Master Controller").effect("Frame Rate")("Slider");
delay = (frameRate*(index-1))*thisComp.frameDuration;

thisComp.layer("PJ").transform.opacity.valueAtTime(time-delay);

//This is the code from the main slider driving the rest of the expressions on layer "Master Controller";

cycleRate = effect("Cycle in Seconds")("Slider");
frameRate = effect("Frame Rate")("Slider");
frameDur = frameRate * thisComp.frameDuration;
nearKey = effect("Frame Rate")("Slider").nearestKey(time).index;
lastKey = (frameRate.key(nearKey).time>time) ? ((nearKey>1) ? nearKey-1 : nearKey) : nearKey;
prevKey = frameRate.key(lastKey).index-1;
FG = effect("ForeGround Layers")("Slider");
if
((frameRate.key(lastKey).index == frameRate.key(nearKey).index) && (time - frameRate.key(lastKey).time &lt;= cycleRate) && (frameRate.key(prevKey).value > frameRate.key(lastKey).value)) //if lowering frame rate
{
frameRate.value;
thisComp.layer("PJ").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Mike").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Cody").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Matt").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Rob").transform.opacity.valueAtTime(time+(index-FG)) = 100;
}
else if
((frameRate.key(nearKey).time - time &lt;= cycleRate) && (frameRate.key(nearKey).value &lt; frameRate.key(lastKey).value)) // if raising frame rate
{
frameRate.value;

thisComp.layer("PJ").transform.opacity.valueAtTime(time) = 100;
thisComp.layer("Mike").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Cody").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Matt").transform.opacity.valueAtTime(time+(index-FG)) = 100;
thisComp.layer("Rob").transform.opacity.valueAtTime(time+(index-FG)) = 100;
}
else {
frameRate.value;
}

// There's a slider for ForeGround elements ( a couple scenes are green screened);
if (thisComp.layer("PJ").index == 1)
{
0;
}
else
{
thisComp.layer("PJ").index - 1;
}
Math.floor(value);

//and this is the cycle expression that auto populates this slider based off of the comp;
(effect("Frame Rate")("Slider")*(index-1-effect("ForeGround Layers")("Slider")))*thisComp.frameDuration;


Return to posts index

Andrei Popa
Re: Using sliders to change time of opacity shifts
on Sep 21, 2019 at 7:42:47 am

Is this like a loading animation that accelerates or something?

What i understand you want to do:
Layer one becomes invisible when meets the checkbox. Other 4 layers follow at a given delay(your frameRate). You want to modify this framerate over the time? You also want to modify the cycle time to fit the new "frameRate"?

Am I correct in my assuptions?

Andrei
My Envato portfolio.


Return to posts index

Luke McKinney
Re: Using sliders to change time of opacity shifts
on Sep 21, 2019 at 5:15:49 pm

Your assumptions seem to be correct! I'll include some more info here to try to help clarify everything.

This is creating a replacement animation effect using video rather than shooting stills frame by frame. The effect is an allegory for the character's emotional state so we need to be able to speed up and slow down the speed of the effect, which is why I'm trying to keyframe the frame rate slider.

Ideally, the keyframes would auto-move to the end of a cycle before changing to the new frameRate.

Thanks for trying to decipher both my code and my concept!!!



13736_screenshot20190921at12.03.01pm.png.zip

13735_screenshot20190921at12.04.09pm.png.zip


Return to posts index


Andrei Popa
Re: Using sliders to change time of opacity shifts
on Sep 21, 2019 at 8:55:58 pm

Hey. I'm not at the office until monday morning CET and I don't have After Effects at home.
I'll try to make something work then and reply, in case anyone else does not do it before me :D

Andrei
My Envato portfolio.


Return to posts index

Luke McKinney
Re: Using sliders to change time of opacity shifts
on Sep 22, 2019 at 3:23:37 am

Thank you!


Return to posts index

Andrei Popa
Re: Using sliders to change time of opacity shifts
on Sep 23, 2019 at 8:26:17 am

This has been way harder than i first imagined 😃

You need 3 sliders on your control layer: Forground layers, Duration and Number of layers.
Add this expression to opacity to each of the layers:
layersNumber = thisComp.layer("Control Layer").effect("Layers Number")("Slider");
forGroundLayers = thisComp.layer("Control Layer").effect("Foreground Layers")("Slider");
dur = thisComp.layer("Control Layer").effect("Duration")("Slider");//Duration for the animation

function extractCycles(myDur){
cycleValues = [inPoint];
for (var i=1; i<=myDur.numKeys; i++){
cycleValues.push(cycleValues[i-1] + myDur.key(i).value * layersNumber);
}
if (myDur.numKeys == 0) var cycleValues = myDur.value;
return cycleValues;
}

cycleStarts = extractCycles(dur);
lastCycleEnd = cycleStarts[cycleStarts.length-1];
myIndex = index-1-forGroundLayers;

if (dur.numKeys>0){
if (time < lastCycleEnd){
//Check to see in which cycle we fit
var i = cycleStarts.length-1;
while(cycleStarts[i] > time && i!=0){
i--;
}
cycleLength = cycleStarts[i+1]-cycleStarts[i];
thisDuration = cycleLength/layersNumber;
(((time-cycleStarts[i]-myIndex*thisDuration) % cycleLength) <= thisDuration) ? 100 : 0;

}else{
//Continuously loops with the last duration
(((time-lastCycleEnd-myIndex*dur.key(dur.numKeys).value) % (dur.key(dur.numKeys).value*layersNumber)) <= dur.key(dur.numKeys).value) ? 100 : 0;
}
}else{
((time-inPoint-myIndex*dur) % (dur*layersNumber) <= dur) ? 100 : 0;
}


Andrei
My Envato portfolio.


Return to posts index


Luke McKinney
Re: Using sliders to change time of opacity shifts
on Sep 24, 2019 at 2:41:26 pm

It works a lot more cleanly than what I came up with!!!! Thank you so much!!!

I can't find anything in the expressions manual I downloaded on cycles or variables. Do you know of any good resources for learning about this. Just trying to avoid having to bother you for help again. Thanks!


Return to posts index

Andrei Popa
Re: Using sliders to change time of opacity shifts
on Sep 23, 2019 at 8:32:58 am

This has been a bit more difficult than i first imagined.

You need to create a control layer with 3 sliders: Duration, Forground layers, Layers numbers.

The expression takes one value from duration keyframes as the duration of the animation for each cycle. Ex: Duration has 3 keyframes:1,2,3. The first 3 cycles will have the duration of the animation 1,2 respectively 3. It does not matter where the keyframes are in time. After 3 cycles, the animation continues with the last duration for all the folowing cycles.

If no keyframe is present in Duration slider, it will take its value and create cycles with that.

You need to add this exression to the opacity of your layers:

layersNumber = thisComp.layer("Control Layer").effect("Layers Number")("Slider");
forGroundLayers = thisComp.layer("Control Layer").effect("Foreground Layers")("Slider");
dur = thisComp.layer("Control Layer").effect("Duration")("Slider");//Duration for the animation

function extractCycles(myDur){
cycleValues = [inPoint];
for (var i=1; i<=myDur.numKeys; i++){
cycleValues.push(cycleValues[i-1] + myDur.key(i).value * layersNumber);
}
if (myDur.numKeys == 0) var cycleValues = myDur.value;
return cycleValues;
}

cycleStarts = extractCycles(dur);
lastCycleEnd = cycleStarts[cycleStarts.length-1];
myIndex = index-1-forGroundLayers;

if (dur.numKeys>0){
if (time < lastCycleEnd){
//Check to see in which cycle we fit
var i = cycleStarts.length-1;
while(cycleStarts[i] > time && i!=0){
i--;
}
cycleLength = cycleStarts[i+1]-cycleStarts[i];
thisDuration = cycleLength/layersNumber;
(((time-cycleStarts[i]-myIndex*thisDuration) % cycleLength) <= thisDuration) ? 100 : 0;

}else{
//Continuously loops with the last duration
(((time-lastCycleEnd-myIndex*dur.key(dur.numKeys).value) % (dur.key(dur.numKeys).value*layersNumber)) <= dur.key(dur.numKeys).value) ? 100 : 0;
}
}else{
((time-inPoint-myIndex*dur) % (dur*layersNumber) <= dur) ? 100 : 0;
}


And here is the aep project

Andrei
My Envato portfolio.


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2019 CreativeCOW.net All Rights Reserved
[TOP]