2

I've got a bunch of objects on an artboard and I'd like to know the X/Y positions of them all. It would be fine to either have pixel values, or a % from the sides of the artboard.

Importantly, I don't want to just click each one and then copy down the values stored in their position fields. Ideally I could generate a list of:

object_name : x_position, y_position

values. Anyone have an idea how I could accomplish something like this in Illustrator or Inkscape?

4
  • 2
    an SVG file has (this;probably) information embedded
    – Ilan
    Commented May 11, 2015 at 21:13
  • What do you consider an object? Is it a path group compound path... What do you consider its postion the upper corner of a BB, individual vertices center etc. @Ilan yes but not necessarily in the way he hopes. A ascript could be easily made.
    – joojaa
    Commented May 11, 2015 at 21:23
  • I'm pretty flexible in terms of what exactly I mean by "x,y" position, because I can always translate it on my own if it's not just what I want. Ideally, it would be the center point of an object (e.g., a circle, and I want the center of the circle). Not sure if that's qualified as a "path" or not. If all that information is stored in the SVG file, then it sounds like that might be quite easy...
    – choldgraf
    Commented May 12, 2015 at 1:53
  • All information is stored in the svg its just that data is a tree. So if you have groups its hard to say directly from the file. because each group is measured in local coordinates.
    – joojaa
    Commented May 12, 2015 at 3:57

3 Answers 3

4

You can also do this with Illustrator scripting, with same caveat as @Wrzlprmft's answer that objects have to be at top level. (you can recurse the for loop for groups compound paths etc if you wish. This is a quick example after all):

#target illustrator

var sel = app.activeDocument.selection; 
var file = File.saveDialog('save centers', 'center:*.txt');
file.open('w')

for(var i = 0; i < sel.length; i++){
      if(sel[i].typename == "PathItem"){
          var obj = sel[i];
          var center = obj.position
          center[0] -= obj.width/2.0;
          center[1] += obj.height/2.0;  
          file.write(obj.name+" : "+center[0]  + ", "+center[1]+"\n"); 
      }
}

file.close();

Script asks for file name and dumps data into it (without warning!). To run put in a .jsx file and drag and drop to illustrator or use extendScript toolkit.

1

If you look into the source of your SVG (open it with a text editor), you will find mainly stuff like this:

<rect
   style="opacity:0.57009343;color:#000000;fill:#3f3790"
   id="rect2996"
   width="10.714286"
   height="52.857143"
   x="282.85715"
   y="155.16518"
   transform="translate(242.40625,114.78125)" />

Those lines starting with x= and y= contain exactly what you are looking for. You can now write some script to extract them, e.g., with an Inkscape-saved SVG the following works for me (for other SVGs you might need some adjustment):

grep " x=\"\| y=\"" drawing.svg | sed "s/[^\"]*\"//;s/\".*//" | paste -d '\t' - -

Note that the above may not work if the objects belong to a transformed group or are otherwise special.

1
  • 1
    Only if rect does not belong to a transformed group! Also no name of object.
    – joojaa
    Commented May 12, 2015 at 7:54
0

@joojaa gave a fantastic answer here. I used it to write the below script. I formatted it to spit out JSON with an array of paths, each an object with a pathname (the name of your path on in the layers panel) and an array of x/y points on that path.

To get exactly the right numbers to output you need to do a little bit of maths with the position of your artboard as things get offset otherwise.

I've used JSON as I wanted these numbers to be fed into some graphical javascript - but it's pretty easy to format them any way you like. The commented website is pretty useful btw:

#target illustrator
// help here
// https://illustrator-scripting-guide.readthedocs.io/jsobjref/PathItems/

var doc = app.activeDocument; 
var sel = doc.selection; 
var activeAB = doc.artboards[doc.artboards.getActiveArtboardIndex()]; // get active AB
var docLeft = activeAB.artboardRect[0];
var docTop = activeAB.artboardRect[1]; 

var file = File.saveDialog('save centers', 'center:*.txt');
file.open('w')

file.write('{"paths": [\n'); 

for(var i = 0; i < sel.length; i++){
    if(sel[i].typename == 'PathItem'){

        var obj = sel[i];
        var pathLen = obj.pathPoints.length;

        file.write('{\n'); 
        file.write('"name":"' + obj.name + '","points":[\n'); 
        for ( j = 0; j < pathLen; j++ ) {
            var center = obj.pathPoints[j].anchor;
            var x = parseFloat(Math.abs(docLeft)) + parseFloat(center[0].toFixed(4));
            var y = docTop - center[1].toFixed(4);
            file.write('['+ x + ', ' + y + ']');
            if(j < pathLen - 1) {
                file.write(',');
            }
        }

        file.write(']}\n'); 
        if(i < sel.length - 1) {
            file.write(',');
        }
    }
}

file.write(']\n}\n'); 

file.close();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.