Evaluate expression from within a script
Copy link to clipboard
Copied
I have a script that needs the value of this expression -
length(this_comp.layer("A").position, this_comp.layer("B").position);
How can I obtain the value of an expression from within a script ?
Copy link to clipboard
Copied
You can't on the plain expression, but you can of course convert everything to keyframes by invoking the respective menu command. That's a trick that in the past has been employed by several scripts - apply an expression, convert to keyframes, retrieve the keyframe values, delete keyframes if needed. The only caveat here is that eventually things may get too slow and the script may break or AE crashes attempting to actually draw the keyframes on teh timeline.
Mylenium
Copy link to clipboard
Copied
Is there an example for - apply an expression ? If I have a plugin with a dummy slider - I can apply the expression to the dummy slider and obtain the value.
Is that roughly what you are referring to ?
Copy link to clipboard
Copied
Typically you'd add the expression to a suitable property.expression, then read the value of that property.
For example, you have an A & B layer, also a Text layer with the Source Text property selected:
myProperty = app.project.activeItem.selectedProperties[0];
myProperty.expression = 'length(thisComp.layer("A").position, thisComp.layer("B").position);';
lengthResult = myProperty.value;
$.writeln(lengthResult.toString());
If you want more than just a static value then you'll need to loop through sampling each frame with valueAtTime().
I think it's only with certain expressions that took time to evaluate that you need to do things like Convert To Keyframes, but even that was supposedly addressed in CC 2014.
Also a quick google for "distance between 2 points javascript" will give you numerous examples you could just use directly in your script if you want to bypass the expressions.
var Apos = [3300,1124];
var Bpos = [1064,1208];
var result = 0;
for (var x=0; x< Apos.length; x++) {
result += Math.pow(Bpos[x]-Apos[x], 2);
}
result = Math.sqrt(result);
$.writeln("length = " + result);
Copy link to clipboard
Copied
Obtaining the distance is not the issue - the problem is that I wish to obtain certain vectors that are only available from expressions (per my knowledge).
For instance,
toWorld(anchorPoint)
thisComp.activeCamera.position
These are both unavailable in the script. Once these vectors are available, the distance can be evaluated.
Copy link to clipboard
Copied
Sure. That was just a bonus answer after explaining how to apply/sample expressions. In fact I would have encouraged the use of expressions if those spatial transforms had been the ones you mentioned.
Copy link to clipboard
Copied
I got the camera position in script via
app.project.activeItem.activeCamera.transform.position;
Is there a way to convert the position object to a string so it can be used for further processing and passed around ?
For example, I tried
app.project.activeItem.activeCamera.transform.position.toString() ;
- I got
[object Property]
Copy link to clipboard
Copied
The Position object? You mean the value? You access the value through .value or .valueAtTime(). I'm not really sure what you'd expect when converting the Position object into a string.
Position is a Property object as shown here with all its many attributes and methods:
Copy link to clipboard
Copied
Thank you -
app.project.activeItem.activeCamera.transform.position.value works for me. This supplies a comma delimited string
Copy link to clipboard
Copied
I've no idea of your level of scripting experience but generally speaking there aren't many reasons why you'd convert the value into a string (except maybe embedding in an expression or saving to a text file). I'm not sure what your definition of "so it can be used for further processing and passed around" is.
Otherwise you'd just store the value in a variable. It'll either be a single value or an array of values (if a multi-dimension property) so you might do something like:
myValue = app.project.activeItem.activeCamera.transform.position.value;
and then access each individual X, Y, etc component with myValue[0], myValue[1], etc, if you wanted to manipulate it before applying to another property:
myOtherProperty.setValue(myValue);

