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

Script button not looping

Explorer ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

Hi, i am trying to create a small script for my own workflow. i am a begginer so i am not sure if looping is the correct terminolgy for this issue, but took a guess as i am not sure what to search for.

 

The part of the script i need help with is where i have a button that creates a new layer above the layer i have selected.

The problem is that the script only works properly once, after the first time it has been run either from extendscript or from the window tab within after effects - meaning, that the layer that was selected before running the script, gets the new layer created above it, which is right, but when i then select another layer and click the button, it still creates it above the original layer that was selected before the script was initiated. in order for it to work on another layer, i need to select the new layer and then re-run the script.

 

TLDR - Is there something specific that needs to be done in order for the button to keep creating above the new layer that i select each time without having to re run the script?

 

the code is as basic as it comes:

var myLayers = app.project.activeItem.selectedLayers;
var firstLayer = myLayers[0];
var secondLayer = myLayers[1];

moveButton.onClick = function() {
  secondLayer.moveBefore(firstLayer);
}

createButton.onClick = function() {
  var newSolid = myComp.layers.addSolid([0.8, 0.2, 0.5], "NEW LAYER", 1920, 1080, 1).moveBefore(firstLayer);
}

 

TOPICS
Scripting

Views

420

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

Enthusiast , Jan 17, 2021 Jan 17, 2021

At a quick glance, I'd guess it's because you're only ever defining which are the selected layers once, when the script is first run. You simply need to put copies of those first lines inside each of the functions instead so they are defined at the point when the buttons are clicked.

Votes

Translate

Translate
LEGEND ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

On the face of it this should work, but you may need to add some extra checks to manage the undo queue, check whether there's actually only one or a bunch of contiguous layers selected, clear the selection after execution and similar. On a hunch it seems like the internal layer index doesn't get updated somehow, but I have no idea why.

 

Mylenium

Votes

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
Explorer ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

ok thanks for your reply, i will consider some of this stuff in the future.

Votes

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
Enthusiast ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

At a quick glance, I'd guess it's because you're only ever defining which are the selected layers once, when the script is first run. You simply need to put copies of those first lines inside each of the functions instead so they are defined at the point when the buttons are clicked.

Votes

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
Explorer ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

yep, that did the trick. and also makes total sense now that i think of it 🙂 .

not sure if there is a way to do this in more automated way outside of the button, because if lets say there are 2,3 or 4 buttons, then you'd need to have duplicate lines of the same code under each button.onClick. you dont have to answe this one.. im just thinking out loud here, out of curiousity.

Votes

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
Explorer ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

and thank you for anwsering, appreciate it

Votes

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
Enthusiast ,
Jan 17, 2021 Jan 17, 2021

Copy link to clipboard

Copied

LATEST

No problem. You're always going to need to redefine activeItem / selectedLayers inside the click function because you want it to work whatever comp / layer is selected.

 

You could have a function just to define those things and call that function at the start of each on click function, but then you need to be careful of the variable scope. You'd need to define the variables in the main script scope (i.e. var firstLayer, secondLayer;) then not use var when assigning those variables inside a function scope so it is using the instances of the variables from the main scope. If you use var to define a variable inside a function that variable only exists inside the scope of that function. Not using var anywhere at all is bad practice though as then it's in the full scope of any scripts run during this session of After Effects.

 

Something I've done before is assign a bunch of buttons to the same click function then read this.text to get the text on whichever button was clicked and alter what the function does accordingly.

 

I haven't tested this but you should get the idea. And you can always use if/else rather than switch.

moveButton.onClick = createButton.onClick = function() {
	
	if (app.project.activeItem != null && app.project.activeItem instanceof CompItem) {
		
		var myLayers = app.project.activeItem.selectedLayers;
		var firstLayer = myLayers[0];
		var secondLayer = myLayers[1];

		switch(this.text) {	// assumes your buttons are named Move and Create
			case "Move": 
				secondLayer.moveBefore(firstLayer);
				break;
			case "Create": 
				var newSolid = myComp.layers.addSolid([0.8, 0.2, 0.5], "NEW LAYER", 1920, 1080, 1).moveBefore(firstLayer);
				break;
		}
	
	} else alert("no comp selected");
};

But for something simple like this I'd just double up the code in each function. There's something to be said for keeping things separate to make it easier to read and debug.

 

You should also be doing things like making sure activeItem != null && activeItem instanceof CompItem because activeItem can also refer to whatever is selected in the project window. Also not assuming selectedLayers.length > 1 if you do actually need to be defining the second selected layer.

 

That should give you some more stuff to think about!

Votes

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