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

Trying to recursively loop through comp to find all color controls

Enthusiast ,
Jun 05, 2018 Jun 05, 2018

Copy link to clipboard

Copied

Hey guys, new to scripting. I'd like to be able to crawl through my comp and identify any visible color controls (whether inside stroke or fill, for text, or color expression controls, etc.) to either .push() into an array or to modify each by appending an expression to it. I've modified snippets given by Horshack and Dan Ebberts (thanks btw!) and am successfully combing through every property of every layer of my comp, but I'm also returning hidden colors that I'd like to not have plus I'm getting some odd errors:

//  find / replace parameters are for names, not relevant at the moment

// main("Stroke 1", "Stroke");

var count = 0;

var colorArray = [];

// Horshack @https://forums.adobe.com/thread/2317720

function dumpPropTree(rootObj, nestingLevel, find, replace) {

    var countProps = rootObj.numProperties;

    for (var propIndex=1; propIndex <= countProps; propIndex++) {

        var prop = rootObj.property(propIndex);

        if (prop.name === find) {

          prop.name = replace;

        }

        var type = prop.propertyValueType;

  /////// Color:

        switch(prop.propertyValueType) {

          case PropertyValueType.COLOR:

            if (prop.canSetExpression) {

              var newColor = rgbToHex(prop.value[0] * 255, prop.value[1] * 255, prop.value[2] * 255);

               // working:

              // alert(newColor);

              count++;

               // not working:

              // colorArray.push(newColor);

            }

            break;

          default:

            break;

        }

  /////// End color

        if (prop.numProperties > 0)

            dumpPropTree(prop, nestingLevel+1, find, replace);

    }

}

function main(find, replace) {

  var activeComp = app.project.activeItem;

  var countSelectedLayers = activeComp.layers.length;

  for (selectedLayerIndex = 1; selectedLayerIndex <= countSelectedLayers; selectedLayerIndex++) {

      var layer = activeComp.layers[selectedLayerIndex];

      dumpPropTree(layer, 0, find, replace);

  }

  // alert("Result is " + colorArray);  // ERROR: Invalid numeric result (divide by zero?)

        // But why? There's no division in this code, and hex values are showing correctly?

  alert(count);

}

/// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb

// componentToHex();

// rgbToHex();

When I use this on a comp that has one shape layer with 4 rectangles (each of which having one distinct fill), then I return 13 colors instead of 4, and the extras seem to be for Blending Modes because they're pure white or pure black. I thought .canSetExpression would filter those out since they don't seem to be visible, is there a better way to identify only the visible Color properties, and can I have any pointers on why I'm getting errors trying to push these hex values to a global array? The ideal output  would be returning an array like ["ff0000", "00aa99", "bcbcbc", "323232"], which would be all four (fill/stroke/expression control) colors currently inside my comp.

Can I get any help here? I can discriminate the array so only new colors are added to prevent duplicates on my own, but I'm unsure why pushing to this array doesn't work here and how to get only visible colors (and would need these solved before moving on).

TOPICS
Scripting

Views

803

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

Advocate , Jun 07, 2018 Jun 07, 2018

Hey Tom. Wellcome to the club!

alert("Result is " + colorArray); throws error because you are concatinating String with Array, witch is a bit nonono in JS land. To fix this, all you need to do is convert array to string, like so:

alert("Result is " + colorArray.toString());

To answer your quesstion regarding Hidden properties, I have this method, that tries to apply expression to a property (check function isHidden()). If it succeeds - then the property is hidden, if it fails - property is visible.

...

Votes

Translate

Translate
Advocate ,
Jun 07, 2018 Jun 07, 2018

Copy link to clipboard

Copied

LATEST

Hey Tom. Wellcome to the club!

alert("Result is " + colorArray); throws error because you are concatinating String with Array, witch is a bit nonono in JS land. To fix this, all you need to do is convert array to string, like so:

alert("Result is " + colorArray.toString());

To answer your quesstion regarding Hidden properties, I have this method, that tries to apply expression to a property (check function isHidden()). If it succeeds - then the property is hidden, if it fails - property is visible. We all wish there were an API to check if property is hidden, but there isn't;

Also I have this snippet that retrieves all visible colors from a selected layer. I collect them all into an array colorProperties and then can do what ever I like with them, like adding expressions or whatever (not included in the snippet)

Anyways, I hope this helps you out.

Cheers.

(function() {

    var composition = app.project.activeItem;

    if (!composition || !(composition instanceof CompItem)) {

        return alert("Please select composition first");

    }

    var layer = composition.selectedLayers[0];

    if (!layer) {

        return alert('Please select a layer');

    }

    var colorProperties = getProperties(layer, isVisibleColorPropery);

    alert("Found " + colorProperties.length + " properties:\n" + colorProperties.join('\n'));

    function isVisibleColorPropery(property) {

        return  property.propertyValueType === PropertyValueType.COLOR && !isHidden(property);

    }

    function isHidden(property) {

        var oldExpression = property.expression;

        try {

            // try to add some dummy expression;

            // If it errors out - this means property is hidden

            // overwise property can be modified

            property.expression = "some dummy expression;";

        } catch (e) {

            return true;

        }

        // Set expression to it's old value;

        property.expression = oldExpression;

        return false;

    }

    function getProperties(property, callback, colorProperties) {

        colorProperties = colorProperties || [];

        var curProperty;

        for (var i = 1, il = property.numProperties; i <= il; i++) {

            curProperty = property.property(i);

            if (callback(curProperty)) {

                colorProperties.push(curProperty.matchName);

            }

            getProperties(curProperty, callback, colorProperties);

        }

        return colorProperties;

    }

})();

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