• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Misleading scripting guide? PathPoints index

Community Beginner ,
Jul 14, 2015 Jul 14, 2015

Copy link to clipboard

Copied

Hello,

I've had trouble finding how to access the PathPoint positions today.

Apparently, the correct way to do it is by writing something like this: app.activeDocument.pathItems[itemIndex].pathPoints[pointIndex]

Which makes sense (pathPoints is an array) and it works fine and everything. Great.

Now why in the Illustrator Scripting Reference - JavaScript (CC 2015) PDF, page 138, this method is suggested: index(itemKey), type:number, returns:PathPoint, "Gets an element from the collection."?

I've tried using it and the only thing I got is this error message "app.activeDocument.pathItems[0].pathPoints.index is not a function" (with pathPoints.index(0) for example) which leads me to believe that there is no index method in the API... Is this correct or am I simply being very dumb and not using the method properly?

The reason I'm taking the time to write about this is because it seems I'm not the only one having this issue:

https://forums.adobe.com/thread/440700

EDIT:

Also, it seems pathPoints[pointIndex] works, but PathPoints[pointIndex], as it is written in the guide, doesn't.

TOPICS
Scripting

Views

2.9K

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

Valorous Hero , Jul 15, 2015 Jul 15, 2015

I don't think that'd work because it's taking an anchor properties and trying to re-destribute them? I think a more manual approach of collecting each of the pathPoints into an array, re-ordering them, and building a new path via setEntirePath out of them.

Votes

Translate

Translate
Adobe
Valorous Hero ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

Perhaps the PDF guide is inferior to the OMV, because I do not see the index method when looking at PathPoints in the OMV.2015-07-15 09_16_11-.jpg

Votes

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
Community Beginner ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

I don't see any index method for pathPoints either so I guess this is a mistake in the guide (one which made me lose quite a bit of time unfortunately).

In any case I didn't know about this OMV window. This should be very helpful in the future, thanks.

I'm having another problem/limitation where I would like to append new points to my pathPoints array but I need to be able to choose the position in the array where my [x,y] are inserted.

By default, when I use "var newPoint = pathItem.pathPoints.add();" and then "newPoint.anchor = [xVal, yVal];" the new [x,y] array is always added at the end of the pathPoints array and there is no argument available for this method where I could specify at which index in my array I would like my new point to be inserted.

So I suppose I will have to write a function to move [x,y] from the end of the array to the position I want it to be, which happens after it has already been added to the array, which seems pretty inefficient and time-consuming to me.

Is there a better/cleaner way to this? It would be much easier and logical if there was an argument for the add() method to specify where to insert the new item, no?

Votes

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
Community Beginner ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

"doc.pathItems[0].pathPoints.splice is not a function"

So apparently, and even when you can access the points with pathPoints[pointIndex], pathPoints is considered an object, not an array (alert(String(typeof(doc.pathItems[0].pathPoints))); returns "object").

So maybe that's why I can't use the splice method on it, which would mean I can't reorder the pathPoint located in pathPoint at all?

Any tips on that?

Votes

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
Valorous Hero ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

From what I have gathered so far, the Illustrator (or Adobe) object collections such as layers, pathItems, groupItems, etc., are array-like objects which are actually not arrays, and have to be used custom functions on. I think, sometimes, I am able to perform my array-specific operations (again, only when specific needs are there, not generic) by making an own array and pushing all of the (or specific) members of the Illustrator collection into it.

Also, I learned that you can't use prototypes to add onto the native Illustrator classes. I am not sure if this is true, I would like to know more. It would be nice, for instance in this case, to do something like pathPoints.insertAfter(index).

Votes

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
Community Beginner ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

It would be very nice indeed!

On the other hand the length method works very well on pathPoints. This is strange.

And I can't edit it but in my last message, the correct sentence is "I can't reorder the pathPoint located in pathPoints at all".

Anyway, I've tried storing the positions in my own intermediate array like your suggested but I still get a message highlighting lines 15 and 19 and telling me that "undefined is not an object".

Code below:

if ( app.documents.length > 0 ) {

    var doc = app.activeDocument;

    var line = doc.pathItems.add();

    line.stroked = true;

    line.setEntirePath( Array( Array(220, -475), Array(375, -300) ) );

   

    var newPoint = doc.pathItems[0].pathPoints.add();

    newPoint.anchor = Array(220, -300);

    newPoint.leftDirection = newPoint.anchor;

    newPoint.rightDirection = newPoint.anchor;

    newPoint.pointType = PointType.CORNER;

   

    var myArray = [];   

    for (i=0; i < doc.pathItems[0].pathPoints.length; i++) {

        myArray = doc.pathItems[0].pathPoints.anchor;

        }

    alert(String(myArray));

   

    myArray = myArray.splice(1, 0, myArray.splice(doc.pathItems[0].pathPoints.length, 1)[0]);

    alert(String(myArray));

   

    for (i=0; i < doc.pathItems[0].pathPoints.length; i++) {

        doc.pathItems[0].pathPoints.anchor = myArray

        }

}

(to avoid mistakes, lines 1 to 11 are an example from the scripting guide)

Votes

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
Valorous Hero ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

I don't think that'd work because it's taking an anchor properties and trying to re-destribute them? I think a more manual approach of collecting each of the pathPoints into an array, re-ordering them, and building a new path via setEntirePath out of them.

Votes

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
Community Beginner ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

OK so I tried collecting pathPoint instead of pathPoint.anchor but this doesn't work with setEntirePath(myArray) ("illegal argument error") since setEntirePath() needs an array of [x, y], and not an array of pathPoint. So I went back to pathPoint.anchor, made a prototype to simplify things up/avoid mistakes and used setEntirePath to re-attribute the points like you suggested, and it works! Thanks a lot Silly-V!

Correct code:

Array.prototype.move = function (from, to) {

    this.splice(to, 0, this.splice(from, 1)[0]);

    return this;

};

if ( app.documents.length > 0 ) {

    var doc = app.activeDocument;

    var line = doc.pathItems.add();

    line.stroked = true;

    line.setEntirePath( Array( Array(220, -475), Array(375, -300) ) );

   

    var newPoint = doc.pathItems[0].pathPoints.add();

    newPoint.anchor = Array(220, -300);

    newPoint.leftDirection = newPoint.anchor;

    newPoint.rightDirection = newPoint.anchor;

    newPoint.pointType = PointType.CORNER;

   

    var myArray = [];   

    for (i=0; i < doc.pathItems[0].pathPoints.length; i++) {

        myArray = doc.pathItems[0].pathPoints.anchor;

        }

    alert(String(myArray[2]));

   

    myArray = myArray.move(2,0);

    alert(String(myArray[2]));

   

    doc.pathItems[0].setEntirePath(myArray);

    }

}

Now when I include this bit in one of the functions of my script the line 2, where the splice method is called, is highlighted and I get the error "undefined is not an object", which is not the case with the code above, even when prototype is the exact same. What am I missing here?

Here is the function I'm having problems with:

Array.prototype.move = function (from, to) {

    this.splice(to, 0, this.splice(from, 1)[0]);

    return this;

};

function divideSegment(pathItem, pStart, pEnd, divideBy) {

    var xOperator;

    var yOperator;

   

    var xDiff = Math.abs(pStart[0] - pEnd[0]);

    var yDiff = Math.abs(pStart[1] - pEnd[1]);

    if (pStart[0] < pEnd[0]) { xOperator = 1; } else { xOperator = -1; };

    if (pStart[1] < pEnd[1]) { yOperator = 1; } else { yOperator = -1; };

   

    for (i = 0 ; i< divideBy-1; i++) {

        var fraction = i/(divideBy-1);

        var xVal = pStart[0] + xOperator*fraction*xDiff;

        var yVal = pStart[1] + yOperator*fraction*yDiff;

       

        var newPoint = pathItem.pathPoints.add();

       

        newPoint.anchor = [xVal, yVal];

        newPoint.leftDirection = newPoint.anchor;

        newPoint.rightDirection = newPoint.anchor;

        newPoint.pointType = PointType.CORNER;

       

        var myArray = [];

        for (i=0; i < pathItem.pathPoints.length; i++) {

            myArray = pathItem.pathPoints.anchor;

            }

        myArray = myArray.move(pathItem.pathPoints.length,0);

        pathItem.setEntirePath(myArray);

        }

    }

if (app.documents.length > 0) {

    var doc = app.activeDocument;

    var ellipseSize = 100.0;

    var hex1 =  doc.pathItems.polygon(doc.width/2, -doc.height/2, ellipseSize/2, 6);

    hex1.rotate(90);

    divideSegment(hex1, hex1.pathPoints[0].anchor, hex1.pathPoints[1].anchor, 6);

    }

Votes

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
Valorous Hero ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

Hmm, if you are moving something with an index of pathPoints.length, that index will be higher than possible. For example, you would not be able to move something with index of 11 in an 11-member collection, because the first item is at index 0, and last index is 10.

Try to use pathPoints.length-1 is your from-index.

Votes

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
Community Expert ,
Jul 15, 2015 Jul 15, 2015

Copy link to clipboard

Copied

Perhaps you can play with this:

if ( app.documents.length > 0 ) {

    var doc = app.activeDocument;

    var line = doc.pathItems.add();

    line.stroked = true;

    line.setEntirePath( Array( Array(220, -475), Array(375, -300) ) );

   

    var newPoint = doc.pathItems[0].pathPoints.add();

    newPoint.anchor = Array(220, -300);

    newPoint.leftDirection = newPoint.anchor;

    newPoint.rightDirection = newPoint.anchor;

    newPoint.pointType = PointType.CORNER;

   

    var myArray = [];

    var myPType = [];

    var myPleft = [];

    var myPright = [];

   

    for (i=0; i < doc.pathItems[0].pathPoints.length; i++) {

        myArray = doc.pathItems[0].pathPoints.anchor;

        myPType = doc.pathItems[0].pathPoints.pointType;

        myPleft = doc.pathItems[0].pathPoints.leftDirection;

        myPright = doc.pathItems[0].pathPoints.rightDirection;

        }

   

    doc.pathItems[0].pathPoints.add();

   

    var myArr =  [100,150];

    var myTP = PointType.CORNER;

    var myTl = myArr;

    var myTr = myArr;

   

    myArray.splice(1, 0, myArr);

    myPType.splice(1, 0, myTP);

    myPleft.splice(1, 0, myTl);

    myPright.splice(1, 0, myTr);

   

    for (i=doc.pathItems[0].pathPoints.length-1; i >=0; i--) {

        doc.pathItems[0].pathPoints.anchor = myArray;

        doc.pathItems[0].pathPoints.pointType = myPType;

        doc.pathItems[0].pathPoints.leftDirection = myPleft;

        doc.pathItems[0].pathPoints.rightDirection = myPright;

        }

    } 

Votes

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
Community Beginner ,
Jul 21, 2015 Jul 21, 2015

Copy link to clipboard

Copied

Thanks a lot Silly-V, that was a stupid mistake. My script is now fully completed thanks to you!

pixxxel schubser, thanks this is very heplful! I understand now why I couldn't use splice on the whole pathPoints array/object.

If anyone's interested, here's a reusable function based on pixxxel schubser last message, though setEntirePath works fine too if you don't want to deal with control points:

if (app.documents.length > 0) {

    var doc = app.activeDocument;

    var line = doc.pathItems.add();

    line.stroked = true;

    line.filled = false;

    line.setEntirePath([[200, -200], [600, -200]]);

   

    var newPAnchor = [400, -400]

    insertInPath(doc.pathItems[0], newPAnchor, newPAnchor, newPAnchor, PointType.CORNER, 1, 0);

    }

// add a new point in a path at the specified index (or replace a preexisting point if spliceDeleteCount is set to 1)

function insertInPath(pathItem, pAnchor, pCtrlL, pCtrlR, pType, spliceAtIndex, spliceDeleteCount) {

   

    // initialize temporary arrays

    var iAnchor = [];

    var iCtrlL = [];

    var iCtrlR = [];

    var iType = [];

    // fill temporary arrays so they are equivalent to the current pathItem's arrays

    for (i=0; i < pathItem.pathPoints.length; i++) {

        iAnchor = pathItem.pathPoints.anchor;

        iCtrlL = pathItem.pathPoints.leftDirection;

        iCtrlR = pathItem.pathPoints.rightDirection;

        iType = pathItem.pathPoints.pointType;

        }

   

    // add a point at the end of pathItem's arrays to increase their lenghts by one

    pathItem.pathPoints.add();

   

    // insert the point properties at the correct index in the temporary arrays

    iAnchor.splice(spliceAtIndex, spliceDeleteCount, pAnchor);

    iCtrlL.splice(spliceAtIndex, spliceDeleteCount, pCtrlL);

    iCtrlR.splice(spliceAtIndex, spliceDeleteCount, pCtrlR);

    iType.splice(spliceAtIndex, spliceDeleteCount, pType);

   

    // replace the values of pathItem's arrays with the values from the temporary arrays

    for (i=pathItem.pathPoints.length-1; i >=0; i--) {

        pathItem.pathPoints.anchor = iAnchor;

        pathItem.pathPoints.leftDirection = iCtrlL;

        pathItem.pathPoints.rightDirection = iCtrlR;

        pathItem.pathPoints.pointType = iType;

        }

    }

Votes

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 ,
Jul 21, 2015 Jul 21, 2015

Copy link to clipboard

Copied

klts wrote:   If anyone's interested, here's a reusable function "insertInPath"


Nice job. Just curious, what is it you are creating and / or using this for ?

Votes

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
Community Expert ,
Jul 21, 2015 Jul 21, 2015

Copy link to clipboard

Copied

W_J_T schrieb:

… Just curious, what is it you are creating and / or using this for ?

An interesting question.

W_J_T schrieb:

Nice job …

Hmmh?

Really?

A very good feedback.

Yes.

Really I like it, particularly the description.

But a good job? …

… This is the same code, that I've posted before (but only with description, with renamed variables and packed into a function)

And a little bit I miss the source or the origin or the repository (what is the correct word for this?) in the code itself.

Votes

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 ,
Jul 21, 2015 Jul 21, 2015

Copy link to clipboard

Copied

Edit: Oops!

Sorry, pixxxel schubser I was just glancing through the thread, good job to you.

Speaking of repositories, do you have one? I always love looking at you code / snippets, there is always something good in your posts. Link to your code repository for perusing? 😉

Votes

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
Community Beginner ,
Jul 22, 2015 Jul 22, 2015

Copy link to clipboard

Copied

Yes, I only renamed and reordered the variables and added comments so it makes more sense (mostly to me) if and when I need to use it later.

Sorry pixxxel schubser, I though saying it was based on your code was enough. For the next time what comment do you think I should put in the function for pointing to the source?

A link to this thread, something like "function by pixxxel schubser", both or something else? I'm still new to scripting so I'm not familiar with these customs.

I can't edit a previous post once somebody has answered to it right?

W_J_T, the script I made is used to generate geometric shapes and patterns by selecting a seed and inputing the number of iterations in a prompt box (possibly thousands of shapes, very time-consuming to do by hand). The objects which paths get subdivided (this is where I needed to reorder vertices) are actually  "guide objects" used to generated other shapes and are then discarded afterwards.

I know there is a script named Divide (length) by shspage which does the subdivision and much more, but I did this project mostly to get better at scripting and copying someone else's code doesn't really help much with that. And to be honest, I'm finally taking a look at it now, and even after Silly-V and pixxxel schubser explanations I still can't figure out his for loops in the applyData2Path and applyData2AfterIdx functions. I'll have to take more time to read the entire thing later.

Votes

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 ,
Jul 22, 2015 Jul 22, 2015

Copy link to clipboard

Copied

Yes that type of script reference is always good, with both.

klts wrote:

W_J_T, the script I made is used to generate geometric shapes and patterns by selecting a seed and inputing the number of iterations in a prompt box (possibly thousands of shapes, very time-consuming to do by hand). The objects which paths get subdivided (this is where I needed to reorder vertices) are actually  "guide objects" used to generated other shapes and are then discarded afterwards.

That sounds really interesting, are you planning on posting the final code somewhere? I would love to see the outcome.

Votes

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
Community Beginner ,
Jul 22, 2015 Jul 22, 2015

Copy link to clipboard

Copied

Yes I would like to release it at some point but not right now. I'm pretty sure there's quite a few things I will be able to do better when I'll have a bit more experience with scripting. Things like a proper UI panel and progress bar (which doesn't update correctly right now), good/useful variable names and comments, there's also a crash when you ask for too many iterations that I haven't find how to fix yet.

But if you can give me some feedback on the code I can send you what I have right now which is functional and achieve its purpose, even though I'd like to add more features and polish things up a bit in the future. I just don't want to post it here as if it was a finished product because it's not.

Votes

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
Community Expert ,
Jul 22, 2015 Jul 22, 2015

Copy link to clipboard

Copied

LATEST

for sake of completeness, indeed the Index() function in Javascript seems to be broken...and the documentation is wrong (surprise).

the good news (sort of) is that this function does work in VB...and it's properly documented (surprise again!)

pathPointsMethods.JPG

Votes

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
Community Expert ,
Jul 22, 2015 Jul 22, 2015

Copy link to clipboard

Copied

W_J_T schrieb:

… Speaking of repositories, do you have one? I always love looking at you code / snippets, there is always something good in your posts. Link to your code repository for perusing? 😉

Sorry, I only have my own snippet libraries here at home (and the knowledge base in my head ) – but not online. Most of them I wrote here in Forum is based on that.

klts schrieb:

…

For the next time what comment do you think I should put in the function for pointing to the source?

A link to this thread, something like "function by pixxxel schubser", both or something else? I'm still new to scripting so I'm not familiar with these customs.

If I use snippets or parts of scripts, written by others (and you cannot find exactly this part „at every corner in the www“) then it's a good way to do something like this.

Show the source:

// https://forums.adobe.com/message/7759845#7759845

// script (or part of script) written by author (no matter if real name or nick name)

Or you can also use a phrase like this:

// ---------------------

// based on function (or on code) by author

… your adapted code

// ---------------------

But don't worry. All is ok

Have fun

Votes

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