15 Replies Latest reply on Nov 19, 2015 1:53 AM by 212dfcascas

    How to align items (groupItem) with clipping masks?

    212dfcascas

      I have a script that aligns an groupItemToBeAligned on one layer to another referenceGroupItem on another layer, so far so good. Problem comes when the groupItemToBeAligned consists of items that have clipping masks, simply using

       

      groupItemToBeAligned.position = referenceGroupItem.position;
      
      

       

      Doesn't work, it's taking the position of everything, what's the best method to align what's actually visible ? I tried using:

       

      var vBounds = referenceGroupItem.visibleBounds;
      x1 = vBounds[0];
      y1 = vBounds[1];
      x2 = vBounds[2];
      y2 = vBounds[3];
      groupItemToBeAligned.position = [x1, y1];
      
      

       

      Produces the same results unfortunately.

        • 1. Re: How to align items (groupItem) with clipping masks?
          Vinicius Baptista Level 2

          Hello 212dfcascas

           

          Man, just make sure the object is "Clipped" if "true", use the coordinates of the "pageItems[0]" of him, like this:

           

          Select two objects before perform this script:

           

          if(app.selection[0].clipped){
              var referenceGroupItem = app.activeDocument.selection[0].pageItems[0];
              }else{
                  var referenceGroupItem = app.activeDocument.selection[0];
                  };
          
          
          if(app.selection[1].clipped){
              var groupItemToBeAligned = app.activeDocument.selection[1].pageItems[0];
              }else{
                  var groupItemToBeAligned = app.activeDocument.selection[1];
                  };
              
          var groupItemToBeAligned = app.activeDocument.selection[1];
          var vBounds = referenceGroupItem.visibleBounds;  
          x1 = vBounds[0];  
          y1 = vBounds[1];  
          x2 = vBounds[2];  
          y2 = vBounds[3];  
          groupItemToBeAligned.position = [x1, y1];
          

           

          to more informations see this post: Re: Get Clipping Path dimensions

           

          I hope helped you.

          Enjoy

          • 2. Re: How to align items (groupItem) with clipping masks?
            212dfcascas Level 1

            Thanks for your help! Unfortunately it still doesn't align, I should clarify, the groupItemToBeAligned is made of many items, some have a clipping mask, others do not, does that matter? Do I need to cycle through each item in a group… or something?

             

            Also doesn't line 14 break line 9 (it's the same as line 11?), I tried with and without the line and still doesn't work btw

             

            This is my script It works if it is a simple case of an object, and another clipped object. The way I use it is I have many artboards and 2 layers. For every artboard, the top layer has a group item, this group item contains several items, some clipped (I think almost all the clipped items are meshes), some are not clipped. I want the group item in the top layer to align to the item in the bottom layer.

            var myDoc = app.activeDocument;
            
            
            for (var i = 0; i < myDoc.artboards.length; i++ ) {
                var artboard = myDoc.artboards[i];
                thisArtboard = myDoc.artboards.setActiveArtboardIndex(i);
                // $.writeln(artboard);
            
            
                myDoc.selectObjectsOnActiveArtboard();
            
            
                var referenceItem = null;
                var itemToBeAligned = null;
                var items = selection;
                // var clippedSelection = null;
                // $.writeln(items);
            
            
                if (selection[0].clipped){
                    var clippedSelection[0] = selection[0].pageItems[0];
                    }else{
                        var clippedSelection[0] = selection[0];
                };
            
            
                if (selection[1].clipped){
                    var clippedSelection[1] = selection[1].pageItems[0];
                    }else{
                        var clippedSelection[1] = selection[1];
                };
            
            
                topLayer = documents[0].layers[1];
                bottomLayer = documents[0].layers[0];
            
            
                if ( ( null == topLayer ) || ( null == bottomLayer ) )
                {
                    alert("Error");
                }
                else
                {
                    for ( x = 0; x != 2; ++x )
                    {
                        if ( clippsedSelection[ x ].layer == bottomLayer )
                        {
                            referenceItem = clippsedSelection[ x ];
                        }
                        else if ( clippsedSelection[ x ].layer == topLayer )
                        {
                            itemToBeAligned = clippsedSelection[ x ];
                        }
                    }
                    // $.writeln(itemToBeAligned.position);
                    // $.writeln(referenceItem.position);
            
            
                    var vBounds = referenceItem.visibleBounds;
            
            
                    x1 = vBounds[0];
                    y1 = vBounds[1];
                    x2 = vBounds[2];
                    y2 = vBounds[3];
            
            
                    // itemToBeAligned.position = referenceItem.position;
                    itemToBeAligned.position = [x1,y1];
                }
            }
            redraw();
            
            
            
            
            • 4. Re: How to align items (groupItem) with clipping masks?
              Vinicius Baptista Level 2

              Hello again man, see the video below:

               

              https://www.sendspace.com/file/zp3w8k

               

              Your question is answered but, there's some error in your code, today I'll try to find it, see ya!

               

              -Vinícius

              • 5. Re: How to align items (groupItem) with clipping masks?
                212dfcascas Level 1

                Hey Vinícius

                Thanks for your reply again!


                Let me show you my video of what I'm trying to do, I can also attach the file I'm trying to align here.

                 

                File:

                Dropbox - test-doc.ai

                Video:

                https://www.dropbox.com/s/8k8eb7945n0kaqy/script.mov?dl=1

                And my new script which tries to loop through every clipped object and find the left-most and top-most object clipping object to use for alignment and use the difference.

                // Match object in the first layer to the object in the second layer in each artboard
                
                
                var myDoc = app.activeDocument;
                
                
                for (var i = 0; i < myDoc.artboards.length; i++ ) {
                    var artboard = myDoc.artboards[i];
                    thisArtboard = myDoc.artboards.setActiveArtboardIndex(i);
                    // $.writeln(artboard);
                
                
                    myDoc.selectObjectsOnActiveArtboard();
                
                
                    var referenceItem = null;
                    var itemToBeAligned = null;
                    var items = selection;
                    // $.writeln(items);
                
                
                    topLayer = myDoc.layers[0];
                    bottomLayer = myDoc.layers[1];
                
                
                    if ( ( null == topLayer ) || ( null == bottomLayer ) )
                    {
                        alert("Error");
                    }
                    else
                    {
                        for ( x = 0; x != 2; ++x )
                        {
                            if ( items[ x ].layer == bottomLayer )
                            {
                                referenceItem = items[ x ];
                            }
                            else if ( items[ x ].layer == topLayer )
                            {
                                itemToBeAligned = items[ x ];
                            }
                        }
                
                
                        var listOfClipMaskBoundsx = [];
                        var listOfClipMaskBoundsy = [];
                
                
                        for (var k = 0; k < itemToBeAligned.pathItems.length; k++ ) {
                            var thisPageItem = itemToBeAligned.pathItems[k]
                            if (thisPageItem.clipping = true){
                                var pageItemBounds = thisPageItem.visibleBounds;
                                $.writeln("x ", pageItemBounds[0]);
                                listOfClipMaskBoundsx.push(pageItemBounds[0]);
                                $.writeln("y ", pageItemBounds[1]);
                                listOfClipMaskBoundsy.push(pageItemBounds[1]);
                            }
                        }
                
                
                        $.writeln("list x ", listOfClipMaskBoundsx);
                        $.writeln("list y ", listOfClipMaskBoundsy);
                        var leftMostVisiblex = Math.min.apply(Math, listOfClipMaskBoundsx);
                        var topMostVisibley = Math.max.apply(Math, listOfClipMaskBoundsy);
                        $.writeln("left ", leftMostVisiblex);
                        $.writeln("top ", topMostVisibley);
                
                
                        var vBoundsRef = referenceItem.visibleBounds;
                        xR = vBoundsRef[0];
                        yR = vBoundsRef[1];
                
                
                        var vBoundsItem = itemToBeAligned.visibleBounds;
                        xI = vBoundsItem[0];
                        yI = vBoundsItem[1];
                
                
                        // itemToBeAligned.position = referenceItem.position;
                        itemToBeAligned.position = [xI-(leftMostVisiblex-xR),yI-(topMostVisibley-yR)];
                    }
                }
                redraw();
                
                
                
                
                • 6. Re: How to align items (groupItem) with clipping masks?
                  Vinicius Baptista Level 2

                  Humm, exactly as I imagined, I'm writing a code to try solve this. I hope I can. lol

                   

                  Let's talking, see ya

                   

                  -Vinícius

                  • 7. Re: How to align items (groupItem) with clipping masks?
                    williamadowling Level 4

                    You just need to dig into the objects to find the path whose clipped property is true. then use that path to set the coordinates for alignment. For some stupid unknowable reason ESTK sets the 'visible' bounds to the entire contents of the clipping masks.. even the invisible parts...

                     

                    In theory it's pretty easy because the clipping path should always be at the top. But things get sticky when you have a complex group that contains clipping masks.

                    • 8. Re: How to align items (groupItem) with clipping masks?
                      212dfcascas Level 1

                      Yes, not so easy either when I have a group with more than one clipping masks.

                      • 9. Re: How to align items (groupItem) with clipping masks?
                        williamadowling Level 4

                        Understood. Unfortunately that's the only way. Until Adobe changes the way javascript views visibleBounds, we'll always have to dig into the group to find the clipping mask and then do our transformations based on that.

                         

                        It's typically a good bet that you're looking for the top-most clipping mask in the object, so the function necessary isn't too difficult.

                         

                        Just start at the very top level of the group and check all the pathItems to see if they're clipping masks. if none are, then loop through the groupItems to check the pathItems within each group.

                         

                        If your artwork is fairly consistent and predictable, you can hard code the loops to the necessary depth, otherwise if the art is unpredictable, you'll need a recursive function to dig indefinitely until it finds the first instance of a clipping mask.

                        • 10. Re: How to align items (groupItem) with clipping masks?
                          212dfcascas Level 1

                          Thanks williamdowling, Would you be able to give an example of how to loop through a group? I'm trying with the above script but it crashes… many thanks

                          • 11. Re: How to align items (groupItem) with clipping masks?
                            williamadowling Level 4

                            Ok. it took me a little longer than i would like to admit to figure out the relatively simple math involved in moving aligning the visible parts of the clipping mask, but huzzah. I've done it.

                             

                            As to why your script was crashing i couldn't say. I saw a number of issues in there (inconsistencies in loop syntax, assignment operators in places where there should have been equality operators and a few variables that were declared and never used) so it seemed easier to re-write everything from scratch. I tried to put the most descriptive comments i could so you would know what's happening and when, but if you still don't understand or need clarification, please ask. =)

                             

                            function align(){
                                var myDoc = app.activeDocument;
                                var aB = myDoc.artboards;
                                var layers = myDoc.layers;
                            
                            
                                for(var a=0;a<aB.length;a++){
                                    aB.setActiveArtboardIndex(a);
                                    myDoc.selectObjectsOnActiveArtboard();
                            
                            
                                    var reference; // this is the object we wan to align to.. AKA Key object
                                    var obj; // this is the object we want to align.
                                    var items = myDoc.selection;
                            
                            
                                    var topLayer = layers[0];
                                    var botLayer = layers[1];
                            
                            
                            
                            
                                    if(topLayer =! null || botLayer =! null){
                                        for(var b=0;b<2;b++){
                                            if(items[b].layer == botLayer){
                                                reference = items[b];
                                            }
                                            else if(items[b].laer = topLayer){
                                                obj = items[b];
                                            }
                                        }
                            
                            
                                        //recursive function digs into groupItems until
                                        //it finds the first clipping path, then returns
                                        //the clipping path that serves as the bounds visible to us.
                                        function findClip(thisGroup){
                                            var item;
                                            for(var b=0;b<thisGroup.pageItems.length;b++){
                                                item = thisGroup.pageItems[b];
                                                if(item.clipping){
                                                    return item;
                                                }
                                            }
                                            if(thisGroup.groupItems.length>0){
                                                for(var b=0;b<thisGroup.groupItems.length;b++){
                                                    var inGroup = thisGroup.groupItems[b];
                                                    return findClip(inGroup);
                                                }
                                            }
                                        }
                            
                            
                                        //the next 2 lines find the top-most clipping path.
                                        //for all intents and purposes, this is the "visible bounds"
                                        //as they should be. this object will be used for final positioning.
                                        var refClip = findClip(reference);
                                        var objClip = findClip(obj);
                            
                            
                                        //determines the extraneous, invisible, extra art
                                        //on the left side and top of the objects so that
                                        //that measurement can be ignored during placement
                                        var objExtraLeft = objClip.left - obj.left;
                                        var objExtraTop = obj.top - objClip.top;
                                        var refExtraLeft = refClip.left - reference.left;
                                        var refExtraTop = reference.top - refClip.top;
                            
                            
                                        //determine top and left coordinates for object
                                        //to be aligned.
                                        var left = reference.left + (refExtraLeft-objExtraLeft);
                                        var top = reference.top - (refExtraTop - objExtraTop);
                            
                            
                                        //move object to be aligned into position
                                        obj.left = left;
                                        obj.top = top;
                            
                            
                            
                            
                                    }
                                    else{
                                        alert("You're missing a layer!");
                                    }
                                }
                            }
                            align();
                            
                            • 12. Re: How to align items (groupItem) with clipping masks?
                              t23gagzg Level 1

                              Thank you so much for taking to the time to try solve this puzzle!

                              I tried the script but it still doesn't align, I am using this file to test it.

                              Dropbox - test-doc.ai

                              Screen Shot 2015-11-18 at 3.01.08 pm.pngScreen Shot 2015-11-18 at 3.01.07 pm.png

                              Note each group has several clipping mask, and it needs to align to the top-most and left-most clipped object.

                               

                              I modified the script to not process the reference object as it is a single object.

                              function align(){
                                  var myDoc = app.activeDocument;
                                  var aB = myDoc.artboards;
                                  var layers = myDoc.layers;
                              
                              
                                  for(var a=0;a<aB.length;a++){
                                      aB.setActiveArtboardIndex(a);
                                      myDoc.selectObjectsOnActiveArtboard();
                              
                              
                                      var reference; // this is the object we wan to align to.. AKA Key object
                                      var obj; // this is the object we want to align.
                                      var items = myDoc.selection;
                              
                              
                                      var topLayer = layers[0];
                                      var botLayer = layers[1];
                              
                              
                              
                              
                                      if(topLayer =! null || botLayer =! null){
                                          for(var b=0;b<2;b++){
                                              if(items[b].layer == botLayer){
                                                  reference = items[b];
                                              }
                                              else if(items[b].laer = topLayer){
                                                  obj = items[b];
                                              }
                                          }
                              
                              
                                          //recursive function digs into groupItems until
                                          //it finds the first clipping path, then returns
                                          //the clipping path that serves as the bounds visible to us.
                                          function findClip(thisGroup){
                                              var item;
                                              for(var b=0;b<thisGroup.pageItems.length;b++){
                                                  item = thisGroup.pageItems[b];
                                                  if(item.clipping){
                                                      return item;
                                                  }
                                              }
                                              if(thisGroup.groupItems.length>0){
                                                  for(var b=0;b<thisGroup.groupItems.length;b++){
                                                      var inGroup = thisGroup.groupItems[b];
                                                      return findClip(inGroup);
                                                  }
                                              }
                                          }
                              
                              
                                          //the next 2 lines find the top-most clipping path.
                                          //for all intents and purposes, this is the "visible bounds"
                                          //as they should be. this object will be used for final positioning.
                                          var objClip = findClip(obj);
                              
                              
                                          //determines the extraneous, invisible, extra art
                                          //on the left side and top of the objects so that
                                          //that measurement can be ignored during placement
                                          var objExtraLeft = objClip.left - obj.left;
                                          var objExtraTop = obj.top - objClip.top;
                              
                              
                                          //determine top and left coordinates for object
                                          //to be aligned.
                                          var left = reference.left - objExtraLeft;
                                          var top = reference.top + objExtraTop;
                              
                              
                                          //move object to be aligned into position
                                          obj.left = left;
                                          obj.top = top;
                              
                              
                                      }
                                      else{
                                          alert("You're missing a layer!");
                                      }
                                  }
                              }
                              align();
                              
                              
                              
                              
                              
                              
                              

                               

                              I tried to solve this problem of detecting the top-most and left-most here with the following version of the script, and it looks like it's not looping through each clipping mask?

                              If you see the console, "All L" shoudl be all the left, i.e. 2 items, instead there is only one

                               

                              Artboard 0

                              Group Item: 0

                              All L: -258.311776100257

                              All T: 339.395659174326

                              mostLeft: -258.311776100257

                              mostTop: 339.395659174326

                               

                              function align(){
                                  var myDoc = app.activeDocument;
                                  var aB = myDoc.artboards;
                                  var layers = myDoc.layers;
                              
                              
                                  for(var a=0;a<aB.length;a++){
                                      $.writeln("\nArtboard ", a);
                              
                              
                                      aB.setActiveArtboardIndex(a);
                                      myDoc.selectObjectsOnActiveArtboard();
                              
                              
                                      var reference; // this is the object we wan to align to.. AKA Key object
                                      var obj; // this is the object we want to align.
                                      var items = myDoc.selection;
                              
                              
                                      var topLayer = layers[0];
                                      var botLayer = layers[1];
                              
                              
                                      if(topLayer =! null || botLayer =! null){
                                          for(var b=0;b<2;b++){
                                              if(items[b].layer == botLayer){
                                                  reference = items[b];
                                              }
                                              else if(items[b].laer = topLayer){
                                                  obj = items[b];
                                              }
                                          }
                              
                              
                                          //recursive function digs into groupItems until
                                          //it finds the first clipping path, then returns
                                          //the clipping path that serves as the bounds visible to us.
                                          function returnPosition(thisGroup, listOfLeft, listOfTop){
                                              var item;
                                              var lefts = listOfLeft;
                                              var tops = listOfTop;
                              
                              
                                              for(var b=0;b<thisGroup.pageItems.length;b++){
                                                  item = thisGroup.pageItems[b];
                                                  if(item.clipping){
                                                      // return item;
                                                      lefts.push(item.left);
                                                      tops.push(item.top);
                                                      $.writeln("Group Item: ", b, "\n", "L: ", item.left, "\nT: ", item.top);
                                                  }
                                              }
                              
                              
                                              if(thisGroup.groupItems.length>0){
                                                  for(var b=0;b<thisGroup.groupItems.length;b++){
                                                      var inGroup = thisGroup.groupItems[b];
                                                      return returnPosition(inGroup, lefts, tops);
                                                  }
                                              }
                              
                              
                                              $.writeln("All L: ", lefts, "\n", "All T: ", tops);
                                              var mostLeft = Math.min.apply(Math, lefts);
                                              var mostTop = Math.max.apply(Math, tops);
                                              $.writeln("mostLeft: ", mostLeft, "\nmostTop: ", mostTop);
                                              return [mostLeft, mostTop];
                                          }
                              
                              
                                          //the next 2 lines find the top-most clipping path.
                                          //for all intents and purposes, this is the "visible bounds"
                                          //as they should be. this object will be used for final positioning.
                                          var objClip = returnPosition(obj, [], []);
                              
                              
                                          //determines the extraneous, invisible, extra art
                                          //on the left side and top of the objects so that
                                          //that measurement can be ignored during placement
                                          var objExtraLeft = objClip[0] - obj.left;
                                          var objExtraTop = objClip[1] - obj.top;
                              
                              
                                          // $.writeln(objExtraLeft, " ", objExtraTop)
                                          //determine top and left coordinates for object
                                          //to be aligned.
                                          var left = reference.left - objExtraLeft;
                                          var top = reference.top + objExtraTop;
                              
                              
                                          //move object to be aligned into position
                                          obj.left = left;
                                          obj.top = top;
                              
                              
                                      }
                                      else{
                                          alert("You're missing a layer!");
                                      }
                                  }
                              }
                              align();
                              
                              
                              
                              
                              • 13. Re: How to align items (groupItem) with clipping masks?
                                williamadowling Level 4

                                Ok, i looked at the file you posted, and i see why my script wasn't working.. but my question i guess is why is the artwork created that way??? why don't you just use a hexagon to clip all of the artwork inside? why do you have a group of different clipping masks that create a shape instead of using a shape to create the clipping mask?

                                 

                                Anyway.. neither here nor there. Not my place.

                                 

                                Upon quick review, based on your comment about not looping through all the clipping paths, i notice that you have an if statement out of place (beginning on line 55).

                                 

                                line 55, that reads "if(thisGroup.groupItems.length>0){" needs to be inside of the for loop above it, like this:

                                 

                                for(var b=0;b<thisGroup.pageItems.length;b++){ 

                                    item = thisGroup.pageItems[b]; 

                                    if(item.clipping){ 

                                        // return item; 

                                        lefts.push(item.left); 

                                        tops.push(item.top); 

                                        $.writeln("Group Item: ", b, "\n", "L: ", item.left, "\nT: ", item.top); 

                                    } 

                                    if(thisGroup.groupItems.length>0){ 

                                        for(var c=0;c<thisGroup.groupItems.length;c++){  //embarrasing note.. i realize i originally had a nested loop that used the same variable as the parent loop.... fixed that this time..

                                            var inGroup = thisGroup.groupItems[c]; 

                                            return returnPosition(inGroup, lefts, tops); 

                                        } 

                                    }

                                }

                                 

                                 

                                in order for the recursion to work, you need to check all of the loose pathItems to see if they're clipping paths first, then loop through all of the groupItems. The way you had it, you were executing the for loop on the pageItems of thisGroup and only checking whether any of those were clipping masks. then after that loop was finished, then you were looking into the groupItems.

                                 

                                Let me dig around in this and see if i can't get it working for the test file you sent. It is a HUGE help to test the script on the actual file rather than some bogus file that i built based on assumptions of what you're trying to do. So thanks. =)

                                • 14. Re: How to align items (groupItem) with clipping masks?
                                  williamadowling Level 4

                                  Huzzah, yet again! I can't express how much it helps to have the actual file you're working with. This version aligns perfectly on all artboards. Let me know if you have any other issues. =)

                                   

                                  function align(){  
                                      var myDoc = app.activeDocument;  
                                      var aB = myDoc.artboards;  
                                      var layers = myDoc.layers;
                                      
                                    
                                    
                                      for(var a=0;a<aB.length;a++){
                                          var masks = []; 
                                          myDoc.selection = null;
                                          aB.setActiveArtboardIndex(a);  
                                          myDoc.selectObjectsOnActiveArtboard();  
                                    
                                    
                                          var reference; // this is the object we wan to align to.. AKA Key object  
                                          var obj; // this is the object we want to align.
                                          var items = myDoc.selection;  
                                    
                                    
                                          var topLayer = layers[0];  
                                          var botLayer = layers[1];  
                                          
                                          
                                    
                                    
                                    
                                          if(topLayer =! null || botLayer =! null){  
                                              for(var b=0;b<2;b++){  
                                                  if(items[b].layer == botLayer){  
                                                      reference = items[b];  
                                                  }  
                                                  else if(items[b].layer = topLayer){  
                                                      obj = items[b];
                                                  }  
                                              }  
                                    
                                    
                                              //recursive function digs into groupItems to find all
                                              //clipping masks present on the current artboard.
                                              //pushes all clipping masks to 'masks' array.  
                                              function findClips(thisGroup){  
                                                  var item;  
                                                  for(var b=0;b<thisGroup.pageItems.length;b++){  
                                                      item = thisGroup.pageItems[b];  
                                                      if(item.clipping){  
                                                          masks.push(item); 
                                                      }  
                                                  }  
                                                  if(thisGroup.groupItems.length>0){  
                                                      for(var b=0;b<thisGroup.groupItems.length;b++){  
                                                          var inGroup = thisGroup.groupItems[b];  
                                                          findClips(inGroup);  
                                                      }  
                                                  }
                                  
                                  
                                              }  
                                  
                                  
                                              //searches masks array for the clipping mask with highest top value
                                              function findTop(masks){
                                                  var topMost;
                                                  for(var b=0;b<masks.length;b++){
                                                      if(b==0){
                                                          topMost = masks[b];
                                                      }
                                                      else if(masks[b].top > topMost.top){
                                                          topMost = masks[b];
                                                      }
                                                  }
                                                  return topMost.top;
                                              }
                                  
                                  
                                              //searches masks array for clipping mask with farthest left value
                                              function findLeft(masks){
                                                  var leftMost;
                                                  for(var b=0;b<masks.length;b++){
                                                      if(b==0){
                                                          leftMost = masks[b];
                                                      }
                                                      else if(masks[b].left < leftMost.left){
                                                          leftMost = masks[b];
                                                      }
                                                  }
                                                  return leftMost.left;
                                              }
                                    
                                    
                                              //populate masks array
                                              findClips(obj);
                                  
                                  
                                              //find highest and farthest left clipping mask coordinates
                                              var clipLeft = findLeft(masks);
                                              var clipTop = findTop(masks);
                                               
                                    
                                    
                                              //determines the extraneous, invisible, extra art  
                                              //on the left side and top of the objects so that  
                                              //that measurement can be ignored during placement  
                                              var objExtraLeft = clipLeft - obj.left;  
                                              var objExtraTop = obj.top - clipTop; 
                                  
                                  
                                    
                                    
                                              //determine top and left coordinates for object  
                                              //to be aligned.  
                                              var left = reference.left - objExtraLeft;  
                                              var top = reference.top + objExtraTop;
                                    
                                    
                                              //move object to be aligned into position  
                                              obj.left = left;  
                                              obj.top = top;  
                                    
                                          }  
                                          else{  
                                              alert("You're missing a layer!");  
                                          }  
                                      }  
                                  }  
                                  align();  
                                  
                                  • 15. Re: How to align items (groupItem) with clipping masks?
                                    212dfcascas Level 1

                                    Genius!!! Thank you so much for your help! Works perfect. This has been a really great learning experience for me too.