Copy link to clipboard
Copied
i saw a plugin that would dynamically name a pre-comp, but couldn't handle more than one layer at a time. i need to group individual animated characters, which are on their own individual layer ...so i can have pre-comps of the words. i have way too many to handle and typing the name for each pre-comp would take forever.
Can you recommend code or a plugin to do this?
i eventually will be trying to use monkey layer or something match the words to markers.
Create Precomps.jsx
(function(thisObj) {
buildUI(thisObj);
function buildUI(thisObj) {
var palette = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Create Precomps", undefined, {
resizeable: true
});
palette.alignChildren = ["left", "top"];
palette.spacing = 7;
palette.margins = 10;
var button = palette.add("button", undefined, 'Create Precomp');
if (palette instanceof Window) {
palette.center();
palette.show();
} else {
...
Copy link to clipboard
Copied
Can you make a screen recording to show us the manual steps you take?
This will allow us to write a script or direct you to a script that performs these actions.
Copy link to clipboard
Copied
https://youtu.be/7HnoJDyGEbU
i would be naming them because i think you need a word to be a single layer to work in monkey layers with textsyncr. or maybe i could do something with textforce.
Copy link to clipboard
Copied
Create Precomps.jsx
(function(thisObj) {
buildUI(thisObj);
function buildUI(thisObj) {
var palette = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Create Precomps", undefined, {
resizeable: true
});
palette.alignChildren = ["left", "top"];
palette.spacing = 7;
palette.margins = 10;
var button = palette.add("button", undefined, 'Create Precomp');
if (palette instanceof Window) {
palette.center();
palette.show();
} else {
palette.layout.layout(true);
palette.layout.resize();
}
button.onClick = function() {
var proj = app.project;
var thisComp = proj.activeItem;
var selectedLayers = thisComp.selectedLayers;
if (!selectedLayers.length) {
alert('Select at least 1 layer');
return false;
}
app.beginUndoGroup("Create Precomps");
var precompName = '';
var indexes = [];
for (var i = 0; i < selectedLayers.length; i++) {
precompName += selectedLayers[i].name;
indexes.push(selectedLayers[i].index);
}
var precomp = thisComp.layers.precompose(indexes, precompName, true);
app.endUndoGroup();
};
}
})(this);
Copy link to clipboard
Copied
This is great, can i bother you to set it to remove any numbers it sees? There are layers with the same character cuasing the numbering that ae does.
Copy link to clipboard
Copied
at the end of the script, you have this line:
var precomp = thisComp.layers.precompose(indexes, precompName, true);
replace with:
// remove numbers
var precomp = thisComp.layers.precompose(indexes, precompName.replace(/\d/g, ''), true);
// remove numbers and spaces
var precomp = thisComp.layers.precompose(indexes, precompName.replace(/[\d\s]/g, ''), true);
Copy link to clipboard
Copied
Your Extendscript select a group of layers and then put them into a precomp. Can you change it to move the selected layers to the next available marker?
i know it's possible to make a counter of makers with a slider. But i don't know if Extendscript uses something different.
Copy link to clipboard
Copied
i mashed something together from you, Dan, and Fabrice
var palette = new Window("palette", "Move Selected Layers to Marker Position", undefined);
var button = palette.add("button", undefined, "Move Layers");
palette.center();
palette.show();
button.onClick = function () {
var proj = app.project;
var thisComp = proj.activeItem;
var selectedLayers = thisComp.selectedLayers;
if (!thisComp.markerProperty.numKeys) {
alert('Please, add a marker on the timeline.');
return
}
if (!selectedLayers.length) {
alert('Select at least 1 layer');
return false;
}
app.beginUndoGroup("undo");
var myComp = app.project.activeItem;
var myProp = myComp.markerProperty;
var myTime = myComp.time;
var n = 0;
if (myProp.numKeys > 0){
n = myProp.nearestKeyIndex(myTime);
if (myProp.keyTime(n) <= myTime) n++;
if (n > myProp.numKeys) n = 0;
}
if (n > 0){
myComp.time = myProp.keyTime(n)
}
for (var i = 0; i < selectedLayers.length; i++) {
selectedLayers[i].startTime = myTime;
}
endUndoGroup();
}
https://community.adobe.com/t5/after-effects-discussions/get-number-of-comp-markers/td-p/9969076
https://creativecow.net/forums/thread/how-to-move-timeline-layers-with-marker/
Copy link to clipboard
Copied
Or even faster.
Create Precomps - v2.0.jsx
(function(thisObj) {
Array.prototype.indexOf = function(item) {
var index = 0,
length = this.length;
for (; index < length; index++) {
if (this[index] === item)
return index;
}
return -1;
}
buildUI(thisObj);
function buildUI(thisObj) {
var palette = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Create Precomps", undefined, {
resizeable: true
});
palette.alignChildren = ["left", "top"];
palette.spacing = 7;
palette.margins = 10;
palette.add("statictext", undefined, 'Precomp Names Separated with Commas:');
var precomps = palette.add('edittext {properties: {name: "edittext1"}}');
precomps.text = "";
var proj = app.project;
var thisComp = proj.activeItem;
if (thisComp) {
for (var i = 1; i <= thisComp.numLayers; i++) {
precomps.text += thisComp.layer(i).name
}
}
precomps.preferredSize.width = 300;
var button = palette.add("button", undefined, 'Create Precomp');
button.preferredSize.width = 300;
if (palette instanceof Window) {
palette.center();
palette.show();
} else {
palette.layout.layout(true);
palette.layout.resize();
}
button.onClick = function() {
var done = [];
var arr = precomps.text.split(',');
var proj = app.project;
var thisComp = proj.activeItem;
app.beginUndoGroup("Create Precomps");
for (var i = 0; i < arr.length; i++) {
// DeselectAll
app.executeCommand(2004);
var precompName = arr[i];
var layerNames = arr[i].split('');
var indexes = [];
for (var j = 1; j <= thisComp.numLayers; j++) {
if (done.indexOf(thisComp.layer(j)) == -1 && thisComp.layer(j).name == layerNames[0]) {
thisComp.layer(j).selected = true;
indexes.push(thisComp.layer(j).index);
layerNames = layerNames.slice(1);
if (!layerNames.length) {
var precomp = thisComp.layers.precompose(indexes, precompName, true);
done.push(precomp);
break;
}
}
}
}
app.endUndoGroup();
};
}
})(this);
Copy link to clipboard
Copied
i save it as a .jsx and then do a file/scripts/run ...but it doesn't work ...how do i get that console you are using?
Copy link to clipboard
Copied
I tried from file > Scripts -> Run.... it works
The CONSOLE I use is a custom extension.
But I recently saw one that looks even better.
Copy link to clipboard
Copied
It's ae acting weird with naming of duplicatly named layers ...i think it works for you because your layers are not of precomps. Is there a way to have the code only look at the first character for a name? ...or sptit the string at a blank space?
Copy link to clipboard
Copied
i think it's acting weird because the idividual layers start out as precomps?
Copy link to clipboard
Copied
Try this code,
it should rename your layers correctly.
Just be aware that your Controller layer will be renamed to C
(function(thisObj) {
Array.prototype.indexOf = function(item) {
var index = 0,
length = this.length;
for (; index < length; index++) {
if (this[index] === item)
return index;
}
return -1;
}
buildUI(thisObj);
function buildUI(thisObj) {
var palette = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Create Precomps", undefined, {
resizeable: true
});
palette.alignChildren = ["left", "top"];
palette.spacing = 7;
palette.margins = 10;
palette.add("statictext", undefined, 'Precomp Names Separated with Commas:');
var precomps = palette.add('edittext {properties: {name: "edittext1"}}');
precomps.text = "";
var proj = app.project;
var thisComp = proj.activeItem;
if (thisComp) {
for (var i = 1; i <= thisComp.numLayers; i++) {
thisComp.layer(i).name = thisComp.layer(i).name.substring(0, 1)
precomps.text += thisComp.layer(i).name
}
}
precomps.preferredSize.width = 300;
var button = palette.add("button", undefined, 'Create Precomp');
button.preferredSize.width = 300;
if (palette instanceof Window) {
palette.center();
palette.show();
} else {
palette.layout.layout(true);
palette.layout.resize();
}
button.onClick = function() {
var done = [];
var arr = precomps.text.split(',');
var proj = app.project;
var thisComp = proj.activeItem;
app.beginUndoGroup("Create Precomps");
for (var i = 0; i < arr.length; i++) {
// DeselectAll
app.executeCommand(2004);
var precompName = arr[i];
var layerNames = arr[i].split('');
var indexes = [];
for (var j = 1; j <= thisComp.numLayers; j++) {
if (done.indexOf(thisComp.layer(j)) == -1 && thisComp.layer(j).name == layerNames[0]) {
thisComp.layer(j).selected = true;
indexes.push(thisComp.layer(j).index);
layerNames = layerNames.slice(1);
if (!layerNames.length) {
var precomp = thisComp.layers.precompose(indexes, precompName, true);
done.push(precomp);
break;
}
}
}
}
app.endUndoGroup();
};
}
})(this);
Copy link to clipboard
Copied
Thanks for looking into this. i just changed the index to step over the controller layer:
if (thisComp) {
for (var i = 2; i <= thisComp.numLayers; i++) {
Copy link to clipboard
Copied
Can i please annoy you again? Would you know how to make a copy of that first layer controller and put it into each of the new precomps that this makes?
Copy link to clipboard
Copied
Maybe like this:
(function(thisObj) {
Array.prototype.indexOf = function(item) {
var index = 0,
length = this.length;
for (; index < length; index++) {
if (this[index] === item)
return index;
}
return -1;
}
buildUI(thisObj);
function buildUI(thisObj) {
var palette = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Create Precomps", undefined, {
resizeable: true
});
palette.alignChildren = ["left", "top"];
palette.spacing = 7;
palette.margins = 10;
palette.add("statictext", undefined, 'Precomp Names Separated with Commas:');
var precomps = palette.add('edittext {properties: {name: "edittext1"}}');
precomps.text = "";
var proj = app.project;
var thisComp = proj.activeItem;
if (thisComp) {
for (var i = 2; i <= thisComp.numLayers; i++) {
thisComp.layer(i).name = thisComp.layer(i).name.substring(0, 1)
precomps.text += thisComp.layer(i).name
}
}
precomps.preferredSize.width = 300;
var button = palette.add("button", undefined, 'Create Precomps');
button.preferredSize.width = 300;
if (palette instanceof Window) {
palette.center();
palette.show();
} else {
palette.layout.layout(true);
palette.layout.resize();
}
button.onClick = function() {
var done = [];
var arr = precomps.text.split(',');
var proj = app.project;
var thisComp = proj.activeItem;
app.beginUndoGroup("Create Precomps");
for (var i = 0; i < arr.length; i++) {
// DeselectAll
app.executeCommand(2004);
var precompName = arr[i];
var layerNames = arr[i].split('');
var indexes = [1];
thisComp.layer(1).duplicate();
thisComp.layer(1).selected = true;
thisComp.layer(1).name = thisComp.layer(2).name;
for (var j = 3; j <= thisComp.numLayers; j++) {
if (done.indexOf(thisComp.layer(j)) == -1 && thisComp.layer(j).name == layerNames[0]) {
thisComp.layer(j).selected = true;
indexes.push(thisComp.layer(j).index);
layerNames = layerNames.slice(1);
if (!layerNames.length) {
var precomp = thisComp.layers.precompose(indexes, precompName, true);
done.push(precomp);
thisComp.layer(1).moveAfter(thisComp.layer(thisComp.numLayers));
break;
}
}
}
}
thisComp.layer(1).remove();
app.endUndoGroup();
};
}
})(this);
Copy link to clipboard
Copied
That does put a copy in there, thank you ...but erm, it seems FontManager bakes in a some paths as it generates the animations of each letter, so after i use your scipt is starts asking for a layer that i don't think ever existed. "T 2 1" ...for example. Does your script change the name of the layers as they go into their new precomp?
Copy link to clipboard
Copied
i'm noticing that the 44 errors come up right as i run your script ...so before i even click "Create Precomps". That's weird.
Copy link to clipboard
Copied
You did everything i asked ...but i think i was asking for something that was never going to work. These layers are super weird from FontManager ...i'm getting all kinds of crazy errors after they get grouped into precomps ...the paths are breaking somewhere.
i could avoid the whole grouping thing if there was a way to move multiple layers (that make up each word) to markers based on a paragraph of text that i feed it.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now