17 Replies Latest reply on Jan 7, 2015 3:25 PM by williamadowling

    Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path

    williamadowling Level 4

      Hello again everyone.

       

      I've been able to work out a bunch of this code from other people's questions, but i've hit a snag in my if/else clause structure.. I need to make an artboard around each top level groupItem on layer[0]. That part is cake.. unless there's a clipping mask. Visible bounds don't work when there's a clipping mask. So i built some for loops that cycle through the pathItems to search for the clipping mask and return the visibleBounds of said mask. However, i can't seem to work out how to structure the if clause in a way that will create the artboard around the clipping mask if there is one.

       

      I'm successfully finding the visibleBounds of the mask and creating the appropriate artboard, but it's ALSO creating an artboard around the visible bounds of the entire group. How would i structure an if clause to determine whether an artboard was made around the clip path already and thus, not create a second artboard around the visible bounds of the whole groupItem? i imagine i'd need some kind of function to determine whether createdArtboardAroundClip = true and if so, skip this group..

       

      Thanks all.

       

      here's the code:

       

      var aB = docRef.artboards;
      var docLayers = docRef.layers;
      var layer1 = docLayers[0];
      var groupLevel1 = layer1.groupItems;
      
      for (a = 0; a < groupLevel1.length; a++){
          var groupLevel2 = groupLevel1[a].groupItems;
          var vB = groupLevel1[a].visibleBounds
          
          for (b = 0; b < groupLevel2.length; b++){
              var paths = groupLevel2[b].pathItems;
              
              for (c = 0; c < paths.length; c++){
                  if (paths[c].clipping == true){
                      var clipBounds = paths[c].visibleBounds;
                      aB.add(clipBounds);
                      break;
                      }
                  }
              }
          aB.add(vB);
          }
      
        • 1. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
          pixxxel schubser Level 5

          Hi williamadowling,

          try this for your "firstlevel groups" on your layer 1

          var docRef = app.activeDocument;
          var aB = docRef.artboards;
          //var aB_0 = aB[docRef.artboards.getActiveArtboardIndex()];
          var docLayers = docRef.layers;
          var layer1 = docLayers[0];
          var groupLevel1 = layer1.groupItems;
          
          for (a = 0; a < groupLevel1.length; a++){
              //var groupLevel2 = groupLevel1[a].groupItems;
              if(groupLevel1[a].pathItems[0].clipping == false) {
                  var vB = groupLevel1[a].visibleBounds;
                  } else {
                      var vB = groupLevel1[a].pathItems[0].visibleBounds;
                      }
                  aB.add(vB);
                  }
              //aB_0.remove();
          
          
          

           

          Here is my layers hierarchy:

          IlluArtboardsAroundGroups.png

           

          Have fun

           

          • 2. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
            williamadowling Level 4

            can you explain that a little? i don't really understand what's going on there.

             

            i want to avoid looking at a specific index **groupLevel1[a].pathItems[0].clipping** because the clipping mask could be anywhere within that group.

             

            can i loop through the indexes for the pathItems of groupLevel1[a]?

            • 3. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
              pixxxel schubser Level 5

              I've added a screenshot of my own layers hierarchy to my previous posting at this moment.

               

              Can you show me the same of yours, please?

              • 4. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                Silly-V Adobe Community Professional

                hey, you can probably use the continue keyword in the for loop once you've set up a flag to let you know if something's already been created.

                • 5. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                  williamadowling Level 4

                  pixxxel schubser

                   

                  here's that screenshot.

                  Screen Shot 2015-01-07 at 8.48.29 AM.jpg

                   

                  Silly-V

                   

                  could you elaborate on that a little more? i think i understand what the continue keyword does, but i don't really know how to set up a flag or use said flag/continue combination to do what i'm looking for here..

                   

                   

                  what i had in mind was to push the parent index to an array if an artboard was created around the clip mask.. something like this

                   

                  var dontMakeAB = [];

                   

                  for (loop through top level groups){

                       for(loop through group items within top level groups){

                            var paths = groupLevel2[b].pathItems

                            for (c=0; c< paths.length; c++){

                                 if (paths[c]clipping == true){

                                      var clipBounds = paths[c].visibleBounds;

                                      aB.add(clipBounds);

                                      dontMakeAB.push(paths[c].parent.index)

                   

                  but i already know that's not really going to work because it's calling out the parent of 'paths' which is <Clip Group> in the screenshot above. I don't know how to go back farther to get the "groupLayer1[index]" and at that point.. how to use that index to negate a future artboard..

                   

                  am i way off base here? pixxxel it seems like your solution is much more elegant.. but i just don't understand how it works at all. (in fact, when i copied that into my code, it didn't work.. but that could just be because i was unsure where to put it or how to use it).

                   

                   

                  EDIT***

                   

                  or what about a function to determine simply weather the clipping mask exists instead of building that if clause into the for loop? example:

                   

                  var ifClipped = function(){

                       loop through path items in each 2nd level group

                       if paths have clipping masks

                            make global variable for bounds of clip mask

                            return true

                       else

                            return false

                  }

                   

                  for (loop through top level groups){

                       for (loop through group items within top level groups){

                                 if (ifClipped){

                                      make artboard at bounds of global clip mask variable created in the function

                                      }

                                 else {

                                      make artboard at bounds of top level group

                  • 6. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                    Silly-V Adobe Community Professional

                    So now it's kind-of getting confusatory here, so I'd like to step back a moment and offer a different approach.  Through the screenshots it looks like you want to put artboards around art objects, and the visible bounds with clip paths is complicating things.  I offer you my own technique for this: make your target art group selected (groupItem.selected = true), make a new artboard and use document.artboards.fitToSelectedArt() to fit the temporary board to the edges of your art group.  Then, you will be able to resize your new board if you need buffer on edges.  This will work CS5 and up, that I know of.

                    • 7. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                      Silly-V Adobe Community Professional

                      If you use the approach you have now, you will potentially need to go through all the pathitems in your group to see if one of them is clipping == true, or something.  However, if you recall our last conversation about groupitem and layers references, you would have to dig through your entire group recursively to find the one you are looking for.  Still, you can make this process easier as well, using what I call the "selection hack"  where you make your group selected, and then use Document.pathitems collection to go through it and if(pathItem.selected == true), then it's a path item in your selected group.  Although you must be aware that with complex art of many hundreds or thousands of paths , this may have a slowing effect on your script.

                      • 8. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                        williamadowling Level 4

                        your first comment here is correct. clip paths are complicating things. however, not so much that i can't work with that. i've gotten to the point where my script creates every artboard that i need. but then it creates one extra one. creating the artboard around the clip mask is not the problem at all. (and as to your second suggestion regarding the selection hack.. i want to avoid that because while most of our art files are relatively small, i'd like to keep the computing as simple as possible so that if and when we do get to a file that is overly complex, we don't get any wrenches thrown into the works).

                         

                        i think i have it worked out.. i just don't know how to define a global variable from inside a for loop (or function). how do i go about doing that?

                        • 9. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                          Silly-V Adobe Community Professional

                          Your variable has to be outside the for-loop:

                           

                          var flag = false;

                           

                          for(var i=0; i<doc.layers.length; i++){

                               if(doc.layers[i].name == 'Special Name'){

                                    flag = true;

                               }

                               if(flag == false){

                                    // do the thing

                               }

                          };

                           

                          Is this correct?

                          • 10. Re: Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                            williamadowling Level 4

                            that looks right.. the problem i'm having is that the if clause you wrote above will be nested inside a couple of for loops. i set up my flag as "clipped" to make it easier for me to identify. so if clipped == true, then i want it to create an artboard around the visible bounds of the clip mask. that part works great. but then i hit a snag when it comes to applying the artboards to the objects wherein clipped == false. i can't do that task within that for loop or it creates an artboard around every 2nd level group (i end up with several artboards around each piece of art.. one for each sub group within groupLevel1). and i can't do that task outside of the for loop without creating an additional artboard around that artwork (one artboard around the clipping mask and then another around the visual bounds of the group).

                             

                            sorry, i know i'm not explaining this right.. but i don't know how else to word it. see the attached screenshot. the red box is the one i need. i am currently able to create this artboard with this snippet (inside of the for loops):

                             

                            for (c = 0; c < paths.length; c++){
                                        if (paths[c].clipping == true){
                                            var clipBounds = paths[c].visibleBounds;
                            //~                 alert(c + " index" + clipBounds)
                                            aB.add(clipBounds);
                                            break;
                                            }
                                        }
                            

                             

                            This part of the code works great and creates the artboard i want (the red one in the screenshot). problem is, if there is no clipping mask found, then no artboard is created (hence, line 21 of the code i originally posted). but creating artboards with bounds vB at that point in the loop negates the search for the clipping mask because it creates each artboard around the visible bounds of each top level group (even the ones that already got an artboard applied to the clipping mask, so any art that includes a clipping mask gets two artboards, represented by the red and blue squares in screenshot).

                             

                            now. the logical thing to do is to put an else statement to create an artboard around "groupLevel1[a]" if (paths[c].clipping == false).

                             

                            for (c = 0; c < paths.length; c++){
                                        if (paths[c].clipping == true){
                                            var clipBounds = paths[c].visibleBounds;
                            //~                 alert(c + " index" + clipBounds)
                                            aB.add(clipBounds);
                                            break;
                                            }
                                        else {
                                            aB.add(vB);
                                            break;
                            

                             

                            But that creates an artboard around "groupLevel1[a]" every time it loops through.. so if there are 5 groupItems inside of "groupLevel1[a]" i get 5 artboards at that size and location.

                             

                            Screen Shot 2015-01-07 at 11.54.12 AM.jpg

                            • 11. Re: Re: Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                              williamadowling Level 4

                              this is my most current block of code.. i was really confident this would work, but it doesnt.. = (

                               

                              var docRef = app.activeDocument;
                              var aB = docRef.artboards;
                              var docLayers = docRef.layers;
                              var layer1 = docLayers[0];
                              var groupLevel1 = layer1.groupItems;
                              var clipped = false;
                              var selec = docRef.selection;
                              var clipBounds = false;
                              
                              for (a = 0; a < groupLevel1.length; a++){
                                  var groupLevel2 = groupLevel1[a].groupItems;
                                  var vB = groupLevel1[a].visibleBounds
                                  clipped = false;
                                  for (b = 0; b < groupLevel2.length; b++){
                                      var paths = groupLevel2[b].pathItems;
                                      for (c = 0; c < paths.length; c++){
                                          if (paths[c].clipping == true){
                                              clipBounds = paths[c].visibleBounds;
                              //~                alert(c + " index" + clipBounds)
                                              clipped = true;
                                              break;
                                              }
                                          else {
                                              clipped = false;
                                              }
                                          }
                                  if (clipped == true){
                                      aB.add(clipBounds);
                                      alert("Group " + a + " has a clipping mask");
                                      }
                                  else if (clipped == false){
                                      aB.add(vB);
                                      }
                                  }
                              }
                              
                              • 12. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                Silly-V Adobe Community Professional

                                Hey, can you please post the screenshot of your layers expanded ?   I'd like a clearer picture of your stacking order, because it looks like you are using visible bounds from groupLevel1[a], while you really want the ones from groupLevel2[b]   

                                • 13. Re: Re: Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                  williamadowling Level 4

                                  i tagged you in a comment above where i posted the layers panel.

                                   

                                  groupLevel1[a] is the sum total of all objects i want to be inside the artboard.

                                   

                                  groupLevel2[b] could be any number of groups within that top group (which may be smaller than the desired artboard) and thus, i do not want to use that group. for example, in the screenshot of my layers i posted earlier, the left hand side is the front of a shirt. the top level group (groupLevel1) is every piece of artwork on the front of the shirt. the second level group (groupLevel2) could be the entirety of the front logo. I wouldn't want to use groupLevel2 to create the artboard because that would create an artboard just around the front logo.

                                  • 14. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                    Silly-V Adobe Community Professional

                                    Oh sorry, I forgot about that one.  I was able to view the image big to see what's up.  Okay, so I saw a problem there, you have one of your closing braces out of place.   Your first nested for-loop does not close where you want it to.  2015-01-07 14_49_19-_ Source3.jpg

                                    • 15. Re: Re: Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                      williamadowling Level 4

                                      bloody brilliant! man that makes a lot of sense. i thought i was finally there.. all the pieces seemed to fit and the theory seemed right.. wow. i'm going to have to be a lot more careful in the future and more diligent about nesting things properly.. i think that sort of thing happens often because i'm constantly deleting and rewriting lines or blocks to try out another idea. and then the tabs and spacing get messed up and i get confused.

                                       

                                      i think that for a while, until i get more comfortable, i'm going to start labeling the close braces as i create them so i know which belong to what.

                                       

                                      wow.. thank you so much for all your help on that! i was going mad. it seemed so easy.. and at the same time always just out of reach.

                                      • 16. Re: Re: Re: Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                        pixxxel schubser Level 5

                                        williamadowling,

                                        after seeing your screenshot I can say:

                                        Silly-Vs way makes sense.

                                         

                                         

                                        But you are a little to complicated. Give this codesnippet a chance:

                                        var docRef = app.activeDocument;
                                        var groupLevel1 = docRef.layers[0].groupItems;
                                        
                                        for (a = 0; a < groupLevel1.length; a++){
                                            if(groupLevel1[a].clipped == true) {
                                                alert("Group "+ a + " is a clipped group");
                                                // read groupLevel1[a].pathItems[0] bounds
                                                } else {
                                                    // read the pathItems bounds
                                                    }
                                                }
                                        
                                        
                                        

                                         

                                        And please – be careful with the word clipped. This is a property and should do not be used as a variable.

                                        Have fun

                                         

                                        • 17. Re: Create artboard around group, unless there's a clipping path, then create the artboard around the clipping path
                                          williamadowling Level 4

                                          thanks pixxxel schubser,

                                           

                                          however i don't think that would do what i wanted. the clipping mask i'm looking for (if my artists are doing their job properly) should never reside on the outside of "groupLevel1[a]". the clipping mask is inside of that group, often within another group.

                                           

                                          additionally, if you see the screenshot i posted above as to the order of my layer structure, you'll see that even once you get to the "Clip Group", the clipping mask is inside of that "Clip Group". if i get the visible bounds of "Clip Group", i'll be in the same boat i was to begin with as the visible bounds of "Clip Group" include the artwork that spills out of the clipping mask. it's important for me to get the bounds of ONLY the clipping path.

                                           

                                          your snippet reminds me though that i need to plan for the possibility that "Clip Group" is nested in the first group..