10 Replies Latest reply on Feb 25, 2017 3:39 PM by StrongBeaver

    PageItem.applyEffect(LiveEffectXML)

    Silly-V Adobe Community Professional

      I am wondering if anyone has been able to figure out what kind of "LiveEffectXML" is a parameter to PageItem.applyEffect()

      It's been years since this feature has been out, but no documentation anywhere.

        • 1. Re: PageItem.applyEffect(LiveEffectXML)
          luca.dall

          They may be SVG filter?

          • 2. Re: PageItem.applyEffect(LiveEffectXML)
            CarlosCanto Adobe Community Professional & MVP

            Hi Silly-V, I figured it out, with big big, and I mean BIG help from Adobe's Sanjay K

             

            // apply offset path live effect to selected path
            var idoc = app.activeDocument;
            var ipath = idoc.selection[0];
            
            xmlstring = '<LiveEffect name="Adobe Offset Path"><Dict data="R mlim 4 R ofst 20 I jntp 2 "/></LiveEffect>';
            
            ipath.applyEffect(xmlstring);
            
            //mlim is the MiterLimit Value “4”, ofst is the Offset Value “20”, jntp is the Join Type “2” for Miter.
            


            more details here

            2 people found this helpful
            • 3. Re: PageItem.applyEffect(LiveEffectXML)
              Silly-V Adobe Community Professional

              Way to go! This shall prove infinitely useful, no doubts about it. Thanks for the research.

              • 4. Re: PageItem.applyEffect(LiveEffectXML)
                W_J_T Level 4

                Nice work Carlos + Sanjay.

                 

                Curious (unable to test myself), does the applyEffect occur and get applied without the effect dialog appearing and no user interaction required, with the provided parameters applied?

                • 5. Re: PageItem.applyEffect(LiveEffectXML)
                  CarlosCanto Adobe Community Professional & MVP

                  Hi W_J_T, that's correct, Effects get applied with the supplied parameters, no dialog shown.

                   

                  Thanks

                  • 6. Re: PageItem.applyEffect(LiveEffectXML)
                    W_J_T Level 4

                    Neat-o! Thanks for the confirmation Carlos, again great job.

                    • 7. Re: PageItem.applyEffect(LiveEffectXML)
                      Silly-V Adobe Community Professional

                      Okay, let the experimentation begin.

                      First, I wanted to get the FXG file, but have no CS5 or CS6 where I am at the moment, so I used the scripting command to do a SaveAs using new FXGSaveOptions.  This saved the current file, but not as fxg, rather as .ai. I renamed the file to fxg manually, but I suspect that one could simply open the ",ai" file as text anyway.

                       

                      Well, in my result which came from CC2015, as there is no UI dialog FXG save option and no "show code" option, I did not get my XML string as described in Carlos' post. However, the same info is present in the FXG text, which for my simple 1-rectangle file consumed over 20,000 lines. Doing a search for my desired effect, Offset Path, I saw a structure from where the data can be also obtained if one doesn't have CS5 or CS6 and has to save the file like I did to get the effect parameter string data.

                      Then I was able to thus isolate this section:

                      /BasicFilter :

                      (Adobe Offset Path) 1 0 /Filter ,

                      1 /Visible ,

                      (OffsetPath.aip) /PluginFileName ,

                      (Offset Path) /Title ,

                      /Dictionary : /NotRecorded ,

                      0 /Int (jntp) ,

                      10 /Real (ofst) ,

                      4 /Real (mlim) ,

                      ; /Dict ;

                       

                      From where you can tell which parts relate to the XML string as Carlos has described:

                      <LiveEffect name="Adobe Offset Path"><Dict data="R mlim 4 R ofst 20 I jntp 2 "/></LiveEffect>


                      The name attribute in LiveEffect tag comes from the line with "1 0 /Filter ,"
                      The various attributes are from the lines beflow the /Dictionary : /NotRecorded ," and their number values (in case of this effect) are followed by the "datatype" (?) name, which is then abbreviated into a 1st capital letter in the effect string, and then the name which is in parentheses.
                      When copied, pasted and spliced and chopped so as to resemble the working example of Carlos, these pieces of strings can be used in the live effect string in any order.
                      Interestingly, the Join Type for this Offset Path effect does not quite correspond with the dropdown menu in the effect's actual UI dialog: the 0 value is for "Round" which is the 2nd (middle) item in the dropdown, the 1 value is for "Bevel" which is the 3rd item, and 2 is for "Miter" which is the 1st item.

                      Doing numbers from 3 on up for the joint type will default this effect to "Miter".


                      Using this new insight, I'm able to produce the all-powerful Transform effect dynamically.
                      In this example, the horizontal move is created using the width of the selection.

                      #target illustrator
                      function test(){ 
                          var doc = app.activeDocument;
                          var p = doc.selection[0];
                      
                          var effectStr_2 =
                          '<LiveEffect name="Adobe Transform">' +
                              '<Dict data="' +
                                  'R scaleH_Factor 1 ' +
                                  'R moveV_Pts 0 ' +
                                  'R scaleV_Percent 100 ' +
                                  'I pinPoint 4 ' + // note the anchor point parameter- it goes from top-left (0) to bottom-right (8)
                                  'B scaleLines 0 ' +
                                  'I numCopies 1 ' +
                                  'B randomize 0 ' +
                                  'R rotate_Radians 0 ' +
                                  'R moveH_Pts ' + p.width + ' ' +
                                  'R scaleV_Factor 1 ' +
                                  'B reflectY 0 ' +
                                  'B reflectX 0 ' +
                                  'R rotate_Degrees 0 ' +
                                  'R scaleH_Percent 100 ' +
                                  'B transformPatterns 0' +
                              '"/>' +
                          '</LiveEffect>';
                          p.applyEffect(effectStr_2);
                      } 
                      test();
                      
                      

                       

                      There is a problem in that we can't edit existing effects, and we can't apply new instances of effects with ability to override old ones. They simply get stacked on and on inside the appearance palette. For those uses where a one-time application is OK, or expansion soon follows, this probably doesn't matter. And for those that it does matter to, it is possible to record a "Reduce to Basic Appearance" action and run it with the script immediately. Another non-optimal solution which may work for some situations is having a pre-included set of 'default' graphic styles in the document, which could be called later to be applied onto the art, overriding any other effects and resetting it back.

                      2015-12-15 11_24_11-.png

                      2 people found this helpful
                      • 8. Re: PageItem.applyEffect(LiveEffectXML)
                        CarlosCanto Adobe Community Professional & MVP

                        great, thanks for adding your findings Silly, seeing the FXGSaveOptions in the documentation and Object browser, I thought we could save as fxg from CC

                        • 9. Re: PageItem.applyEffect(LiveEffectXML)
                          moluapple Level 4

                          Maybe no bother using the FXGSaveOptions(it turned out to be just ai file, not FXG at all), just save ai file without compression, open it with text editer such as SublimeText, using regex mode to search and replace the data.

                          Get the name:

                          (?<=/BasicFilter :\n\()[^)]*(?=\) 1 0 /Filter)

                          Get and format the dict data: find

                          ^([\d.]*) /(\w)[^(\n]*\((\w+)\).+

                          replace with

                          '\2 \3 \1' +

                          So this is another code strings:

                          '<LiveEffect name="Adobe Zigzag">' + 
                          '<Dict data="' + 
                          'R roundness 1' +
                          'R amount 10' +
                          'R ridges 3' +
                          'R relAmount 0' +
                          'R absoluteness 1' +
                          '"/>' + 
                          '</LiveEffect>'; 
                          

                           

                          And now its easy to get all these LiveEffectXML, also we can write functions for reuse.

                          2 people found this helpful
                          • 10. Re: PageItem.applyEffect(LiveEffectXML)
                            StrongBeaver Level 2

                            The instructions on page linked doesn't explain if one wants to get a live effect such as the warp tool, considering you can't apply the warp tool then save the scene as a FXG file and get the XML data from the use of the warp tool ?