6 Replies Latest reply on Dec 7, 2013 7:07 AM by fruityth1ng

    Make a clipping Path while retaining it's appearance - script

    fruityth1ng Level 1

      This has been a long standing wish of mine, and I've devised this script that "kind of" works.

       

      This script takes your selection, copies appearance attributes, and pastes them to the top object after clipping.

       

      It's currently limited in a few ways:

      • It does not accept compound paths as clipping object (and I don't know how to test for it, nor how to iterate down said compound clipping object to set each path object to clipping separately)

      • It only works with a single stroke or fill

      • It does not understand "no fill" it will fill your object with white instead *FIXED*

      • I'm hoping to use the "graphicStyle" property to copy the appearance, since that sounds way cleaner. But I don't understand how to.

       

       

      Even with these limitations, I bound this to CMD+7 using fastscripts - I'm *already* used to it working this way!

      Carlos Santos, thank you for writing the base of what became this script

       

      I'd be much obliged if anyone can help me out with any of those limitations / wishes.

       

      #target Illustrator
      
      //  script.name = Clip Retaining Color.jsx;
      //  script.required = at least two paths selected, top most path is the clipping mask;
      //  script.parent = Herman van Boeijen, www.nimbling.com // 30/11/13;
      //  *** LIMITED TO A SINGLE STROKE AND/OR FILL OF THE CLIPPING OBJECT***
      //  Here's hoping to use the "graphicStyles" property to copy over the appearance.
      
      
      if ( app.documents.length > 0 ) {
          idoc = app.activeDocument;
      }else{
          Window.alert("You must open at least one document.");
      }
      
      
      var idoc = app.activeDocument; // get active document;
      var sel = idoc.selection; // get selection
      var selectedobjects = sel.length;
      
      
      function ClipRetainingColour(idoc){
          var lay = activeDocument.activeLayer
          if(lay.locked || !lay.visible){
              alert("Please select objects on an unlocked and visible layer,\nthen run this script again.");
              return;
          }
      
      
          var igroup = lay.groupItems.add(); // add a group that will be the clipping mask group
          var imask = sel[0]; // the mask is the object on top
      
      
          var clipcolors = [];
      
      
          //copy appearance
          if(imask.filled)     {clipcolors.fillColor = imask.fillColor;} 
          if(imask.stroked)    {
              clipcolors.stroked = imask.stroked;
              clipcolors.strokeWidth = imask.strokeWidth;
              clipcolors.strokeColor = imask.strokeColor;
          }  
          for (var i = selectedobjects-1 ; i > 0 ; i--){
              var ipath = sel[i];
              ipath.move(igroup, ElementPlacement.PLACEATBEGINNING);
          }
          imask.move (igroup, ElementPlacement.PLACEATBEGINNING);
          
          //enable clipping
          igroup.clipped = true;
          imask.clipping = true;
      
      
          //paste appearance
          if(clipcolors.fillColor)    {imask.fillColor = clipcolors.fillColor;}
          if(clipcolors.stroked)      {
              imask.stroked = clipcolors.stroked;
              imask.strokeWidth = clipcolors.strokeWidth;
              imask.strokeColor = clipcolors.strokeColor;
          }
      }
      
      
      if (selectedobjects){
          ClipRetainingColour(idoc);
      }
      
      
      
        • 1. Re: Make a clipping Path while retaining it's appearance - script
          CarlosCanto Adobe Community Professional & MVP

          • I'm hoping to use the "graphicStyle" property to copy the appearance, since that sounds way cleaner. But I don't understand how to.

          create a graphic style manually, then apply it like this

           

          idoc.graphicStyles['GraphicStyleName'].applyTo(imask);
          

           

          but still, no multi-strokes are allowed as clipping masks

          1 person found this helpful
          • 2. Re: Make a clipping Path while retaining it's appearance - script
            fruityth1ng Level 1

            • Carlos, I see I misspelled your name, sorry.

            • The graphicstyle wish was while still hoping to be able to use multiple strokes, seeing that's not in the cards, I think what's in place works fine.

            • The one thing a regular illustrator clip has over this script for now is being able to use compound paths as clipping paths, would you know how to test for one, and set that "group" as the clipping path?

             

            I'm still really happy this is working as is, it fits my clipping workflow much better than the standard clipping path behavior

             

            *EDIT* I replaced

                    //enable clipping
                    imask.clipping = true;
                    igroup.clipped = true;
            

             

            with

             

                if (imask.typename === "CompoundPathItem") {
                    for (var c = 0; c < imask.pathItems.length; c++) {
                        imask.pathItems[c].clipping = true;
                    }
                    igroup.clipped = true;
                }
                else {
                    //enable clipping
                    imask.clipping = true;
                    igroup.clipped = true;
                }
            

             

            but that throws an error at the "igroup.clipped" line telling me top item in the group needs to be a path to create a mask. Would you know how to make it one?

             

            Message was edited by: fruityth1ng, to include code changes and an error message.

            • 3. Re: Make a clipping Path while retaining it's appearance - script
              fruityth1ng Level 1

              I've been hacking at this for two nights straight, to no avail.

               

              While I have learned that clipping groups only accept a regular path as a clipping path, illustrator itself *does* do it.

               

              My theory is now to get this to work on compound paths I need to:

              1: deconstruct the compound path

              2: use the first path of the compound path as a clipping path for the group

              3: add the rest of the compound path parts to the clipping path after that

               

              Do you reckon that's correct?

               

              Oh wait...

              Screen Shot 2013-12-05 at 01.09.54.png

               

              Any advice would be greatly appreciated. I sincerely think that once that feature is in, it's a more than valid replacement for the regular clipping command.

              • 4. Re: Make a clipping Path while retaining it's appearance - script
                CarlosCanto Adobe Community Professional & MVP

                as you have noticed, illustrator just refuses to accept compound paths as clipping masks via javascript...if you have CS6 or CC, try applying a menu command, not sure if that particular command is available.

                • 5. Re: Make a clipping Path while retaining it's appearance - script
                  fruityth1ng Level 1

                  Wow! using the menucommand really shortens the script

                  And illustrator takes care of the clipping using a compound path. Genius.

                  All I need to do now, when it's a compound path, is:

                   

                  * Look for the top compound path in the selection

                  * Paste appearance to that

                   

                  And I keep not being able to find the right way to address that object.

                  Could you help me construct that line?

                  Many thanks!

                   

                   

                  #target Illustrator
                  
                  //  script.name = Clip Retaining Color.jsx;
                  //  script.required = at least two paths selected, top most path is the clipping mask;
                  
                  if ( app.documents.length > 0 ) {
                      idoc = app.activeDocument;
                  }else{
                      Window.alert("You must open at least one document.");
                  }
                  
                  var idoc = app.activeDocument; // get active document;
                  var sel = idoc.selection; // get selection
                  var selectedobjects = sel.length;
                  var clipobject = sel[0]; // the mask is the object on top
                  var clipcolors = [];
                  
                  //copy appearance
                  if(clipobject.filled)  {clipcolors.fillColor = clipobject.fillColor;} 
                  if(clipobject.stroked) {clipcolors.stroked = clipobject.stroked; clipcolors.strokeWidth = clipobject.strokeWidth; clipcolors.strokeColor = clipobject.strokeColor;}
                  
                  function ClipRetainingColour(idoc){
                      var lay = idoc.activeLayer;
                      if(lay.locked || !lay.visible){
                          alert("Please select objects on an unlocked and visible layer,\nthen run this script again.");
                          return;
                      }
                  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  //IF COMPOUND CLIPPING PATH
                      if (clipobject.typename === "CompoundPathItem") {
                          app.executeMenuCommand ('makeMask');
                  
                  //Since making the clipping path changed the selection, set variable for selection again
                  
                  //Look for the top compound path in the selection
                  
                  //paste appearance
                  }
                  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  //IF REGULAR PATH
                      else {
                          app.executeMenuCommand ('makeMask');
                  
                  //paste appearance
                          if(clipcolors.fillColor)    {clipobject.fillColor = clipcolors.fillColor;}
                          if(clipcolors.stroked)      {
                              clipobject.stroked = clipcolors.stroked;
                              clipobject.strokeWidth = clipcolors.strokeWidth;
                              clipobject.strokeColor = clipcolors.strokeColor;
                          }        
                      }
                  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  }
                  
                  if (selectedobjects){
                      ClipRetainingColour(idoc);
                  }
                  

                   

                   

                  In the data browser, the groupitem I have selected looks like this, I think. How do I address it? Again, many thanks!

                  Screen Shot 2013-12-06 at 13.22.06.png

                  • 6. Re: Make a clipping Path while retaining it's appearance - script
                    fruityth1ng Level 1

                    *FIXED IT* - it's working!

                    I bound this to CMD+7 using the excellent Fastscripts

                    My clipping paths will be so much more colorful from now on!

                    Yay!

                     

                    #target Illustrator
                    #targetengine main
                    
                    
                    //  script.name = Clip Retaining Color.jsx;
                    //  script.required = at least two paths selected, top most path is the clipping mask;
                    //  script.parent = Herman van Boeijen, www.nimbling.com // 07/12/13;
                    //  *** LIMITED TO A SINGLE STROKE AND/OR FILL OF THE CLIPPING OBJECT***
                    //  Big thanks to CarlosCanto and MuppetMark on the Adobe Illustrator Scripting Forums, and my pal Niels Bom for showing me the debugger (...)
                    
                    
                    if ( app.documents.length > 0 ) {
                        var curDoc = app.activeDocument;
                    }else{
                        Window.alert("You must open at least one document.");
                    }
                    
                    
                    var sel = curDoc.selection; // get selection
                    var selectedobjects = sel.length;
                    var clipobject = sel[0]; // the mask is the object on top
                    var clipcolors = [];
                    //var pathItems = [];
                    var container = curDoc.activeLayer;
                    
                    
                    //Only if there are objects selected
                    if (selectedobjects){
                        if(container.locked || !container.visible){
                            alert("Please select objects on an unlocked and visible layer,\nthen run this script again.");
                        }else{
                        ClipRetCol(curDoc);
                        }
                    }
                    
                    
                    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    function ClipRetCol(curDoc){
                        //IF COMPOUND CLIPPING PATH
                            if (clipobject.typename === "CompoundPathItem") {
                                //copy appearance
                                sel = curDoc.selection;
                                clipobject = sel[0].pathItems[0];
                                CopyAppearance(clipobject);
                    
                                //MAKEMASK
                                app.executeMenuCommand ('makeMask');
                                //Since making the clipping path changed the selection, set variable for selection again
                                sel = curDoc.selection;
                                clipobject = sel[0];
                                clipobject = clipobject.pageItems[0].pathItems[1];
                                PasteAppearance(clipobject);
                    
                    
                        }
                        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                        //IF REGULAR PATH
                            else {
                                //copy appearance
                                CopyAppearance(clipobject);
                    
                    
                                //MAKEMASK
                                app.executeMenuCommand ('makeMask');
                    
                    
                                //paste appearance
                                PasteAppearance(clipobject);
                            }
                    }//ClipRetCol END
                    
                    
                    function CopyAppearance(clipobject) {
                                if(clipobject.filled)  {
                                    clipcolors.fillColor = clipobject.fillColor;}
                                if(clipobject.stroked) {
                                    clipcolors.stroked = clipobject.stroked;
                                    clipcolors.strokeWidth = clipobject.strokeWidth;
                                    clipcolors.strokeColor = clipobject.strokeColor;}
                    }//CopyAppearance END
                    
                    
                    function PasteAppearance(clipobject) {
                                if(clipcolors.fillColor)    {
                                    clipobject.fillColor = clipcolors.fillColor;}
                                if(clipcolors.stroked)      {
                                    clipobject.stroked = clipcolors.stroked;
                                    clipobject.strokeWidth = clipcolors.strokeWidth;
                                    clipobject.strokeColor = clipcolors.strokeColor;}
                    }//PasteAppearance END