Inkscape.org
Creating New Extensions Accessing and changing object location
  1. #1
    kyocobra kyocobra @kyocobra

    I'm certainly not the hottest python programmer, but I'm trying to recreate Inkscape's Object > Arrange > Rectangular grid command within a python extension for Inkscape 1.0.1. This will be part of a more comprehensive extension that organizes 50+ objects into 3x3 grids on separate layers.

    So far, I've been able to grab a dictionary of the selected objects using

    section = self.svg.selected

    But after scrolling through inkex docs on GitLab, I can't seem to figure out how to move objects around or really do anything with this selection dictionary.

    How could I (i) arrange all these objects in a grid and (ii) center that grid on the page?

  2. #2
    Ellen Wasbø Ellen Wasbø @EllenWasbo

    I'm certainly neither the hottest python programmer, but I learn by doing and I dare to point you in some direction (at your own risk).

    I guess you could make use of the transformation matrix and use the bounding boxes to arrange the objects. There is a submodule called transforms with methods for defining the transformation matrix (I have not used that myself as I struggle with the lack of examples for the syntax). What I have done is to set the transformation matrix for an element like this:

    for elem in self.svg.get_selected():

         elem.set('transform','scale(2) rotate(45) translate(10,10)')

    But the arranging and centering - I guess you would have to do the math based on the bounding_box() and page size (get_page_bbox()) from the svg submodule

  3. #3
    kyocobra kyocobra @kyocobra

    @EllenWasbo that's money, baby.

    I was able to get the centers of bounding_box() objects and place them at a destination x_dest, y_dest with this:

    # destinations for center of objects (mm from top left of page)
    x_dest = 50 
    y_dest = 20
    
    selection = self.svg.get_selected()
    
    for elem in selection:
        
        bbox = elem.bounding_box() # money maker
        x, y = bbox.center # grab center
        
        # calculate delta x, delta y, and translate object
        translate_cmd = 'translate(%.2f, %.2f)' % (x_dest - x, y_dest - y)
        elem.set('transform', translate_cmd)

    A big component was learning how to read the inkex docs. You have to pay close attention to indentation on the webpage to determine which properties and functions fall under which class. I found the center property for bounding_box().center that way.

    You can also get the dimensions (width, height) of a bounding box by using the bounding_box().minimum and bounding_box().maximum properties. This and self.svg.get_page_bbox() are great for calculating grid spacing.

    selection = self.svg.get_selected() # get selected objects
    
    # get dimensions of reference object (first in selection)
    
    # "selection" is an ordered dictionary, you can grab the first
    # element like this (don't know how it works)
    bbox = next(iter(selection)).bounding_box()
    
    min_vect = bbox.minimum # upper left (returns 2dvector)
    max_vect = bbox.maximum # bottom right (also 2dvector)
    
    x1 = min_vect.x # grab "x" property
    x2 = max_vect.x # ...
    width = x2 - x1
    
    y1 = min_vect.y # grab "y" property
    y2 = max_vect.y # ...
    height = y2 - y1
    

    Thanks for the help, detective. I'll be scanning the docs to create new layers when my grid size overflows. Let me know if you have any more leads. :)

  4. #4
    Ellen Wasbø Ellen Wasbø @EllenWasbo

    Glad to see that my fumbling pointing put you on track 😎

  5. #5
    grillover grillover @grillover
    *

    How I can add/embed extension to a site, I want? 

  6. #6
    Ellen Wasbø Ellen Wasbø @EllenWasbo

    grillover: sounds like that is a question for a separate thread and that you need to explain more on what you actually want to achieve.

Inkscape Inkscape.org Inkscape Forum Creating New Extensions Accessing and changing object location