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

Problem setting fill colors with JSFL

New Here ,
Jun 04, 2014 Jun 04, 2014

I am attempting to write a JSFL script to replace the fill colors of shape elements in selected frames using a mapping table.

I can access a shape's fill properties but I cannot set them even though the documentation leads me to believe these properties are read/write.

When I omit the element.beginEdit() and element.endEdit() calls, the script completes successfully but the colors are not actually updated. When I include the beginEdit/endEdit my script crashes the first time i access the fill property with the error message "The following JavaScript error(s) occurred:" with no other information.

I have tried this in CS5.5, CS6 and CC, and it always fails the same way.

Am I doing something wrong or is it a bug? If it is a bug, has anyone found a work around? I appreciate any tips you can give me.

The script:

var replaceFills = {   

     '#ff0000': '#33cccc',   

     '#33cccc': '#ff0000',   

     '#66ff00': '#00ffff',

     '#00ffff': '#66ff00',

     '#2173a6': '#ff00ff',

     '#ff00ff': '#2173a6',

     '#195480': '#ff00ff',

     '#ff00ff': '#195480', };

function recolor(element) {

     if (element.elementType == "shape") {

         element.beginEdit();

         for (var j = 0; j < element.contours.length; j++) {

             var c = element.contours;

             if (c.interior) {

                 if (c.fill.style == 'solid') {

                     if (c.fill.color in replaceFills) {

                         c.fill.color = replaceFills[c.fill.color];

                     }

                 }

             }

         }

         element.endEdit();

     }

}

function recolorFrame(frame) {

     var elements = frame.elements;

     for (var i = 0; i < elements.length; i++)

         recolor(elements);

}

var curSelected = fl.getDocumentDOM().getTimeline().getSelectedFrames();

for (var i = 0; i < curSelected.length; i += 3) {

     var layerIndex = curSelected;

     var startIndex = curSelected[i + 1];

     var endIndex = curSelected[i + 2];

     var layer = fl.getDocumentDOM().getTimeline().layers[layerIndex];

     for (var j = startIndex; j < endIndex; j++) {

         var frame = layer.frames;

         if (j == frame.startFrame)

             recolorFrame(frame);

     }

}

Thanks,

Bill

TOPICS
Exchange extensions
2.0K
Translate
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
Guide ,
Jun 05, 2014 Jun 05, 2014

Is it possible that you're trying to access the fill of a contour with a null fill? I don't see any null checks in your code.

Translate
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
New Here ,
Jun 05, 2014 Jun 05, 2014

Thanks for the tip but even accessing the fill field like if(!c.fill) fl.trace("Null fill"); results in the same error. The contour c is definitely not null because the c.interior check works.

Translate
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
Guide ,
Jun 06, 2014 Jun 06, 2014

Just to make sure I'm understanding you--you've tried it with just

if (!c.fill) {

     fl.trace('null fill');

}

and you've removed all references to c.fill.color and c.fill.style? And that still errors?

Also, what happens if you remove the empty element from your array?

Translate
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
Guide ,
Jun 06, 2014 Jun 06, 2014

OK, it looks like you can only get a usable fill object with getCustomFill(). So, if you need to edit on a per-contour basis, you're probably SOL. However, I found that this code works for one object on one frame. You'll probably need to edit it to make sure each object is selected before you fill it.

function recolorFrame(frame) {

     var elements = frame.elements;

     for (var i = 0; i < elements.length; i++) {
         recolor(elements);
  }
}

function recolor(element) {
if (element.elementType == "shape") {
        var fill = fl.getDocumentDOM().getCustomFill(element);
       fill.color = '#FF0000';
       fl.getDocumentDOM().setCustomFill(fill);
}
}

var curSelected = fl.getDocumentDOM().getTimeline().getSelectedFrames();

for (var i = 0; i < curSelected.length; i += 3) {

     var layerIndex = curSelected;

     var startIndex = curSelected[i + 1];

     var endIndex = curSelected[i + 2];

     var layer = fl.getDocumentDOM().getTimeline().layers[layerIndex];

     for (var j = startIndex; j < endIndex; j++) {

         var frame = layer.frames;

         if (j == frame.startFrame) recolorFrame(frame);

     }

}

Translate
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
New Here ,
Jun 06, 2014 Jun 06, 2014

Thanks for your help. I do need to change the fill per contour and since I don't think I can select a contour via jsfl I guess what I want to do is not possible.

It seems odd though that the fill attribute is not modifiable. The docs don't say anything about it being read only.

Translate
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
Guide ,
Jun 06, 2014 Jun 06, 2014
LATEST

The docs do say that the way to get a fill is through getCustomFill().

One thing you may find useful is that Search and Replace can operate per "scene", which translates to the local timeline, and it will remember your color choices. So you can use that if you can open each timeline and apply it, then repeat for the next color. You may even find something in the History when you do that that will help you.

Translate
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