Copy link to clipboard
Copied
// Get the speed value from the text layer
var speed = thisComp.layer("<empty text layer>").text.sourceText;
// Get the value from the "Black Solid 2 | Fractal Noise" effect
var currentValue = thisComp.layer("C | Connector").effect("Black Solid 2 | Fractal Noise")("Connector").value;
// Check if the speed value is negative
if (speed < 0) {
// If yes, increase the effect value by 25 until it reaches 100
if (currentValue < 100) {
currentValue += 25;
}
} else {
// If the speed value is not negative, decrease the effect value by 25 until it reaches 0
if (currentValue > 0) {
currentValue -= 25;
}
}
// Return the current value
currentValue;
The main idea of the expression is to dynamically adjust the value of an effect based on the value of a text layer. The expression:
This allows you to create animations that respond to changes in the text layer, such as changing the speed of an animation based on a user input.
However, it doesn't work as I want. For some reason, the value stops when it reaches 25, on the first frame of the negative speed, and does not reach 100 on the next 3 frames. When speed is no longer negative, the effect value becomes 0, meaning the expression reacts to speed, but not exactly as expected.
That is, I want if the speed value is negative, the effect value becomes 100 within 4 frames, and gradually decreases in the same way if the speed is not negative
Thank you in advance!
I think the issue you're running into is that expressions have no memeory and therefor have no access to previous values calculated by that expression. So any references to .value() and .valueAtTime() for that property (the one with the expression) will only return pre-expressions values (as if the expression didn't exist). However, you can usually achieve the result you're after by looping through all previous frames with valueAtTime() to re-calculate everything that has occured in the past. It
...Copy link to clipboard
Copied
I think the issue you're running into is that expressions have no memeory and therefor have no access to previous values calculated by that expression. So any references to .value() and .valueAtTime() for that property (the one with the expression) will only return pre-expressions values (as if the expression didn't exist). However, you can usually achieve the result you're after by looping through all previous frames with valueAtTime() to re-calculate everything that has occured in the past. It can be calculation-intensive, especially if your comp is long, because the expression has to do more and more work at each successive frame. This is an example (for a case similar to yours):
spd = thisComp.layer("<empty text layer>").text.sourceText;
fCur = timeToFrames(time);
f = 0;
val = valueAtTime(0);
while (f <= fCur){
t = framesToTime(f);
val += (parseFloat(spd.valueAtTime(t)) >= 0 ? -25 : 25);
f++;
}
val
Copy link to clipboard
Copied
spd = thisComp.layer("<empty text layer>").text.sourceText;
fCur = timeToFrames(time);
f = 0;
val = valueAtTime(0);
while (f <= fCur){
t = framesToTime(f);
val += (parseFloat(spd.valueAtTime(t)) >= 0 ? -25 : 25);
val = Math.max(0, Math.min(val, 100));
f++;
}
val;
In the original code, the value val was being incremented or decremented by 25 based on the source text. However, there was no limit set for val, so it could potentially go below 0 or above 100. In the modified code, I added a line val = Math.max(0, Math.min(val, 100)); to limit the value of val between 0 and 100. This line of code ensures that if val is less than 0, it will be set to 0, and if val is more than 100, it will be set to 100. This way, val will always stay within the range of 0 to 100.
Thank you very much
P.S.
I think the issue you're running into is that expressions have no memeory and therefor have no access to previous values calculated by that expression. So any references to .value() and .valueAtTime() for that property (the one with the expression) will only return pre-expressions values (as if the expression didn't exist).
By @Dan Ebberts
But the current value of the effect can be obtained. If you use somelayer.valueAtTime(time) with time*60 you will get the correct value. I don't quite understand. Or is it impossible to perform any manipulations with this obtained value?
Copy link to clipboard
Copied
It is a little confusing. When an expression is referring to its host property's own value, using .value() or .valueAtTime(), it always gets the pre-expression value. However, when an expression refers to any other property, .value() and .valueAtTime() always return that property's post-expression value. So an expression can access the result of any other property's expression, just not its own.