PageItem.applyEffect(LiveEffectXML)

Adobe Community Professional ,
Jun 19, 2015 Jun 19, 2015

Copy link to clipboard

Copied

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.

TOPICS
Scripting

Views

4.2K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct Answer

Adobe Community Professional , Dec 13, 2015 Dec 13, 2015
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

Likes

Translate

Translate
New Here ,
Jun 22, 2015 Jun 22, 2015

Copy link to clipboard

Copied

They may be SVG filter?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 13, 2015 Dec 13, 2015

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 14, 2015 Dec 14, 2015

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Mentor ,
Dec 14, 2015 Dec 14, 2015

Copy link to clipboard

Copied

‌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?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 14, 2015 Dec 14, 2015

Copy link to clipboard

Copied

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

Thanks

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Mentor ,
Dec 14, 2015 Dec 14, 2015

Copy link to clipboard

Copied

N‌eat-o! Thanks for the confirmation Carlos, again great job.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 15, 2015 Dec 15, 2015

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 15, 2015 Dec 15, 2015

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
May 06, 2016 May 06, 2016

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 25, 2017 Feb 25, 2017

Copy link to clipboard

Copied

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 ?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Aug 22, 2018 Aug 22, 2018

Copy link to clipboard

Copied

This is a great thread, I was following moluapple's method through an uncompressed AI file when I noticed that these Live Effects look like siblings to what I optimistically hope might be other accessible things. In my file, the Stroke Offset effect shows up mixed in with Stroke and Fill effects:

/Part ,

/BasicFilter :

(Stroke Style Filter) 0 0 /Filter ,

1 /Visible ,

2 /FillOrStroke ,

/Dictionary : /NotRecorded ,

/StrokeStyle : 0 R

0.011535820551217 0.457404434680939 0.82201874256134 0 0.96078431372549 0.607843137254902 0.270588235294118 XA

0 1 0 0 0 Xy

0 J 0 j 2 w 1 M []0 d

0 XR

1 0 Xd

/Def ;

(StrokeStyle) ,

; /Dict ;

/Part ,

/CompoundFilter :

(Chain Style Filter) 0 0 /Filter ,

1 /Visible ,

/BasicFilter :

(Adobe Stroke Offset) 1 0 /Filter ,

1 /Visible ,

(Illustrator.exe) /PluginFileName ,

(Stroke Offset Live Effect) /Title ,

2 /FillOrStroke ,

/Dictionary : /NotRecorded ,

(Inside) /String (DisplayString) ,

/StrokeStyle : 0 R

0 0 0 0 1 1 1 XA

0 1 0 0 0 Xy

0 J 0 j 1.8 w 1 M []0 d

0 XR

1 0 Xd

/Def ;

(StrokeStyle) ,

'B StrokeOffsetInside 1' +

; /Dict ;

/Part ,

/BasicFilter :

(Blend Style Filter) 0 0 /Filter ,

1 /Visible ,

/Dictionary : /NotRecorded ,

/BlendStyle : 0 0.6 0 0 0 Xy

0 J 0 j 1 w 10 M []0 d

0 XR

/Def ;

(BlendStyle) ,

; /Dict ;

/Part ,

The format looks very similar too -- moluapple's RegExp picks up "Adobe Stroke Offset" which looks to be "Stroke Style Filter" in the effect above. I'm curious if strokes and fills could be accessed as LiveEffects and if what we're looking at is how the Appearance panel is handled. Would it be possible to access a stroke through this method then use PageItem.tag to keep track of multiple strokes? I don't know anything about C++, but I wondered if the way this worked was through the AILiveEffectSuite:

ice_screenshot_20180822-224645.png

If so, would that mean that a script could potentially have access via app.sendScriptMessage? Or am I completely out in left field on this?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Aug 23, 2018 Aug 23, 2018

Copy link to clipboard

Copied

Yes, when you make own c++ .aip plugin, you can expose some functionality to scripts and the .jsx scripts can then be used to make your separate .aip plugin features available to one overall .jsx script that may need to be used to utilize any amount of features from the various .aip plugins.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Aug 23, 2018 Aug 23, 2018

Copy link to clipboard

Copied

Is there a way to find out the mechanism behind PageItem.applyEffect(), as in which plugin or Suite it's exposed to, if applicable? As in, trying to apply the XML effect via app.sendScriptMessage() through the above plugin's function (AILiveEffectSuite) as a gauge for whether or not that's the mechanism behind the applyEffect() method?

Your pragmatism is no match for my idealism sir, I want multiple strokes so very much

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Aug 23, 2018 Aug 23, 2018

Copy link to clipboard

Copied

LATEST

The app.sendScriptMessage was added later, and deals with custom plugins, the only documented piece in the javascript guide pdf is this:

So if there are such accessible strings available for the various default plugins, I have not yet seen such a list, but most likely they are not there because this scripting command was added way later. I'd love to be wrong..

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines