Highlighted

How to edit / update a path or mask using expressions?

Community Beginner ,
Sep 12, 2020

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) ]

TOPICS
Expressions, How to, Scripting

Views

73

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

How to edit / update a path or mask using expressions?

Community Beginner ,
Sep 12, 2020

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) ]

TOPICS
Expressions, How to, Scripting

Views

74

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 12, 2020 0
Adobe Community Professional ,
Sep 12, 2020

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).

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 12, 2020 0
Community Beginner ,
Sep 20, 2020

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
	}

}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 20, 2020 0
Adobe Community Professional ,
Sep 20, 2020

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]);
}

 

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 20, 2020 1
Community Beginner ,
Sep 20, 2020

Copy link to clipboard

Copied

Makes a lot of sense, thanks for pointing that out! 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 20, 2020 0