Applying warp to object using extended script

Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

Hello,

 

I found a great post and answer by Silly-V using Live Effects under this post: https://forums.adobe.com/message/9356527#9356527 . It certainly helped me since I can now warp my object. However, I still have a minor issue after using this tool. Namely, after warping, the shape of the object changes but the selection stays the same. I have a specified canvas size and therefore the selection may stay inside the canvas while the shape actually does not. Since my script also exports the PDF it therefore cuts off parts of the shape.

I have seen that using "envelope distort" updates the selection so that the entire shape is included after warping. However, I cannot find any way to apply the envelope distort warp other than this: 

 

 

app.executeMenuCommand("Make Warp");

 

Nonetheless, I need the whole process to be automatic so that does not help. This command only opens the envelope distort warp dialogue, but you first have to manually select the shape and then you have to manually set the warp percentage.
 
Another potential solution would be to update the selection so that it includes the full shape. I don't know how to do this either. If you have any ideas or solutions that would be very much appreciated! Thank you.
TOPICS
Scripting

Views

97

Likes

translate

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

Engaged , Jan 12, 2021 Jan 12, 2021
Hi Karl, Not sure if I understand you right, but see if this makes sense: var item = app.activeDocument.selection[0]; item.applyEffect('<LiveEffect name="Adobe Deform"><Dict data="R DeformValue 0.5 R DeformHoriz 0.0 R DeformVert 0.0 I DeformStyle 3 B Rotate 0 "/></LiveEffect>'); $.writeln('item.height = '+item.height); app.redraw(); app.executeMenuCommand('expandStyle'); item = app.activeDocument.selection[0]; $.writeln('item.height = '+item.height);   Box 1 is starting point. Box 2 has a Warp "...

Likes

translate

Translate

Translate
Engaged ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

Hi Karl,

 

Not sure if I understand you right, but see if this makes sense:

 

var item = app.activeDocument.selection[0];
item.applyEffect('<LiveEffect name="Adobe Deform"><Dict data="R DeformValue 0.5 R DeformHoriz 0.0 R DeformVert 0.0 I DeformStyle 3 B Rotate 0 "/></LiveEffect>');
$.writeln('item.height = '+item.height);
app.redraw();
app.executeMenuCommand('expandStyle');
item = app.activeDocument.selection[0];
$.writeln('item.height = '+item.height);

 

 

Screen Shot 2021-01-12 at 9.24.31 pm.png

 

Box 1 is starting point. Box 2 has a Warp "ArcUpper" on it and exceeds the artboard, but it's height is still 80 so there's no way to know the problem. Box 3 is expanded, so you can resize it to fit artboard. (Note that you could duplicate the item first and expand the duplicate, measure the new dimensions, then remove the expanded item.)

 

Is that what you needed? - Mark

Likes

translate

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
Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

Mark,

 

Wow that did definitely work. Thank you so much for the quick and insightful reply. This is exactly what I needed, to capture that bit of hidden height and resize it. I already had the code to resize, so I just had to copy in the expansion work you did and it immediatly executed perfectly.

If you do not mind, I would like to ask you a theoretical question as well. I just started scripting in Illustrator so I am still new to some concepts. When you work with the activeDocument.selection[0], I thought that I first had to select the object for the changes to apply, but in my case the object is imported directly from my computer so I never get the chance to select it. It still worked for me which is great but I would love to understand why.

Related to this, I had some issues with working on a PDF object after opening it via a script:

 

var fileRef = new File("C:/originalpeople/Winetumbler/canvas_test1.pdf");

if (fileRef != null) {
  var docRef = open(fileRef, DocumentColorSpace.RGB, );
}

 

The PDF is imported just fine here, but I don't understand quite how to access its content. I tried looking at the document's groupItems (there were 9), pathItems (98), rasterItems (0), etc. But it did not quite work. Here is the content of the PDF:

PDF_illustrator.png

 

I want to store this same selection as you see in the image in a variable. I believe I have some fundamental concepts missing and I am sorry if I am phrasing these questions poorly. The solution I used in the end, in case that anyone else has a similar issue, was to embed the PDF as a groupItem as such:

 

var embedDoc = new File(myPath + "canvas_test1.pdf");
if (app.documents.length > 0 && embedDoc.exists) {
  var doc = app.activeDocument;
  var placed = doc.groupItems.createFromFile(embedDoc);
}

 

While this solution works perfectly fine for me, I just want to be able to better understand what is going on so I can tackle similar issues in the future. I basically want to understand how to go about selecting different objects in a script when you do not create them inside the script, and exactly what .selection[o] is referencing (I thought it was the first of whichever object you selected).

 

I hope I have explained myself properly and I am super greatful for the help already provided.

 

Thank you Mark!

Likes

translate

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Hi Karl, I'm really sorry I somehow missed your response here! If not too late, let me have a go at answering.

 

Let's see. In your first example you create a File object (with a path as parameter) and you store that File as a variable called fileRef. Then you open that File, and you store a reference to the newly opened Document in a variable called docRef.

 

To work with the objects in docRef, you could script something like this:

 

var myItems = docRef.pageItems;

 

Now you have a variable called myItems that is a PageItems object (it's an "array-like structure"—it works in some ways like a normal javascript array, but is not the same and doesn't have all the same methods). This is really the answer to your original question about how to 'store a selection'—actually you are storing a reference to all those pageItems in the variable myItems. In most cases you don't need to select them at all in order to use, move or manipulate them.

 

You can do things like this:

 

alert('height of first pageItem in document = ' + myItems[0].height);
alert('height of second pageItem in document = ' + myItems[1].height);

 

or this:

 

for (var i=0; i<myItems.length; i++ ) {
    var myItem = myItems[i];
    alert('Item ' + i + ': ' + myItems[i].typename);
}

 

 In the scripting guide, look at the PageItems object methods. eg. getByName.

 

In your second example, you make it simpler to get a reference to the PageItems in your document by importing the document as a GroupItem. (Note a GroupItem is a type of PageItem, too.) You store a reference to the newly created GroupItem in a variable called "placed".

 

So you could do this, for example:

 

var myItems = placed.pageItems;
alert('height of first item in group is ' + myItems[0].height);

 

 or something like this:

 

app.activeDocument.selection = []; // clear the selection with empty array
placed.pageItems[0].selected = true;

 

 

You can get references to other types of pageItems by accessing the appropriate property, eg.

 

var allGroupsInDocument = docRef.groupItems;
var pathItemsInPlaced = placed.pathItems;

 

 

Your solution of using the GroupItems.createFromFile(file) method was, I think, a neat way to start, because it wraps the pageItems in a group, and is also decoupled from the original document (it's essentially an import, rather than an open). And guess what? I've never noticed that method before, so you've taught me something really useful! 🙂

 

I hope that gives you some idea of working with page items. I recommend reading through the scripting guide on all the different types of PageItems.

 

- Mark

 

P.S. it is really weird that the script I gave you worked if you had nothing selected. I would expect an error.

Likes

translate

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
Explorer ,
Feb 08, 2021 Feb 08, 2021

Copy link to clipboard

Copied

Hello again Mark,

 

Not to worry, it was not an urgent matter, but thank you so much for this clear and insightful explanation. I hope some other people get to see this thread as well because some of these concepts are really key to start scripting in Illustrator in my opinion.

Essentially why I was interested in understanding all this better was because at my company we produce these personalized for mugs, bottles, etc. Typically there are three designs in a PDF, and I wanted to be able to select each one individually. When importing with the "createFromFile" function I get the entire design as a GroupItem, but of course this does not work if I have three separate designs because I would need three separarate groupItem elements.

I think your code worked because I believe that embedding the PDF with this function groups everything together as a groupItem and selects it, which is why selection[0] points to the entire design here. 

In any case, I managed to finally find a solution to my problem, and it basically consists of looping through all the pathItem elements in the document and grouping them together depending on their vertical position in the PDF (I create three groups, one for each design).

If you or anyone else is interested in seeing how this was done you can check out this thread:

https://community.adobe.com/t5/illustrator/issue-grouping-objects-together-using-a-script/m-p/117618...

 

I will have a look at working with pageItems as you discuss, I suspect that would work fine as well. 

 

Thanks a lot for the help 🙂

Likes

translate

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