Skip to main content
brandonb96942845
Inspiring
July 13, 2022
Answered

Advanced AfterEffects Question: Keyframe-able Dropdown?

  • July 13, 2022
  • 3 replies
  • 7601 views

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.

This topic has been closed for replies.
Correct answer Dan Ebberts

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.


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

3 replies

Mathias Moehl
Community Expert
July 14, 2022

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.

 

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
brandonb96942845
Inspiring
July 14, 2022

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.

Mylenium
Brainiac
July 13, 2022

You can do that, but why make your life even more complicated by introducing string processing into the equation - literally? Doesn't really make a lot of sense, since you would need to fetch the paths of the effect controls and then have extra code that constructs the correct reference. I think you're underestimating how complex this could get. I would definitely simply set up a dedicated "Controller" layer in the parent comp and glean all values from there, not mess around with scattering stuff on individual layers and pre-comps. You have to keep in mind that AE's expressiosn still work based on absolute references and creating cascading setups based on pseudo-realtive references such as you propose is in itself already prone to errors and potentially breaking down just by accidentally having a wrong value somewhere or renaming a layer or effect.

 

Mylenium

brandonb96942845
Inspiring
July 13, 2022

I know exactly what I'm doing and with my workflow, this is precisely the way to do it. My entire workflow is based around "change it once, propagate everywhere," and what you're describing complicates my life a lot more than how I want to do it. Your way, I have to change every value in every single layer if I want to make a change, which defeats the entire purpose of trying to set up a master layer in the first place. My way, I have to work harder with the initial setup, but down the line anytime I need to make a change it's a snap.

 

To put my workflow into perspective, I've developed an entire motion graphics package, and it's all in a single project file. The colors, fonts, sizes, everything is parented to an "appearance template" comp, and animations in the individual comps are all parented to "shape dynamics" layers that operate based on math. I had to work hard to get everything set up the way I want it, but now when I need to make a change I don't have to go through fifty different project files and make the same change in each one. I just make it once, and it propagates everywhere. At worst I have to re-export some standalone MOVs but that's no problem at all.

Dan Ebberts
Community Expert
July 13, 2022

It sounds interesting, but a little confusing. Besides knowing which layout is currently selected, each layer also needs to know the template layer to which it is assigned in the scenario. For example, say you have three layers participating, one of the layers needs to know to be offscreen in a 2-layer layout. How do you see that working?

Mylenium
Brainiac
July 13, 2022

The values must be present in the child expressions themselves and then be used accordingly. Of course once they are it could easily be that you use a dropdown to trigger them, including keyframing the value and interpolating using something like a linear(time, value A, value B, start time, start time + delay), but none of this is going to be trivial as you constantly need to check what the current time is, which keyframe is current, what layout and so on. Lots of valueAtTime() and nearestKey() stuff. The change in the dropdown itself is always immediate, since it only has hold keyframes, anyway. that's the easy part. The hard part is the rest.

 

Mylenium

brandonb96942845
Inspiring
July 13, 2022
quote

The values must be present in the child expressions themselves and then be used accordingly.

By @Mylenium

In this scenario I don't think that's correct. What I'm looking to do is this:

> layer: "Shape Dynamics," which will have a dropdown with the various layout options

> individual layers with the names of each layout that appears in the dropdown, each with a set of sliders set to values appropriate for that layout

> the layers for the individual windows I'm working with, each with a set of sliders

 

So let's say from the dropdown I select a layout named "Splitscreen x2 Even." There will be a layer with that name.

 

The expressions on the child layers will be setup something like this: thisLayer.transform.xPosition = thisComp.layer(layer("Shape Dynamics".sourceText).slider("X Position")

In other words, which layer the various windows will pull their values from will change depending on what the dropdown value is. That means I won't have to set up all the values in every slider, just point them all to the wherever the dropdown value will be reflected (I'm guessing that'll be sourceText), but what it'll do is pull the layer name from the source text value.