Copy link to clipboard
Copied
I have not been able to get the correct stacking order of pageItems within a layer/page (in CS5). This was simple to do in CS4 as something like this (CurrentPageItem = myPage.pageItems😉 would return pageItems in the actual stacking order in the document.
With CS5 all textframes come together and all rectangles come together, irrespective of them stacked in any order (TextFrame, Rectangle, TextFrame,.... would come out as TextFrame, TextFrame and Rectangle). Some solutions already in the forum point to changing to older version (6.0), but I don't want to do that.
Can there be a way to determine STACKING ORDER within the layer/page in CS5?
Copy link to clipboard
Copied
Marc Autret wrote:
var zOrderById = {}, itemZO = pgItems.everyItem().index, itemIds = pgItems.everyItem().id, i = pgItems.length; while( i-- ) { zOrderById[itemIds] = itemZO; }
That's more or less the same idea as what I wrote, but more elegently written (and efficient) because you avoided temporary objects and using sort.
One little point, though:
You should have used an array instead of an object for zOrderById...
Harbs
Copy link to clipboard
Copied
You should have used an array instead of an object for zOrderById...
But JS doesn't have sparse arrays, so if you have non-contguous id numbers, as you necessarily will, zOrderByID blows up rapidly, and that's bad. (Also, pseudo-sparse arrays in JS give confusing behavior when you ask about properties like .length).
Copy link to clipboard
Copied
Ah.
Good points.
I'll stick with my function...
Harbs
Copy link to clipboard
Copied
rgartlan wrote:
The documentation says a pageitem's 'index' property is "The index of the PageItem within its containing object." -- but oPage only has two objects. The code blows up if I run it with this set of data, because pageItemArray[ indexes[0] ] translates to pageItemArray[5].
The point is that a page is not a "containing object". In fact, a page is not much more than a rectangle...
Generally, the containing object is what you get from obj.parent. (Which is a Spread or MasterSpread for top-level objects in CS5+.)
Harbs
Copy link to clipboard
Copied
I use the findings of this thread to get the z-index for an HTML Export. This works well with less than ~200 PageItems per Page. With more PageItems InDesign becomes unresponsive and I need to kill the process manually. Tested with Windows 7 and CS 6/CC 2015.
The everyItem() function slow with > 150 PageItems and unusable with > 600 PageItems.
I don't see a solution, but want to add this bit of information to the thread.
For testing I used the following script:
var items = 200;
var dok = app.documents.add();
var page = dok.pages[0];
$.writeln("start " + Date());
for (var i = 0; i < items; i++) {
page.textFrames.add();
}
$.writeln("analyse complete " + Date());
var zOrderById = {};
var itemZO = page.pageItems.everyItem().index,
itemIds = page.pageItems.everyItem().id,
t = page.pageItems.length;
while( t-- ) {
zOrderById[itemIds
] = itemZO ; }
$.writeln("end " + Date());
Copy link to clipboard
Copied
Not too bad here, Mac mini i7 16GB CC2015.1
start Wed Dec 09 2015 13:25:40 GMT-0000
analyse complete Wed Dec 09 2015 13:25:44 GMT-0000
end Wed Dec 09 2015 13:25:50 GMT-0000
Copy link to clipboard
Copied
How many items did you tried?
Change the number of items in line 1. I could not process more than 1000 without killing the process after ~10 minutes.
Would be interesting if it runs better on Mac.
Copy link to clipboard
Copied
1000
start Wed Dec 09 2015 13:38:21 GMT-0000
analyse complete Wed Dec 09 2015 13:38:36 GMT-0000
end Wed Dec 09 2015 13:44:58 GMT-0000
Result: undefined
Copy link to clipboard
Copied
1000 items: i5 2,6 GHz, 4 GB, Windows 7
start Wed Dec 09 2015 15:12:34 GMT+0100
analyse complete Wed Dec 09 2015 15:12:50 GMT+0100
end Wed Dec 09 2015 15:26:22 GMT+0100
Ergebnis: undefined
To long for the task... Mac looks better, but machines are not comparable.
Copy link to clipboard
Copied
Hi Gregor,
with my Mac I can see similar results like Pickory by running your code.
But here is a different approach and a very fast one.
It took the snippet about 0.35 seconds on my Mac to check and write the stacking order of all first class pageItems (1000 items) to an array:
var startTime = Date.now();
var allPageItems = app.documents[0].pages[0].allPageItems;
var pageItemIndex = 0;
var pageItemsInStackingOrder = [];
for(var n=0;n<allPageItems.length;n++){
//We need only firts class citizens:
if(allPageItems
.parent.constructor.name !== "Spread"){ continue
};
pageItemsInStackingOrder[pageItemIndex] = allPageItems
.id; pageItemIndex++;
};
var endTime = Date.now();
var elapsedTimeInSeconds = (( endTime - startTime ) / 1000 );
$.writeln(elapsedTimeInSeconds+"\t"+"sec.");
// A protocol to see the stacking order in the JavaScript Console of the ESTK from top to down:
for(var n=0;n<pageItemsInStackingOrder.length;n++){
$.writeln(n+"\t"+pageItemsInStackingOrder
);
};
//Result: undefined
// 0.352 sec.
// for 1200 page items
I assume that the allPageItems array already has the right stacking order of the page items on the page.
If we want only first citizens, their parent will always be the spread (CS5 and above), we have to only check for parent and continue the loop.
So your running time will depend a bit on how many nested pageItems are on the page.
MacBook Pro (15 Inch, Early 2011)
2 GHz Intel Core i7
8 GB 1333 MHz DDR3
Uwe
Copy link to clipboard
Copied
Hey Uwe,
cool solution. It works with my first tests! Think we found a new best practise here.