10 Replies Latest reply: Jul 12, 2012 10:59 PM by Laubender RSS

    How would I scale every object to some percent?

    alexthebake Community Member

      Hi,

       

      I'm working on a script that creates elements, and occasionally changes the size of the page. I want to add a parameter to my Dialog box called "scale." It should be a percentage value, and it should simply scale all objects to that percentage.

      The point of this parameter would be to accomodate InDesign Page size limit. The only way I can think of to implement this would be to multiply every single number I have by that percent. However, this seems like a lot of work, and it seems like the sub-optimal approach.

       

      Is there some other way to implement this?

        • 1. Re: How would I scale every object to some percent?
          Larry G. Schneider CommunityMVP

          One approach might be to group all the items on the page, scale the group and then ungroup.

          • 2. Re: How would I scale every object to some percent?
            Laubender CommunityMVP

            And to refine this approach that Larry mentioned:

            do the grouping of the objects layer by layer, so you will not have all the objects in one layer after ungrouping.

             

            To start  all that, you do not work directly with the page object, but with the window object and set its activePage to the page you want. As a second ingredience of this recipe we have the "activeLayer" object of the window object.

             

            var myDoc = app.documents[0];
            var myActivePage = myDoc.windows[0].activePage = myPageThatIsChangedInSize;
            
            //Loop through all the layers of "myDoc":
            for(var n=0;n<myDoc.layers.length;n++){
                var myActiveLayer = myDoc.windows[0].activeLayer = myDoc.layers[n];
            
                //Case 1: there are more than 1 page items in the active layer:
                if(myActiveLayer.pageItems.length>1){
                    //Unlock all pageItems:
                    myActiveLayer.pageItems.everyItem().locked = false;
                    //Add a group with all page items on the active layer:
                    var myGroup = myActivePage.groups.add(myActiveLayer.pageItems.everyItem());
                    //myGroup.scale();
                    //myGroup.ungroup();
                    };
            
                //Case 2: there is only 1 page item in the active layer and you cannot group 1 single item:
                if(myActiveLayer.pageItems.length==1){
                    //No need to group something, just scale:
                    myActiveLayer.pageItems[0].locked = false;
                    //myActiveLayer.pageItems[0].scale();
                    }; 
            
                };
            

             

            As center of the scaling you have to use the center of your active page.
            Caution: With that approach all objects on the pasteboard are also scaled.

             

            Of course you can further refine the script and store the IDs of all locked pageItems in an array for locking again after scaling them.

             

            Hope that helps…

             

            Uwe

            • 3. Re: How would I scale every object to some percent?
              Trevorׅ Community Member

              Uwe

               

              Nice answer but won't you run into problems of grouping groups if there are groups already on the page, which is if I remember a bit complicated.

               

              Trevor

              • 4. Re: How would I scale every object to some percent?
                Trevorׅ Community Member

                Sorry Uwe

                 

                My mistake, does work with grouped objects, (I decided to test the script)

                 

                However you do have to change the second line to

                var myActivePage  = myPageThatIsChangedInSize = myDoc.windows[0].activePage;

                 

                Trevor

                • 5. Re: How would I scale every object to some percent?
                  Laubender CommunityMVP

                  @Trevor – that "myPageThatIsChangedInSize" is just a dummy variable.

                  You can set it to any value provided it is a valid page object.

                   

                  //Example for the first page of your document:
                  var myActivePage = myDoc.windows[0].activePage = myDoc.pages[0];
                  

                   

                  Uwe

                  • 6. Re: How would I scale every object to some percent?
                    Trevorׅ Community Member

                    Uwe

                     

                     

                    I should have understood that.

                     

                    Just 2 points

                     

                    1) Case 2 should come before case 1 otherwise case 2 will always be applied after the grouping and the object will be scaled twice

                    2) When the active layer has graphics on other pages (could well happen ) then the line

                    var myGroup = myActivePage.groups.add(myActiveLayer.pageItems.everyItem())
                    

                    is no good

                     

                    Trevor

                    • 7. Re: How would I scale every object to some percent?
                      Muppet Mark Community Member

                      I will chip in as I have tried this before but not full sucess… May be someone can see the errors of my ways? Some parts I just can't get to play…

                      Firstly I don't like the idea of grouping to scale/transform ( goofs layers and no need ). You can use the scale tool on selection and scale without grouping?

                      If you want page items then you could just target by page that way it no effect the pasteboard items…

                      If you want to apply a scale factor to pre-existing art why not transform it? Thats what I would do in the GUI…

                      Anyhows you can try this snippet it scales all the page stuff in my basic test file… But I can only get it to do so from page centre? You could move it all after but that was not what I was trying to achieve…

                       

                      #target indesign
                      #targetengine muppet
                      
                      app.activate();
                      
                      app.transformPreferences.whenScaling = WhenScalingOptions.APPLY_TO_CONTENT;
                      app.transformPreferences.adjustStrokeWeightWhenScaling = true;
                      app.transformPreferences.dimensionsIncludeStrokeWeight = true;
                      app.transformPreferences.transformationsAreTotals = false;
                      app.transformPreferences.showContentOffset = false;
                      
                      var scMat = app.transformationMatrices.add( 1.5, 1.5 ); //150% scale matrix
                      
                      var doc = app.activeDocument;
                      
                      //$.writeln( doc.layoutWindows.item(0).transformReferencePoint );
                      
                      doc.layoutWindows.item(0).transformReferencePoint = [0,0]; // Can't get this to play?
                                                     
                      var pItems = doc.pages.item(0).pageItems.everyItem().getElements();
                      
                      //var p = doc.pages.item(0).allPageItems; Wrong one… not the same as above
                      
                      for ( var i = 0; i < pItems.length; i++ ) {
                        
                                $.writeln( pItems[i].visibleBounds[0] + ' ' + pItems[i].visibleBounds[1] );
                        
                                try {
                        
                                pItems[i].transform( CoordinateSpaces.SPREAD_COORDINATES,
                        
                                          [ -pItems[i].visibleBounds[0], -pItems[i].visibleBounds[1] ], scMat ); // Hum what I do wrong here?
                        
                                } catch(e) { $.writeln(e) }; // This value would cause one or more objects to leave the pasteboard.
                        
                      };
                      
                      • 8. Re: How would I scale every object to some percent?
                        absqua Community Member

                        I agree that grouping seems like an unnecessary and potentially destructive step to accomplish this.

                         

                        You need to set the second ("from") argument to transform to the same point for every transform() call. So, this:

                         

                        var origin = doc.pages.item(0).resolve(AnchorPoint.TOP_LEFT_ANCHOR,CoordinateSpaces.SPREAD_COORDINATES)[0];
                        

                         

                        after your doc declaration, to anchor everything to the top left of the page. (You could set it to the top-left of your top-leftmost page item or somewhere else instead.)

                         

                        And then this:

                         

                        pItems[i].transform( CoordinateSpaces.SPREAD_COORDINATES, origin, scMat );
                        

                         

                        for your transform() call.

                         

                        See this post from Marc: http://forums.adobe.com/message/4179133#4179133 .

                         

                        Jeff

                        • 9. Re: How would I scale every object to some percent?
                          Muppet Mark Community Member

                          Oh thanks Jeff not seen that… I will take a look and see where I went wrong… I would have expected my negative use of bounds to have been the page origin… may be not?

                          • 10. Re: How would I scale every object to some percent?
                            Laubender CommunityMVP

                            @Trevor – you are absolutely right. I used the wrong scope with the layer object, that includes all pages. That would only work in one spread documents or documents with objects only on one spread.

                             

                            To make this all work with groups (you see, I still have not abandoned the idea of scaling groups completely) we could go through all page items of the page we want to scale using the itemLayer property to sort after layer and act on that information for building groups…

                             

                            Uwe