• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers

Advanced AfterEffects Question: Keyframe-able Dropdown?

Participant ,
Jul 13, 2022 Jul 13, 2022

Copy link to clipboard

Copied

Greetings all,

 

I'm looking to try to simplify something I typically do in AfterEffects by hand that's extremely tedious. Basically, I want to try to create a key-frame-able dropdown. Here's the scenario:

One of the motion graphic effects that I use for my podcast is movable talent windows (kind of like when you're watching the news and they do a splitscreen with two people in different places, and the windows change size and position). I've got all the window sizes and positions mapped out in an Excel spreadsheet for easy reference, but it gets tedious having to go through and change everything if I have to adjust any of said sizes or positions.

This may not even be possible, but what I'm looking for is a way to have a dropdown menu that specifies different layouts (i.e. "Splitscreen x2 Even," "Right Video x3 Even," and so on), and have all the other layers look at that and adjust their size and position accordingly. That way if I do have to change a size or a position, all I have to do is change the master (maybe have a set of sliders on some control layers, each with a name corresponding to a different layout). In my vision, the individual layers would be keyed to pull the value from the dropdown, and then pull slider values from a control layer corresponding to the name they see in the dropdown.

The question is, is there a way to key frame a dropdown selection to make it change, say over a span of a single second?

For an example of what I'm trying to simplify: https://youtu.be/UNAxqMYS8Jg?t=868

In order to do this I had to manually keyframe the sizes and positions for three windows, mine and my guest's, plus the large video window as it animates in from its off-camera position. This can be a little complicated when I just have one guest, but it's an even bigger challenge when I have multiple guests.

If you like what you see on this channel, consider leaving a tip on PayPal: https://paypal.me/tnpir4002?country.x=US&locale.x=en_US If you've ever worked with creatives, then you know we don't quite "fit" into the same mold as everyone else (and if I'm honest, we've probably frustrated you at one
TOPICS
Expressions , How to , Performance , Scripting

Views

864

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
community guidelines

correct answers 1 Correct answer

Community Expert , Jul 15, 2022 Jul 15, 2022

OK. I haven't tested this, but I think this is the edit necessary for my previous expression:

L = thisComp.layer("Dropdown Menu");
menu = L.effect("Dropdown Menu Control")("Menu");
moveTime = 1;
val = value;
if (menu.numKeys > 0){
  n = menu.nearestKey(time).index;
  if (time < menu.key(n).time) n--;
  if (n < 2){
    L1name = L.text.sourceText.valueAtTime(menu.key(1).time);
    val = thisComp.layer(L1name).effect(name + " Position X")("Slider").value;
  }else{
    t = menu.key(n).time;
    L1na
...

Likes

Translate

Translate
Participant ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

I was taking a shot in the dark at trying to figure out what to tell it to do, so maybe my syntax and/or logic isn't right. Does what I was trying to do with my modified version at least look right?

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
community guidelines
Community Expert ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

It's not clear to me what you're trying to do there, but in any case, it looks like your code would only have an effect if there were no keyframes on the menu control, which i"m guessing is not what you had in mind.

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
community guidelines
Participant ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

Right--not what I was thinking. (This was me experimenting with something I don't fully understand, so I'm not surprised I did it wrong.)

What I was aiming for was to get the expression to figure out what configuration the dropdown menu was calling for, then pull the name of the layer it was on, and (in this case) do two things when it saw a keyframe:

1)  look back to see if the dropdown had a previous keyframe, and if so, figure out which layout it was calling for and pull the relevant information from that layer (in this case, I was looking to pull the number from the "X Position" slider), and then;

2)  look at the current keyframe nearest to "time" and pull the same value from it, and as you described begin moving things as appropriate for a duration of one second (beginning at the time of the second keyframe). Repeat for any keyframes to follow.

From what I can piece together for the expression you shared, it looks like it does at least some of that, but I'm not seeing where I can point it at the property I want it to pull from. (I'm envisioning applying this or whatever expression we come up with to the X and Y transform properties of each camera input layer, along with the sliders for frame width and frame height).

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
community guidelines
Community Expert ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

I think we might be close. I think the mechanics of the expression pretty much does what you want, but additional stuff needs to happen to get to the actual position values necessary. Assume that the expression has access to the most recent and the previous keyframes and the source text associated with the times of those two keyframes, and see if you can work up the algortim to start with that info and navigate to the correct from and to position values. If you can do that, I think I can turn it into code.

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

This is the best I can come up with, let me know if this is what you were looking for: 

 

Layers:

  • Dropdown Layer
  • Splitscreen x2 Even
  • Splitscreen x5 Even
  • Camera Input Talent 1

In this example: fetching the X position; in this scenario the expression we’re talking about would be applied to the transform.xPosition property of Camera Input Talent 1 (we’re assuming separate transformation properties for X and Y). The layers titled “Splitscreen x2 Even” and “Splitscreen x5 Even” have sliders on them for frame height, frame width, and X and Y positions. The X Position slider would have a name like “Camera Input Talent 1 Position X”

Here’s how I envision it working, with this expression applied to the transform X position property of “Camera Input Talent 1”:

  1. The expression watches the .sourceText value of Dropdown Layer to see what layout layer to pull from. We’ll say that the dropdown menu starts set to “Splitscreen x2 Even.”
  2. So what the expression should do is go to the layer whose title matches the .sourceText value of the Dropdown Layer, and then (for this example) look for the slider whose name contains the name of the layer, followed by “ Position X”
  3. So at time() it will pull whatever the value of the slider described in #2 would be
  4. Then, when the sourceText property of the dropdown changes via keyframe (we’ll say that it changes to “Splitscreen x5 Even” in this example), the expression will repeat the steps in #2, only this time it’ll be looking for the xPosition slider value for the layer named “Splitscreen x5 Even”
  5. With the new values in hand, the expression will (over the course of one second) change the xPosition value from the one specified in the slider on the Splitscreen x2 Even layer to the one on the Splitscreen x5 layer.

If we can come up with a way to make this work for the X position, I can take that and adapt it to work for the Y position and the frame sizes too.

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
community guidelines
Community Expert ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

OK. I haven't tested this, but I think this is the edit necessary for my previous expression:

L = thisComp.layer("Dropdown Menu");
menu = L.effect("Dropdown Menu Control")("Menu");
moveTime = 1;
val = value;
if (menu.numKeys > 0){
  n = menu.nearestKey(time).index;
  if (time < menu.key(n).time) n--;
  if (n < 2){
    L1name = L.text.sourceText.valueAtTime(menu.key(1).time);
    val = thisComp.layer(L1name).effect(name + " Position X")("Slider").value;
  }else{
    t = menu.key(n).time;
    L1name = L.text.sourceText.valueAtTime(menu.key(n-1).time);
    v1 = thisComp.layer(L1name).effect(name + " Position X")("Slider").value;
    L2name = L.text.sourceText.valueAtTime(menu.key(n).time);
    v2 = thisComp.layer(L2name).effect(name + " Position X")("Slider").value;
    val = linear(time,t,t + moveTime,v1,v2);
  }
}
val

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

I'll try it out and report back!

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

IT WORKS!!! You are totally getting a technical consultant credit for any product I make with this from now on. This is going to make my workflow SO much easier! I can't thank you enough for helping me crack this one.

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
community guidelines
Community Expert ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

Glad to hear it! Thanks for letting me know.

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

I did make one slight tweak--I put the property selector in as a temp variable so I could adjust it once per expression and have it propagate through the rest of the expression (I just tested it out going from X position to Y position and it works), so just that fast I'm on my way.

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

One more question that might make this even easier: is there a way to pull an effect name? In other words, if I name a slider "Frame Width," is there a way similar to "thisLayer.name" to get it to recognize the name of the effect? What I'm thinking is this would make it even easier to copy and paste this expression across sliders (so if I'm using it with a "Frame Width" slider on a child layer, the expression will know to go through the layers like we already set up, but it'll pull the name of the slider it's being used on and look for a slider on the parent layer with the same name).

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
community guidelines
Community Expert ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

If you have an expression on a slider and you want to get the custom name of the slider control itself, you can do something like this:

thisProperty.propertyGroup(1).name, which goes up 1 level in the heirarchy to get the name.

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

Awesome--thank you!

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
community guidelines
Community Expert ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

While I was working up the expression, it occurred to me that if instead of this:

"Splitscreen x2 Even Positioin X"

you had used

"Splitscreen x2 Even X Position",

you could then construct the name like this:

temp = name + " " + thisProperty.name;

 

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
community guidelines
Participant ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

That's a good idea--and it's not hard to make that change, I've got a script that can go through expressions throughout a whole project and make adjustments. (It may be counterintuitive but when I do that and AfterEffects shows errors, I can follow those around and make changes to any layer or slider names as needed). Great tip!

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
community guidelines
Community Expert ,
Jul 15, 2022 Jul 15, 2022

Copy link to clipboard

Copied

Yeah, so maybe you end up with 2 flavors of the expression. One that builds the slider name using thisProperty.name and another that uses thisProperty.propertyGroup(1).name.

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
community guidelines
Participant ,
Aug 07, 2022 Aug 07, 2022

Copy link to clipboard

Copied

I have one followup question--so I've been able to get this to work exactly as we wanted it. This is the ultimate result that automatically pulls the property name of the slider:

L = thisComp.layer("Dropdown Menu");
menu = L.effect("Dropdown Menu Control")("Menu");
moveTime = thisComp.layer("Shape Dynamics").effect("Transition Duration")("Slider");
temp1 = " " + thisProperty.propertyGroup(1).name;
val = value;
if (menu.numKeys > 0){
  n = menu.nearestKey(time).index;
  if (time < menu.key(n).time) n--;
  if (n < 2){
    L1name = L.text.sourceText.valueAtTime(menu.key(1).time);
    val = thisComp.layer(L1name).effect(name + temp1)("Slider").value;
  }else{
    t = menu.key(n).time;
    L1name = L.text.sourceText.valueAtTime(menu.key(n-1).time);
    v1 = thisComp.layer(L1name).effect(name + temp1)("Slider").value;
    L2name = L.text.sourceText.valueAtTime(menu.key(n).time);
    v2 = thisComp.layer(L2name).effect(name + temp1)("Slider").value;
    val = linear(time,t,t + moveTime,v1,v2);
  }
}
val

Seeing it in action I do have one question. When it animates between the two keyframes, it behaves as if it's using linear interpolation. It's not a huge deal but I do kind of miss the old way, which used an auto bezier. Is there a way to adjust this to end up with an equivalent of a bezier?

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
community guidelines
Community Expert ,
Aug 07, 2022 Aug 07, 2022

Copy link to clipboard

Copied

You could try replacing linear(time,t,t + moveTime,v1,v2) with ease(time,t,t + moveTime,v1,v2).

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
community guidelines
Participant ,
Aug 07, 2022 Aug 07, 2022

Copy link to clipboard

Copied

I will give it a try and report back! Thanks as usual Dan

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
community guidelines
Participant ,
Aug 09, 2022 Aug 09, 2022

Copy link to clipboard

Copied

LATEST

As usual, it works perfectly! It's a small and subtle thing but it makes a HUGE difference! Many thanks as always Dan!

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
community guidelines
Participant ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

Here's an updated sample file with a partial setup in place; right now the only thing I'm working with is the X Position property on Camera 1 input. If we can make this one work, then I can adapt whatever we come up with to work everywhere else.

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
community guidelines
Community Expert ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

If you want to use the Automation Blocks tool to Time Remap Multiple Animations, you could have

one animation for each transition like "move from layout A to layout B". This rig would still require you to animate two sliders instead of one dropdown (one for picking the animation like "move from layout A to B" and one for the completion of that animation), but should work out of the box very easily.

 

rigTimeRemapPropertiesMulti

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
community guidelines
Participant ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

This is a good suggestion but it won't work. This would require me to set up an exponential amount of animations; remember, I've got six windows (which could increase in number down the line) and to make this work I'd have to configure an animation preset for every single possible combination I might need. FAR too complicated for the end state I'm trying to reach.

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
community guidelines