Store data with one button, paste it with another button

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
jesseHeinsenberg
Posts: 6
Joined: December 26th, 2013, 4:38 am

Hello aenhancers,

This is my first time I'm posting, so before all I'd like to thank all the contributors for sharing their knowledge and making this forum a great ressource.
I've been using AfterEffects for ten years now, but I began to script only this summer, and as I am not a programmer, each new script is a long and difficult process for me. But it really worth it and now I'm hooked.
So for the first time I'm asking a little bit of help because I don't know if I'm using the correct method for the goal I want to reach.
Now,what I want to do is to copy some selected masks+all the effects related to these masks (Fill and Stroke effects) and paste them on another layer in another comp. For now, I'm just trying to copy/paste the masks as you can see in the following script.

Code: Select all

var w = new Window ("palette");
cpy = w.add ("button", undefined, "Copy");
pst = w.add ("button", undefined, "Paste");

//copy Masks
 cpy.onClick= function() {
app.beginUndoGroup("copyMasksAndFX");

	function getSelectedMasks(){
		var oneLayer = app.project.activeItem.selectedLayers[0];
		var selectedMasks = new Array();	
			for(i=1; i<= oneLayer.Masks.numProperties; i++){
			if(oneLayer.Masks.property(i).selected)
			selectedMasks[selectedMasks.length]=oneLayer.Masks.property(i);
			}
		return selectedMasks;
		}
	
getSelectedMasks();

app.endUndoGroup();
}
 
 //paste Masks
 pst.onClick=function() {
app.beginUndoGroup("pasteMasksAndFX");

	function createMasks(numMasks) {
		var anotherLayer = app.project.activeItem.selectedLayers[0];
		var newMasks =  anotherLayer.Masks.addProperty("Mask");
		newMasks.name=selectedMasks[numMasks].name;
		newMasks.maskPath.setValue ( selectedMasks[numMasks].maskPath.value);
		newMasks.maskOpacity.setValue(0);
		}

for (var i = 0; i < selectedMasks.length; i++){
	createMasks(i);	
}

app.endUndoGroup();
}
  
w.show ();
More generally, I'd be curious to know how I could store data with one button and use this data with another button.
beginUndoGroup
Posts: 81
Joined: November 27th, 2012, 6:41 am

You can, all you need to do is declare a variable high enough in your script (for instance at the same level as your window object).
Here i called that variable 'scriptSelection', you can rename it.

Code: Select all

var scriptSelection = [];
var w = new Window("palette", etc);
var cpy = w.add ("button", undefined, "Copy");
var pst = w.add ("button", undefined, "Paste");

cpy.onClick = function()
{
	function getSelectedMasks()
	{
		var comp=app.project.activeItem, oneLayer, selectedMasks=[];
		if (comp instanceof CompItem && comp.selectedLayers.length>1 && comp.selectedLayers[0].Masks)
		{
			oneLayer = app.project.activeItem.selectedLayers[0];
			for(i=1; i<= oneLayer.Masks.numProperties; i++)
			{
				if (oneLayer.Masks.property(i).selected) selectedMasks[selectedMasks.length]=oneLayer.Masks.property(i);
				};
			};
		return selectedMasks;
		};

	app.beginUndoGroup("copyMasksAndFX");   
	scriptSelection = getSelectedMasks();
	app.endUndoGroup();
	};
This way your script stores in its workspace a selection variable which you can reuse for later actions.
Be aware that this selection may become invalid (for instance between the moment the user has made its selection and the moment he asks for using it, the user has deleted one of the masks).
In your "paste" function you'll have to check that the masks in the masks array are still valid individually.
Something like this

Code: Select all

if (Object.isValid(scriptSelection[i])) // do stuff with that mask
By the way i don't think sandwiching the selection process in an undo group has any effect. (Not sure.)
Another thing is that you should check more whether the objects you are dealing with can be applied certain actions.
For instance, if the activeItem is not a composition, or has no layer selected, or has no mask (eg it is a camera) your script would generate error alerts everytime.

Xavier.
jesseHeinsenberg
Posts: 6
Joined: December 26th, 2013, 4:38 am

Thanks a lot Xavier,

I agree that I don't check a lot, that's because most of the time I'm the only user of my scripts.
It took me some time to make your script work, because it seems that the way you declare arrays doesn't work on my old CS4 version. But now it's OK.
Once again, the solution was much more simpler than I thought.
Post Reply