Activity › Forums › Adobe After Effects Expressions › parenting expression
-
parenting expression
Posted by John Baker on February 18, 2013 at 7:54 pmi have not found an answer anywhere to my question so i will ask here –
can someone give me an expression that does exactly the same thing that parenting does, [in terms of position]?
i am only concerned with POSITION for the moment …
i want to apply it to things that you normally cannot parent [like an effect] … i also want to use this as a building block to build other expressions ….
i want to apply this expression to the position point of an EFFECT – say the effect is “ramp” … and i would apply this expression to “start of ramp” and parent this point to another layers position [say a layer of text] … OR i would apply this expression to the emitter position of a particle system
keep in mind what i am asking … when you parent a layer to another layer that layer does not assume the exact position as the other layer – it moves in RELATION to the other layer …. when one layer moves 10 pixels the other layer maintains its relative position but moves 10 pixels as well
i thank you in advance
Dan Ebberts replied 3 years, 3 months ago 8 Members · 23 Replies -
23 Replies
-
Nate Mulliken
February 18, 2013 at 8:48 pmPerhaps this may help. not sur eif this is what your looking to do.
I made a comp with a solid. Put on the ramp effect on the solid.
Precomped the solid with the effect, moving everything into the precomp.Then I made a null next to that precomp. In the null I set a position keyframe so the null moved from top to bottom.
If you drag out the tab of the precomp so you have two timelines open at once you can scroll open the positon of the null and the effect controls for the ramp effect.
Alt click on the start ramp position and pickwhip to the null position.
It’ll write an expression that makes the ramp move with the position of the null.
-
Dan Ebberts
February 18, 2013 at 10:43 pmI think you’re looking for something like this:
myParent = thisComp.layer(“Null 1”);
myProp = myParent.transform.position;
value + (myProp.value – myProp.valueAtTime(0))You need to set a reference so the expression can calculate how far the “parent” layer has moved. Usually, the parent’s position at time 0 works.
Dan
-
Josh Johnson
December 4, 2013 at 7:20 pmHi there Dan,
I found this thread after a few failed attempts at making an expression that can switch the parent.
So I am messing around with this expression on the position property. I am wondering if this can even work.What I need is an expression that can hold the altered position value after the layer is “switched”.
I am using a slider with hold keyframes to jump through index of my layers.
Currently the “child layer” jumps when I keyframe to the next layer.I actually have several problems with the current expression but I feel if I can get past this hurdle I will be well on my way.
I hope you can help.
Thanks,
– Joshpicker = Math.round(effect("IndexSelector")("Slider"));nearSldrKey = effect("IndexSelector")("Slider").nearestKey(time);
sldrSub = nearSldrKey.index-1;
if (nearSldrKey.time >= time){
// catch weird error
if (sldrSub==0){
recentKey = effect("IndexSelector")("Slider").key(nearSldrKey.index);
} else {
recentKey = effect("IndexSelector")("Slider").key(sldrSub);
}
} else {
recentKey = effect("IndexSelector")("Slider").key(nearSldrKey.index);
}pos = thisComp.layer(picker).transform.position.valueAtTime(recentKey.time-0.001);
prntPos = thisComp.layer(picker).transform.position;
origionalPos = valueAtTime(recentKey.time);
posDiff = origionalPos-pos;
newPos = posDiff+prntPos;[newPos[0],newPos[1]]
-
Dan Ebberts
December 5, 2013 at 1:30 amIt’s a little complicated. You need to set up a loop that starts at time zero and loops through all past keyframes of the picker slider to figure out where the child was at the beginning (and end) of each keyframed interval. That is, where the layer started initially, where it ended at then end of the segment with the first parent, where it was at the end of the segment with the second parent, etc. until finally, where it should be now, relative to the current parent.
Not too tough, but not trivial.
Dan
-
Josh Johnson
December 5, 2013 at 5:19 amThank You! This makes total sense.
But also, ugh. Ok brains here we go.
Thanks for looking at it. I will update as soon as I have something.
-
Josh Johnson
December 11, 2013 at 2:27 pmThanks again Dan!
It totally worked. This is what I came up with.Totally useful for me. Buddy thought it was useful as well. Prolly gonna save this out as a preset and post it on my site. I will of course credit you for the help.
– Josh
//// LILSMOKIES PARENT SWAP /////* Should you wish to have an expression
before applying the parent expression
plug the result into the orgValue. */orgValue = position;
// method chooser
chkBox = effect("Select Relative to Original")("Checkbox");
if (chkBox==true) {
Sldr = effect("Select Relative")("Slider");
if (Sldr.numKeys > 0) {
ValueHOLD ();
main (index, orgValue);
} else {
position;
}
} else {
Sldr = effect("Select by Index")("Slider");
if (Sldr.numKeys > 0) {
ValueHOLD ();
main (0, orgValue);
} else {
position;
}
}function ValueHOLD () {
nearSldrKey = Sldr.nearestKey(time);
sldrSub = nearSldrKey.index-1;
if (nearSldrKey.time > time){
// catch weird error
if (sldrSub==0){
recentKey = Sldr.key(nearSldrKey.index);
} else {
recentKey = Sldr.key(sldrSub);
}
} else {
recentKey = Sldr.key(nearSldrKey.index);
}
return recentKey;
}function main(childINDX, posVALUE) {
// need to create a loop
// fix first pass//orgValue = valueAtTime(time);
newPos = posVALUE;
for (i=1;i<=recentKey.index;i++) {
sldrKey = Sldr.key(i);
if (i > 1) {
preSldrKey = Sldr.key(i-1);
prntEnd = thisComp.layer(childINDX+preSldrKey.value).transform.position.valueAtTime(sldrKey.time);
if (thisComp.layer(childINDX+preSldrKey.value).index == thisLayer.index) {
prntEnd = thisComp.layer(childINDX+preSldrKey.value).transform.position.valueAtTime(0);
}
newPos = posDiff+prntEnd;
// previous key first then current key
prntStart = thisComp.layer(childINDX+sldrKey.value).transform.position.valueAtTime(sldrKey.time);
if (thisComp.layer(childINDX+sldrKey.value).index == thisLayer.index) {
prntStart = thisComp.layer(childINDX+sldrKey.value).transform.position.valueAtTime(0);
}
posDiff = newPos-prntStart;
newPos = posDiff+prntStart;
} else if (thisComp.layer(childINDX+sldrKey.value).index == thisLayer.index) {
prntStart = thisComp.layer(childINDX+sldrKey.value).transform.position.valueAtTime(0);
var posDiff = newPos-prntStart;
newPos = posDiff+prntStart;
}else {
prntStart = thisComp.layer(childINDX+sldrKey.value).transform.position.valueAtTime(sldrKey.time);
var posDiff = newPos-prntStart;
newPos = posDiff+prntStart;}
}prntPos = thisComp.layer(childINDX+recentKey.value).transform.position;
if (thisComp.layer(childINDX+recentKey.value).index == thisLayer.index) {
prntPos = thisComp.layer(childINDX+recentKey.value).transform.position.valueAtTime(0);
}
activPos = posDiff+prntPos;if (position.value.length==3) {
return [activPos[0],activPos[1],activPos[2]]
//return [activPos[0],activPos[1],posDiff[0]]
} else {
return [activPos[0],activPos[1]]
}
} -
Tim Hildebrandt
September 2, 2014 at 9:47 amHello Dan,
with your expression you helped me a lot, this was exactly what I was looking for.
So I have an example animation of one square and one circle.
The square is moving from the left to the right:
Then down a little bit:
Then it goes back and the circle is coming with the square:
If the checkbox is ticked then the circle is moving with the square’s position (like in your expression). I just changed the point from when it is starting to move with the quare with a slider control (“Start”).
Now I want the circle to stop on that current position where it is now. And this I want to determine with the second slider control (“End”).
Has to be something like
if(time>End)
{
STAY AT YOUR CURRENT FCKNG POSITION!!!
}
else
{
I WILL KILL YOU
}haha
So. The first part is done. How to stop that whole thing?
This is the code I used (translated in english for you):
myParent = thisComp.layer("Square");
myProp = myParent.transform.position;
Box = thisComp.layer("Adjustment Layer 1").effect("Checkbox")("Checkbox");
Start = thisComp.layer("Adjustment Layer 1").effect("Start")("Slider control");
End = thisComp.layer("Adjustment Layer 1").effect("End")("Slider control");if(time>Start && Box==1)
{
value + (myProp.value - myProp.valueAtTime(Start))
}
else
{
value
} -
Dan Ebberts
September 2, 2014 at 6:09 pmThis worked for me:
myParent = thisComp.layer("Square");
myProp = myParent.transform.position;
Box = thisComp.layer("Adjustment Layer 1").effect("Checkbox")("Checkbox");
Start = thisComp.layer("Adjustment Layer 1").effect("Start")("Slider");
End = thisComp.layer("Adjustment Layer 1").effect("End")("Slider");
if(time>Start && time <= End && Box==1) {
value + (myProp.value - myProp.valueAtTime(Start))
}else if (time > End){
value + (myProp.valueAtTime(End) - myProp.valueAtTime(Start))
} else {
value
}
Although, I’m not sure why you need the checkbox with the sliders (or vice versa).
-
Tim Hildebrandt
September 2, 2014 at 6:39 pmThank you a lot. I will test it in few minutes. I want to create a template and the user should get the option to do this. And not with a square and a circle, of course not 😉
Reply to this Discussion! Login or Sign Up




