Copy link to clipboard
Copied
I'm trying to use expressions to manipulate a mask (path object). I've read the documentation, but I'm hitting a brick wall.
At each frame, I can read the existing points, and I can create an array of the new points I'd like to change them to, but I can't seem to either manipulate the existing points, nor create a new path that I can apply.
In fact, I can't get the .createPath method to do anything at all... does anybody have a simple example?
And / or any other examples of successfully manipulating / moving points in successive frames usings variables?
Thanks!
[Update: of course, I found out how to do it five minutes later... if anybody else is struggling: after you've done all your calculations, just put:
createPath(newPoints)
as the final line of the expressions on the mask layer, or with tangents:
createPath(newPoints, newInTangents, newOutTangents, true) ]
Copy link to clipboard
Copied
Great to hear that you could solve it already.
If you look for inspiration, the path bundle of my extension iExpressions contains all kinds of expressions on paths (but their source code is not readable).
Copy link to clipboard
Copied
I can no longer seem to edit my question, but here's the working code example. It looks at a Template composition, and copies the mask at the time indicated by a Scene selector. If the mask in an upcoming scene is different, then it extrapolates the intervening points of the mask shape across the chosen transition period. It's slow to run! Any tips on optimization welcome.
sceneTransition = thisComp.layer("Expression layer").effect("Transition")("Slider");
templateMask = comp("Template").layer("speaker1.jpg").mask("Mask 1").path;
sceneNow = thisComp.layer("Expression layer").effect("Scene")("Slider");
if (sceneTransition == 0) {
// transition not enabled
templateMask.valueAtTime(sceneNow) //end
}
else { //transitions are enabled
sceneNext = thisComp.layer("Expression layer").effect("Scene")("Slider").nearestKey(time);
fadeCalc = (time - sceneNext.time + sceneTransition) / sceneTransition; // negative if before transition, linear value between 0 and 1 during transition, greater than one after new keyframe
if (fadeCalc < 0 || fadeCalc >1) {
//we're NOT in a transition zone
templateMask.valueAtTime(sceneNow) // end
}
else { //we're in a transition zone so we have to move each point in the mask to a point along the transition path
myPoints = [];
myInTangents =[];
myOutTangents = [];
for (i = 0; i < templateMask.points(time).length; i++) {
myPoints[i] = ease(
fadeCalc,
templateMask.points(sceneNow)[i],
templateMask.points(sceneNext)[i]);
myInTangents[i] = ease(
fadeCalc,templateMask.
inTangents(sceneNow)[i],
templateMask.inTangents(sceneNext)[i]);
myOutTangents[i] =ease(
fadeCalc,templateMask.outTangents(sceneNow)[i],
templateMask.outTangents(sceneNext)[i]);
}
createPath(myPoints, myInTangents, myOutTangents) //end
}
}
,
Copy link to clipboard
Copied
Try to minimize API calls.Instead of calling templateMask.points etc again and again inside your for loop, just call it as often as needed before the loop and reuse the result (because this call is slow).
// save those for later use...
var templateMask_points_time = templateMask.points(time);
var templateMask_points_sceneNow = templateMask.points(sceneNow);
var templateMask_points_sceneNext = templateMask.points(sceneNext);
var templateMask_inTangents_sceneNow = templateMask.inTangents(sceneNow);
var templateMask_inTangents_sceneNext = templateMask.inTangents(sceneNext);
var templateMask_outTangents_sceneNow = templateMask.outTangents(sceneNow);
var templateMask_outTangents_sceneNext = templateMask.outTangents(sceneNext);
for (i = 0; i < templateMask_points_time.length; i++) {
myPoints[i] = ease(
fadeCalc,
templateMask_points_sceneNow[i],
templateMask_points_sceneNext[i]);
myInTangents[i] = ease(
fadeCalc, templateMask_inTangents_sceneNow[i],
templateMask_inTangents_sceneNext[i]);
myOutTangents[i] = ease(
fadeCalc, templateMask_outTangents_sceneNow[i],
templateMask_outTangents_sceneNext[i]);
}
Copy link to clipboard
Copied
Makes a lot of sense, thanks for pointing that out!