Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Check if any of selected layers is not a ShapeLayer

  • Check if any of selected layers is not a ShapeLayer

    Posted by Florian Zeiler on March 21, 2018 at 10:01 am

    Hey there,

    i’m currently trying to find a way to check if any of the selected layers is not a Shape Layer. The only method i found, was using “instanceof” – but i can’t seem to find a good way to apply this to my array, since i want to check if any of the objects in the array is (or is not) a Shape Layer.

    I tried using the some() method on the array, but i can’t seem to get it to work.. The current code below only checks the first selected layer.

    Any help or idea to point me into the right direction is greatly appreciated!

    Thanks in advance

    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;

    if (numLayer[0] instanceof ShapeLayer) {
    alert("This is a Shape Layer - Yeah!");
    } else {
    alert("This is NOT a Shape Layer - Yikes!")
    }

    Florian Zeiler replied 8 years, 1 month ago 2 Members · 10 Replies
  • 10 Replies
  • Andrei Popa

    March 21, 2018 at 10:58 am

    Is this what you are looking for?
    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;

    for(i=0;i

    Andrei
    My Envato portfolio.

  • Andrei Popa

    March 21, 2018 at 11:34 am

    I think i got your question wrong. If you need to check if any selected layer is not shape, you should use this function. The function returns false if at least one layer is not shapelayer, true otherwise.

    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;

    //You call the function using your layers as parameter
    checkIfAllShapes(numLayer);

    //the function
    function checkIfAllShapes(layerArray) {
    for (i = 0; i < layerArray; i++) {
    if ((layerArray[i] instanceof ShapeLayer) == false) return false;
    }
    return true;
    }

    Andrei
    My Envato portfolio.

  • Florian Zeiler

    March 21, 2018 at 2:32 pm

    Hello Andrei,

    thank you so much for taking the time to help me with my Script!

    Using your hint (the for loop… i must have missed that ????) i was able to alter my Script. I can now successfully retrieve the layers, that are not Shape layers. But now i am facing another strange problem – maybe you can help me?

    In the code below, you can see that i am applying an expression to all Stroke colors on the Shape layers. That works already. But for all the non-Shape Layers, i want to apply a preset.

    For some reason, the preset is also applied to the Shape layers, even though the alert i put in for testing only prints out the names of the non-Shape Layers.

    Do you have an idea why this is happening? The other methods (.remove() or moveToBeginning() for example) work just as expected and only affect the non-shape layers – but the .applyPreset() affects all layers.. what’s going on?

    Thanks so much in advance!

    {
    app.beginUndoGroup("Link Stroke Color");

    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;
    var colorExp = '(expression placeholder - for code length reasons :D)"';

    for (var a = 0; a &lt; numLayer.length; a++) {
    if (numLayer[a] instanceof ShapeLayer) {

    function scanPropGroupProperties(propGroup) {
    var i, prop;

    // Iterate over the specified property group's properties
    for (i = 1; i &lt;= propGroup.numProperties; i++) {
    prop = propGroup.property(i);
    if (prop.propertyType === PropertyType.PROPERTY && prop.name === 'Color' && propGroup.canSetEnabled && prop.parentProperty.name.slice(0,6) === 'Stroke') // Found a property
    {
    prop.expression = colorExp
    } else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP)) {
    // Found an indexed or named group, so check its nested properties
    scanPropGroupProperties(prop);
    }
    }
    }

    for (var i = 0; i &lt; numLayer.length; i++) {
    scanPropGroupProperties(numLayer[i]);
    }

    } else {
    alert(numLayer[a].name + " is not a Shape Layer!");
    numLayer[a].applyPreset(File("\fill.ffx"));
    }
    }

    app.endUndoGroup();
    }

  • Andrei Popa

    March 21, 2018 at 2:56 pm

    The line that applies the preset should only be executed at the same time with the alert. I can’t think of a reason for it to be executed more(aka even on the shape layers). But i will give you some hints on your code, things that i don’t really know if create this confusion or not. First of all, do not create the function in the middle of your script. Its so confusing when reading it. Put it on the end. It does not matter where it is written, only where it is called. Second, you used 2 for loops for going through the selected layers. I think that confusion is due to the function being placed there. So here is what i came up with. Tell me how it works.
    {
    app.beginUndoGroup("Link Stroke Color");
    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;
    var colorExp = '(expression placeholder - for code length reasons :D)"';

    for (var a = 0; a < numLayer.length; a++) {
    if (numLayer[a] instanceof ShapeLayer){
    //it is a shape layer
    scanPropGroupProperties(numLayer[i]);
    } else {
    //its not a shape layer
    alert(numLayer[a].name + " is not a Shape Layer!");
    numLayer[a].applyPreset(File("\fill.ffx"));
    }
    }

    //==============================================================================
    function scanPropGroupProperties(propGroup){ //scans the proprieties and adds expressions to the strokes
    var i, prop;
    // Iterate over the specified property group's properties
    for (i = 1; i <= propGroup.numProperties; i++){
    prop = propGroup.property(i);
    if (prop.propertyType === PropertyType.PROPERTY && prop.name === 'Color' && propGroup.canSetEnabled && prop.parentProperty.name.slice(0, 6) === 'Stroke'){ // Found a property
    prop.expression = colorExp;
    } else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP)) {
    // Found an indexed or named group, so check its nested properties
    scanPropGroupProperties(prop);
    }
    }
    }
    app.endUndoGroup();
    }

    Andrei
    My Envato portfolio.

  • Andrei Popa

    March 21, 2018 at 3:08 pm

    I missed a character there, and i don’t know if you can edit your post here. So here we go again:
    {
    app.beginUndoGroup("Link Stroke Color");
    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;
    var colorExp = '(expression placeholder - for code length reasons :D)"';

    for (var a = 0; a < numLayer.length; a++) {
    if (numLayer[a] instanceof ShapeLayer){
    //it is a shape layer
    scanPropGroupProperties(numLayer[a]);
    } else {
    //its not a shape layer
    alert(numLayer[a].name + " is not a Shape Layer!");
    numLayer[a].applyPreset(File("\fill.ffx"));
    }
    }

    //==============================================================================
    function scanPropGroupProperties(propGroup){ //scans the proprieties and adds expressions to the strokes
    var i, prop;
    // Iterate over the specified property group's properties
    for (i = 1; i <= propGroup.numProperties; i++){
    prop = propGroup.property(i);
    if (prop.propertyType === PropertyType.PROPERTY && prop.name === 'Color' && propGroup.canSetEnabled && prop.parentProperty.name.slice(0, 6) === 'Stroke'){ // Found a property
    prop.expression = colorExp;
    } else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP)) {
    // Found an indexed or named group, so check its nested properties
    scanPropGroupProperties(prop);
    }
    }
    }
    app.endUndoGroup();
    }

    Andrei
    My Envato portfolio.

  • Florian Zeiler

    March 21, 2018 at 3:12 pm

    Thanks for the help and for cleaning up the code ☺

    Using this script, i get an error at line 22 – “undefined is not an object”

    Did i mess something up?

  • Andrei Popa

    March 21, 2018 at 3:44 pm

    I did not test this piece of code. Now i did. Only problem i have is applying the preset. I need to use File(“\\fill.ffx”); Do you have any other code than this? Is this part of a bigger script? I can’t seem to figure out what is wrong. You are running this code inside extendscript? Or with file>script>run script?

    Andrei
    My Envato portfolio.

  • Florian Zeiler

    March 21, 2018 at 4:06 pm

    No, this is actually the whole script – the ffx file is residing in a folder and can be accessed by the script. My guess is that there is something fundamentally wrong with the applyPreset() method – every other method i tried (such as remove() for example) works as expected and only affects the non-Shape Layers (with my original script).

    But the applyPreset method affects all layers!

    I am running this in extendscript but also tried Expressionist in Script Mode and the run script method .. all the same!

    Thank you for helping me with this – i am stuck.. ☹

  • Andrei Popa

    March 21, 2018 at 4:25 pm

    Found your problem. applyPresset applies to all selected layers. So you should deselect them all after saving your numLayer variable, and select each one when needed, then deselect it again. I ran into this problem before. I have a function that i sometimes use . So i think this should solve your problem.
    {
    app.beginUndoGroup("Link Stroke Color");
    var myComp = app.project.activeItem;
    var numLayer = myComp.selectedLayers;
    var colorExp = '(expression placeholder - for code length reasons :D)"';
    deselectEverything();

    for (var a = 0; a < numLayer.length; a++) {
    if (numLayer[a] instanceof ShapeLayer){
    //it is a shape layer
    scanPropGroupProperties(numLayer[a]);
    } else {
    //its not a shape layer
    alert(numLayer[a].name + " is not a Shape Layer!");
    numLayer[a].selected = true;
    numLayer[a].applyPreset(File("D:\\fill.ffx"));
    numLayer[a].selected=false;
    }
    }

    //==============================================================================
    function scanPropGroupProperties(propGroup){ //scans the proprieties and adds expressions to the strokes
    var i, prop;
    // Iterate over the specified property group's properties
    for (i = 1; i <= propGroup.numProperties; i++){
    prop = propGroup.property(i);
    if (prop.propertyType === PropertyType.PROPERTY && prop.name === 'Color' && propGroup.canSetEnabled && prop.parentProperty.name.slice(0, 6) === 'Stroke'){ // Found a property
    prop.expression = colorExp;
    } else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP)) {
    // Found an indexed or named group, so check its nested properties
    scanPropGroupProperties(prop);
    }
    }
    }
    app.endUndoGroup();
    }
    //==============================================================================
    //Go through the current active composition and deselect everything
    function deselectEverything() {
    var myActiveComp = app.project.activeItem;
    for (i = 1; i <= myActiveComp.numLayers; i++){
    myActiveComp.layer(i).selected = false;
    }
    }

    But i still don’t know why applyPreset acts this way.

    Andrei
    My Envato portfolio.

  • Florian Zeiler

    March 21, 2018 at 4:58 pm

    Ah, thanks so much for that!

    But it’s rather unexpected behaviour, isn’t it? Especially since the other methods do not perform that way..

    Anyway, your edit works perfectly as expected – thank you so much for your time and effort! ☺

    Regards

    Florian

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy