18 Replies Latest reply: May 10, 2013 1:48 PM by theplu RSS

    Can I batch create symbols from layers?

    theplu Community Member

      I have Illustrator files of some fairly complicated schematics that I will be bringing in to Flash. The layers are already well organized and named so I would like to select particular layers, hit a "create symbols" button and have all of the selected layers turned into separate symbols that have the same name as their layer name. I would even be willing to code something to do this but I can't find any information about how it can be done.

       

      I know that I can import an Illustrator file into Flash and select layers that I can then make into movie clips but again, I have to manually select the layer, tell it to be a movie clip and then give it an instance name. I would be happy to try to automate that process as well but haven't found any info on how it can be done either.

       

      Does anyone have any ideas on how I can batch create symbols from my existing layers?

        • 1. Re: Can I batch create symbols from layers?
          CarlosCanto MVP

          I would even be willing to code something to do this but I can't find any information about how it can be done.

           

           

          check the Scripting Reference it has plenty of samples, this one is for creating symbols

           

          Creating a symbol
          // Creates a path item from each graphic style
          // then adds each item as a new symbol
          var docRef = documents.add();
          var y = 750;
          var x =25;
          var iCount = docRef.graphicStyles.length;
          for(var i=0; i<iCount; i++) {
          var pathRef = docRef.pathItems.rectangle( y, x, 20, 20 );
          docRef.graphicStyles[i].applyTo(pathRef);
          // are we at bottom?
          if( (y-=60) <= 60 ) {
          y = 750; // go back to the top.
          x+= 200
          }
          redraw();
          docRef.symbols.add(pathRef);
          }
          
          • 2. Re: Can I batch create symbols from layers?
            theplu Community Member

            Thanks so much Carlos! I haven't touched Flash since AS2 so I'm just getting started with AS3 and Flash Builder. I'm still learning where to even look for reference materials! And I didn't even know if Illustrator really was open to scripting from the outside. I will check into this!

             

            Thanks again!

            • 3. Re: Can I batch create symbols from layers?
              CarlosCanto MVP

              Illustrator gets scripted from the inside, javascript (crossplatform), applescript and vbscript

               

              here are the guides

              http://www.adobe.com/devnet/illustrator/scripting.html

              • 4. Re: Can I batch create symbols from layers?
                theplu Community Member

                Wow thanks! I know JavaScript so that'll work. I really appreciate your quick replies!

                 

                Sent from my iPhone

                • 5. Re: Can I batch create symbols from layers?
                  theplu Community Member

                  Hi Carlos,

                   

                  I was able to write a little Javascript to pick up the sublayers and make them into symbols but I need for the symbols to be movie clips. In the reference documentation, I don't see where I can set that. The "add" method only takes 2 properties. I would think since I can do it manually, I should be able to do it via scripting. Any ideas?

                   

                  Thanks!

                  • 6. Re: Can I batch create symbols from layers?
                    CarlosCanto MVP

                    unfortunately not everything is exposed to scripting, type of clip is one of those things, but the sample above created "movie" by default.

                     

                    are you getting "graphic" in your script?

                    • 7. Re: Can I batch create symbols from layers?
                      theplu Community Member

                      As I feared. It does seem to just be creating a "graphic" - when I bring my ai file into Flash Pro, the symbols I created via script aren't listed as movie clips but the ones I created manually are. Here's my script..

                       

                      var docRef = app.activeDocument;

                      var layersRef = app.activeDocument.layers;

                      var layersCount = layersRef.length;

                      var pgItems = null;

                       

                      for(var i = layersCount - 1; i >=0; i--) {

                          // get top layer

                          var topLayer = docRef.layers[i];

                          //alert("top layer: " + topLayer.name);

                         

                          if(topLayer.layers.length > 0) {

                             

                              // get sub layers

                              for(var ii = topLayer.layers.length - 1; ii >=0; ii--) {

                                  var subLayer = topLayer.layers[ii];

                                  //alert("sub layer: " + subLayer.name);

                                  //alert("sub layer length: " + subLayer.groupItems.length);

                                 

                                  // create a group

                                  var grp = subLayer.groupItems.add();

                                  // get all page items from layers

                                  var items = subLayer.pageItems;

                                  //alert("items: " + items);

                                 

                                  // add page items to the group

                                  for (var pi= items.length-1; pi >0; pi--)

                                  {

                                      //alert("items length: " + items.length);

                                      items[pi].moveToBeginning(grp);

                                  }

                       

                                  // create symbols from all items in the group

                                  var symbolRef = docRef.symbols.add(grp);

                                  // give symbol the same name as the layer

                                  symbolRef.name = subLayer.name;

                                 

                                  // get sub layers' sub layers

                                  if(subLayer.groupItems.length > 0) {

                                      for(var iii = subLayer.groupItems.length - 1; iii >=0; iii--) {

                                          var subGroupItems = subLayer.groupItems[iii];

                                          //alert("sub group items: " + subGroupItems);

                                      }

                                  }

                              }

                         

                          }

                      • 8. Re: Can I batch create symbols from layers?
                        theplu Community Member

                        Actually, the interesting thing is that if I look at my scripted symbols -> symbol options, the type does in fact say "Movie Clip" but Flash doesn't read them in as movie clips in the same way that it does a manually created one. Odd. Still investigating! Thanks again for your assistance and expertise! (I used some of your older posts to help me in creating the code above so thanks for that as well!)

                        • 9. Re: Can I batch create symbols from layers?
                          theplu Community Member

                          ok, some more information. When importing to Flash, the manual symbols are seen as "symbol" ("Symbol import options for 'label'") whereas the script generated symbols are seen as a "group" ("Group import options for 'LRU'")

                          • 10. Re: Can I batch create symbols from layers?
                            CarlosCanto MVP

                            you're welcome, I made a test with your script and it does import the symbols as movie clips into Flash...but my test consisted of simple shapes and text, I wonder if the problem is dependent on what kind of art is being made into symbols.

                            • 11. Re: Can I batch create symbols from layers?
                              theplu Community Member

                              I did a simple test as well and here are my results: The text layer was made into a symbol via my script (it creates the group below it and that is added to the symbol as it would seem that groupItems are the only thing that symbols.add seems to work with). The square was then made into a symbol manually. When I import the file, the square gets the movie clip icon and comes in with an instance name that is the same as the symbol. This is what I want to have happen. The text doesn't seem to recognize the movie clip type and when I select it, it says that it's a group.

                               

                              ai_test.jpg

                              • 12. Re: Can I batch create symbols from layers?
                                CarlosCanto MVP

                                I see you used import to stage, I did import to Library, unchecked "Check Illustrator layers to import" and down below I checked "import unused symbols" that brought up all symbols and art to the Library.

                                 

                                what happens I think, is that the script creates symbols but don't automatically links the art to the symbol it just created, while manually creating a symbol does. Then when you import to the stage, I guess it imports what's on the Ai Artboard (just art, not symbol instances).

                                • 13. Re: Can I batch create symbols from layers?
                                  theplu Community Member

                                  I had a feeling showing a visual might help. In other words, it would appear that the symbol is created from something on the art board but the original asset is still being used rather than the symbol. Got it. Hmm.. Well, at least I can get movie clips but it's still not very automated if I have to then manually put them into place. I'll keep working on it to see if I can come up with a solution for that issue.

                                   

                                  Thanks again!

                                  • 14. Re: Can I batch create symbols from layers?
                                    CarlosCanto MVP

                                    after you turn your artObject into a symbol, you have to add it to the canvas var mysymbolInstance = docRef.symbolItems.add(yourSymbol); then you can move it to where the artObject is and delete artObject afterwards

                                    • 15. Re: Can I batch create symbols from layers?
                                      theplu Community Member

                                      yeah, I came to that conclusion probably as you were posting this. Well, good to know I was on the right track! I wish there was a replace method though!

                                      • 16. Re: Can I batch create symbols from layers?
                                        theplu Community Member

                                        So here is my working script for anyone who stumbles upon this thread and can use anything from it. For my AI file, there is 1 top layer(ignored), a few sub layers (made into symbols) and a bunch of child layers for each of those sub layers (also made into symbols).

                                         

                                        var docRef = app.activeDocument;

                                        var layersRef = app.activeDocument.layers;

                                        var layersCount = layersRef.length;

                                        var mySymbolInstance = null;

                                         

                                        for(var i = layersCount - 1; i >=0; i--) {

                                            // get top layer

                                            var topLayer = docRef.layers[i];

                                            //alert("top layer: " + topLayer.name);

                                           

                                            if(topLayer.layers.length > 0) {

                                               

                                                // get sub layers

                                                for(var ii = topLayer.layers.length - 1; ii >=0; ii--) {

                                                    var subLayer = topLayer.layers[ii];

                                                   

                                                    // create a group

                                                    var grp = subLayer.groupItems.add();

                                                    // get all page items from layers

                                                    var items = subLayer.pageItems;

                                                   

                                                    // add page items to the group

                                                    for (var pi= items.length-1; pi >0; pi--)

                                                    {

                                                        // create symbols from sub sub layers

                                                        createSymbol(items[pi], items[pi].name);

                                                       

                                                        // add new sub sub layer symbols to group

                                                        mySymbolInstance.moveToBeginning(grp);

                                         

                                                        // remove original sub layer content

                                                        items[pi].remove();

                                                    }

                                         

                                                    // create symbols from sub layers

                                                    createSymbol(grp, subLayer.name);

                                         

                                                    // remove original groupItem

                                                    grp.remove();

                                                }

                                            }

                                        }

                                                   

                                        clearEmptyLayers();

                                         

                                        function createSymbol(layer, layerName) {

                                                        // create symbols from all items in the group

                                                        var symbolRef = docRef.symbols.add(layer);

                                                        // give symbol the same name as the layer

                                                        symbolRef.name = layerName;

                                                   

                                                        // replace original groupItem with symbol instance

                                                        mySymbolInstance = docRef.symbolItems.add(symbolRef);

                                                        mySymbolInstance.left = layer.left;

                                                        mySymbolInstance.top = layer.top;

                                        }

                                         

                                        function clearEmptyLayers() {

                                            if (documents.length > 0 && activeDocument.pathItems.length >= 0){

                                                for (var ni = layersCount - 1; ni >= 0; ni-- ) {

                                                    // get sub layers

                                                    var topLayer = docRef.layers[ni];

                                                   

                                                    for(var ii = topLayer.layers.length - 1; ii >=0; ii--) {

                                                        // delete empty sub layers

                                                        if ( topLayer.layers[ni].pageItems.length == 0 ) {

                                                            topLayer.layers[ni].remove();

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                         

                                        Thanks again Carlos!

                                        • 17. Re: Can I batch create symbols from layers?
                                          theplu Community Member

                                          Soooo... the saga continues. I'm trying to see if I can make all items a symbol instead of just 2 levels down. I was able to make sure that the symbols replace the original element on the stage but is it possible to keep the same layer structure as well?

                                           

                                          In my research, I've found that Illustrator uses the following structure:

                                           

                                          Layer -> Sub Layer -> Group -> Path Item -> Compound Path

                                           

                                          so if I have a path item under a group, can I tell it to stay within that group? According to the reference documentation, I have access to the parent so I tried:

                                           

                                          mySymbolInstance.parent = layer.parent;

                                           

                                          but it still seems to pull each one out into it's own separate layer.

                                           

                                          My ultimate goal is to have movie clips in Flash that have the same hierarchy as the Illustrator file. I'm thinking that I need to turn each path and compound path item into a symbol, then read through the groups, gather all of the page items in the group and turn that into a symbol (which will include the path symbols), then gather all of page items in the sublayers and turn those into symbols (which will include the group symbols), then do the same for each layer so that everything stays relative to the Illustrator organization.

                                           

                                          Your help is soooo appreciated!

                                          • 18. Re: Can I batch create symbols from layers?
                                            theplu Community Member

                                            I figured this out using recursion. Pasted here in case it helps someone else:

                                             

                                            #target Illustrator

                                             

                                            var docRef = app.activeDocument;

                                            var layersRef = app.activeDocument.layers;

                                            var layersCount = layersRef.length;

                                            var mySymbolInstance = null;

                                             

                                            if ( app.documents.length > 0 ) {

                                                // if the file is not empty, loop through all levels

                                                recurseLayers(docRef.layers);

                                                clearEmptyLayers();

                                                alert("I'm done");

                                            }

                                             

                                            function recurseLayers(objArray) {

                                                // loop through main layers

                                                for (var l = 0; l < objArray.length; l++) {

                                                    // loop through secondary layers

                                                    if (objArray[l].layers.length > 0) {

                                                        recurseLayers(objArray[l].layers);

                                                    }

                                                    // loop through first level groups

                                                    if (objArray[l].groupItems.length > 0) {

                                                        recurseGroups(objArray[l].groupItems);

                                                       

                                                        // create a group

                                                        var layerGrp = objArray[l].groupItems.add();

                                                      

                                                        //give new group the same name as the old group

                                                        var layerName = objArray[l].name;

                                                        layerGrp.name = layerName;

                                                       

                                                        // get all page items from group

                                                        var layerGrpPageItems =  objArray[l].pageItems;

                                                       

                                                        //alert("how many group page items: " + layerGrpPageItems.length);

                                                        for (var li= layerGrpPageItems.length-1; li >0; li--) {

                                                            // will become the symbol name

                                                            var layerPageItemName = layerGrpPageItems[li].name;

                                                           

                                                            // if it's not already a symbol, make it into one

                                                            if (layerGrpPageItems[li].typename == "SymbolItem") {

                                                                layerGrpPageItems[li].moveToBeginning(layerGrp);

                                                            } else {

                                                                // create symbols

                                                                createSymbol(layerGrpPageItems[li], layerGrpPageItems[li].name);

                                                               

                                                                // add symbols to group

                                                                mySymbolInstance.moveToBeginning(layerGrp);

                                             

                                                                // remove original content

                                                                layerGrpPageItems[li].remove();

                                                            }

                                                        }

                                                   

                                                        // create symbols from layer

                                                        createSymbol(layerGrp, layerName);

                                                        // remove original layer content

                                                        layerGrp.remove();

                                                    }

                                                }

                                            }

                                             

                                            function recurseGroups(objArray) {

                                                for (var g = 0; g < objArray.length; g++) {

                                                    // loop through second level groups

                                                    if (objArray[g].groupItems.length > 0) {

                                                       

                                                        recurseGroups(objArray[g].groupItems);

                                                       

                                                        // create a group

                                                        var grp = objArray[g].groupItems.add();

                                                      

                                                       //give new group the same name as the old group

                                                        var groupName = objArray[g].name;

                                                        grp.name = groupName;

                                                        //alert("which group is this? " + groupName);

                                                       

                                                        // get all page items from group

                                                        var grpPageItems =  objArray[g].pageItems;

                                                       

                                                        //alert("how many group page items: " + grpPageItems.length);

                                                        for (var gi= grpPageItems.length-1; gi >0; gi--) {

                                                            // will become the symbol name

                                                            var pageItemName = groupName + "_" + grpPageItems[gi].name;

                                                           

                                                            createSymbol(grpPageItems[gi], pageItemName);

                                                           

                                                            // add symbols to group

                                                            mySymbolInstance.moveToBeginning(grp);

                                             

                                                            // remove original content

                                                            grpPageItems[gi].remove();

                                                        }

                                                    }

                                                 }

                                            }

                                             

                                            function createSymbol(element, elementName) {

                                                //alert("elementName" + elementName);

                                                // create symbols from all items in the group

                                                var symbolRef = docRef.symbols.add(element);

                                             

                                                //alert("element unnamed before: " + elementName);

                                                // if the element name is empty, give it a name

                                                var addElementIndex = 0;

                                                if(elementName == "") {

                                                    elementName = "unnamed" + addElementIndex;

                                                    addElementIndex++;

                                                }

                                               

                                                // loop through all the symbols in the document

                                                var symbolCount = docRef.symbols.length;

                                                    for(var s=0; s<symbolCount; s++)  {

                                                        // existing symbols

                                                        var symbolCheck = docRef.symbols[s];

                                                        //alert(symbolCheck.name);

                                                        var addIndex = 0;

                                                        // if the name already exists, add the index number to it and increment

                                                        if(elementName == symbolCheck.name) {

                                                            elementName = elementName + addIndex;

                                                            addIndex++;

                                                    }

                                                }

                                               

                                                symbolRef.name = elementName;

                                                //alert("symbol name: " + symbolRef.name);

                                                       

                                                mySymbolInstance = docRef.symbolItems.add(symbolRef);

                                                mySymbolInstance.left = element.left;

                                                mySymbolInstance.top = element.top;

                                            }

                                             

                                            function clearEmptyLayers() {

                                                if (documents.length > 0 && activeDocument.pathItems.length >= 0){

                                                    for (var ni = layersCount - 1; ni >= 0; ni-- ) {

                                                        // get sub layers

                                                        var topLayer = docRef.layers[ni];

                                                       

                                                        for(var ii = topLayer.layers.length - 1; ii >=0; ii--) {

                                                            // delete empty sub layers

                                                            if ( topLayer.layers[ni].pageItems.length == 0 ) {

                                                                topLayer.layers[ni].remove();

                                                            }

                                                        }

                                                    }

                                                }

                                            }