6 Replies Latest reply on Jul 31, 2017 9:00 AM by williamadowling

    Script to Rename Artboards Based on Layers (and Reverse)

    sensibleworld Level 1

      A couple of years ago I had some awesome help making a couple of scripts to rename layers based on the containing artboard (Re: Script to Rename Artboards with Layer Names). One problem posed (and solved) was:

       

      - Each artboard has a name.

      - Each layer NEEDS a name.

      - There are an equal number of layers and artboards.

      - Only one layer "exists" on each artboard. (i.e. They share coordinates.)

      - I would like to name the layer with the same name as its encompassing artboard.

       

      The solution was:

       

      function artboardLayerNameMatch() {  
          if (app.documents.length == 0) {  
              alert("No Open / Active Document Found");  
          } else {  
              var doc, i, l, ab, sel, n;  
              doc = app.activeDocument;  
              for (i = 0, l = doc.artboards.length; i < l; i++) {  
                  ab = doc.artboards[i];  
                  doc.artboards.setActiveArtboardIndex(i);  
                  doc.selectObjectsOnActiveArtboard();  
                  sel = doc.selection[0];  
                  sel.parent.name = ab.name;  
                  doc.selection = false;  
              }  
          }  
      }  
      artboardLayerNameMatch(); 
      

       

      Now, I'm wondering if the reverse is also possible?

       

      The new scenario is:

      • Each layer has a name.
      • Each artboard NEEDS a name.
      • There are an equal number of layers and artboards.
      • Only one layer "exists" on each artboard. (i.e. They share coordinates.)
      • I would like to name the artboard with the same name as the layer that resides “on” it
        • 1. Re: Script to Rename Artboards Based on Layers (and Reverse)
          williamadowling Level 4

          Here's the inelegant, not very efficient pseudo-code. real code to follow:

           

          if # of layers == # of artboards

               for each layer

                    select all artwork on current layer

                    bounds = visibleBounds of first item in selection array

                    for each artboard

                         if bounds +/- buffer overlaps current artboard

                              current artboard.name = current layer.name

                              break

          else

               alert 'there must be an equal number of artboards and layers'

          • 2. Re: Script to Rename Artboards Based on Layers (and Reverse)
            williamadowling Level 4

            Here you go. This is certainly not nearly as robust as it could be, but it gets the job done.

             

            function container()
            {
                var docRef = app.activeDocument;
                var layers = docRef.layers;
                var aB = docRef.artboards;
            
            
                var curLay, curAb, rect, sel, bounds, aBounds, intersect = false;
                var aBLen = aB.length,
                    layLen = layers.length;
            
            
                function isIntersect(sel, ab)
                {
                    return !(sel.l > ab.r || sel.r < ab.l || sel.t < ab.b || sel.b > ab.t);
                }
            
            
                if (aBLen === layLen)
                {
                    //clear out the selection
                    docRef.selection = null;
            
            
                    //loop the layers
                    for (var x = 0; x < layLen; x++)
                    {
                        curLay = layers[x];
                        curLay.hasSelectedArtwork = true;
                        sel = docRef.selection[0];
                        bounds = {
                            l: sel.left,
                            t: sel.top,
                            r: sel.left + sel.width,
                            b: sel.top - sel.height
                        };
            
            
                        for (var y = 0; y < aBLen && !intersect; y++)
                        {
                            curAb = aB[y];
                            rect = curAb.artboardRect;
                            aBounds = {
                                l: rect[0],
                                t: rect[1],
                                r: rect[2],
                                b: rect[3]
                            };
                            if (isIntersect(bounds, aBounds))
                            {
                                intersect = true;
                                curAb.name = curLay.name;
                            }
                        }
                        intersect = false;
                        docRef.selection = null;
                    }
                }
                else
                {
                    alert("You need to have a matching number of artboards and layers.");
                }
            }
            container();
            
            • 3. Re: Script to Rename Artboards Based on Layers (and Reverse)
              sensibleworld Level 1

              Works like a charm! Wow. Thank you so much, williamadowling!

              • 5. Re: Script to Rename Artboards Based on Layers (and Reverse)
                Silly-V Adobe Community Professional

                Would ya look at what a couple of years here in the forums can do! This code is that of a seasoned veteran

                • 6. Re: Script to Rename Artboards Based on Layers (and Reverse)
                  williamadowling Level 4

                  Well thanks, V. That means a lot coming from you.

                   

                  I have to give all the credit to the brilliant and helpful minds on this forum. And a special shoutout to someone who will never read this comment, Daniel Shiffman of NYU and The Coding Train (on youtube), for the significantly more efficient and cleaner intersection detection method.

                   

                  Even though nobody asked, i'll elaborate. In a previous version of one of my flagship scripts here at work, i used to use this very long winded and confusing method of checking for overlap:

                   

                  function intersect(art, dest) {
                              var intersect = false;
                              var artBounds = art.geometricBounds;
                              var destBounds = dest.geometricBounds;
                  
                  
                              var AL = artBounds[0];
                              var AT = artBounds[1];
                              var AR = artBounds[2];
                              var AB = artBounds[3];
                  
                  
                              var DL = destBounds[0];
                              var DT = destBounds[1];
                              var DR = destBounds[2];
                              var DB = destBounds[3];
                  
                  
                              //check for intersection of 1 or 2 sides 
                              //this part breaks down if 3 sides are intersected 
                              if (((AL >= DL && AL <= DR) || (AR >= DL && AR <= DR)) && ((AT <= DT && AT >= DB) || (AB <= DT && AB >= DB)))
                              //this art intersects this destination on one or two sides 
                                  intersect = true;
                              else if ((((AL <= DR && AL >= DL) || (AL <= DL && AR >= DL)) && (AT >= DT && AB <= DB)) || (((AB <= DT && AB >= DB) || (AT >= DB && AT <= DT)) && AL <= DL && AR >= DR)) {
                                  //art covers 3 sides of dest piece
                                  intersect = true;
                              } else if (AT >= DT && AR >= DR && AB <= DB && AL <= DL) {
                                  //art completely covers dest piece
                                  intersect = true;
                              }
                  
                  
                              return intersect;
                          }
                  

                   

                   

                  Daniel, in one of his many many brilliant youtube videos, pointed out that you can save yourself tons of calculations by simply looking for a single condition that would make an overlap impossible (like the right edge of something being further left than the left edge of the potential dest), rather than looking for a series of conditions that all need to be true to achieve a true result.

                   

                  So this concludes the unsolicited presentation about efficient overlap detection.