Skip to content

Position

positions_vertical = [Dimensions.Top, Dimensions.Bottom, Dimensions.CenterY] module-attribute

ALIGNMENT

align(axis=None, layer=None, reference=None)

Align the currently active layer to current selection, vertically or horizontal. @param axis: Which axis use when aligning the layer, can be provided as a single axis or list. @param layer: ArtLayer or LayerSet to align. Uses active layer if not provided. @param reference: Reference to align the layer within. Uses current selection if not provided.

Source code in src/helpers/position.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def align(
    axis: Union[str, list[str], None] = None,
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """
    Align the currently active layer to current selection, vertically or horizontal.
    @param axis: Which axis use when aligning the layer, can be provided as a single axis or list.
    @param layer: ArtLayer or LayerSet to align. Uses active layer if not provided.
    @param reference: Reference to align the layer within. Uses current selection if not provided.
    """
    # Default axis is both
    axis = axis or [Dimensions.CenterX, Dimensions.CenterY]

    # Get the dimensions of the reference and layer if not provided
    area = get_dimensions_from_bounds(app.activeDocument.selection.bounds) if not reference else (
        reference if isinstance(reference, dict) else get_layer_dimensions(reference))
    layer = layer or app.activeDocument.activeLayer
    item = get_layer_dimensions(layer)

    # Single axis provided
    if isinstance(axis, str):
        x = area[axis] - item[axis] if axis in positions_horizontal else 0
        y = area[axis] - item[axis] if axis in positions_vertical else 0
    else:
        x = area[axis[0]] - item[axis[0]]
        y = area[axis[1]] - item[axis[1]]

    # Shift location using the position difference
    layer.translate(x, y)

align_all(layer=None, reference=None)

Utility definition for passing CenterX and CenterY to align function.

Source code in src/helpers/position.py
62
63
64
65
66
67
def align_all(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing CenterX and CenterY to align function."""
    align([Dimensions.CenterX, Dimensions.CenterY], layer, reference)

align_bottom(layer=None, reference=None)

Utility definition for passing Bottom to align function.

Source code in src/helpers/position.py
110
111
112
113
114
115
def align_bottom(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing Bottom to align function."""
    align(Dimensions.Bottom, layer, reference)

align_horizontal(layer=None, reference=None)

Utility definition for passing CenterX to align function.

Source code in src/helpers/position.py
78
79
80
81
82
83
def align_horizontal(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing CenterX to align function."""
    align(Dimensions.CenterX, layer, reference)

align_left(layer=None, reference=None)

Utility definition for passing Left to align function.

Source code in src/helpers/position.py
86
87
88
89
90
91
def align_left(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing Left to align function."""
    align(Dimensions.Left, layer, reference)

align_right(layer=None, reference=None)

Utility definition for passing Right to align function.

Source code in src/helpers/position.py
94
95
96
97
98
99
def align_right(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing Right to align function."""
    align(Dimensions.Right, layer, reference)

align_top(layer=None, reference=None)

Utility definition for passing Top to align function.

Source code in src/helpers/position.py
102
103
104
105
106
107
def align_top(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing Top to align function."""
    align(Dimensions.Top, layer, reference)

align_vertical(layer=None, reference=None)

Utility definition for passing CenterY to align function.

Source code in src/helpers/position.py
70
71
72
73
74
75
def align_vertical(
    layer: Union[ArtLayer, LayerSet, None] = None,
    reference: Union[ArtLayer, LayerSet, dict, None] = None
) -> None:
    """Utility definition for passing CenterY to align function."""
    align(Dimensions.CenterY, layer, reference)

frame_layer(layer, reference, smallest=False, anchor=AnchorPosition.TopLeft, alignments=None)

Scale and position a layer within the bounds of a reference layer. @param layer: Layer to scale and position. @param reference: Reference frame to position within. @param smallest: Whether to scale to smallest or largest edge. @param anchor: Anchor position for scaling the layer. @param alignments: Alignments used to position the layer.

Source code in src/helpers/position.py
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def frame_layer(
    layer: Union[ArtLayer, LayerSet],
    reference: Union[ArtLayer, LayerSet, dict],
    smallest: bool = False,
    anchor: AnchorPosition = AnchorPosition.TopLeft,
    alignments: Union[Dimensions, list[Dimensions], None] = None
):
    """
    Scale and position a layer within the bounds of a reference layer.
    @param layer: Layer to scale and position.
    @param reference: Reference frame to position within.
    @param smallest: Whether to scale to smallest or largest edge.
    @param anchor: Anchor position for scaling the layer.
    @param alignments: Alignments used to position the layer.
    """
    # Get layer and reference dimensions
    layer_dim = get_layer_dimensions(layer)
    ref_dim = reference if isinstance(reference, dict) else get_layer_dimensions(reference)

    # Scale the layer to fit either the largest, or the smallest dimension
    action = min if smallest else max
    scale = 100 * action((ref_dim['width'] / layer_dim['width']), (ref_dim['height'] / layer_dim['height']))
    layer.resize(scale, scale, anchor)

    # Default alignments are center horizontal and vertical
    align(alignments or [Dimensions.CenterX, Dimensions.CenterY], layer, ref_dim)

position_between_layers(layer, top_layer, bottom_layer)

Align layer vertically between two reference layers. @param layer: Layer to align vertically @param top_layer: Reference layer above the layer to be aligned. @param bottom_layer: Reference layer below the layer to be aligned.

Source code in src/helpers/position.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def position_between_layers(
    layer: Union[ArtLayer, LayerSet],
    top_layer: Union[ArtLayer, LayerSet],
    bottom_layer: Union[ArtLayer, LayerSet]
) -> None:
    """
    Align layer vertically between two reference layers.
    @param layer: Layer to align vertically
    @param top_layer: Reference layer above the layer to be aligned.
    @param bottom_layer: Reference layer below the layer to be aligned.
    """
    docref = app.activeDocument
    bounds = [0, top_layer.bounds[3], docref.width, bottom_layer.bounds[1]]
    align_vertical(layer, reference=get_dimensions_from_bounds(bounds))

position_dividers(dividers, layers)

Positions a list of dividers between a list of layers. @param dividers: Divider layers to position, should contain 1 fewer objects than layers param. @param layers: Layers to position the dividers between.

Source code in src/helpers/position.py
139
140
141
142
143
144
145
146
147
148
149
def position_dividers(
    dividers: list[Union[ArtLayer, LayerSet]],
    layers: list[Union[ArtLayer, LayerSet]]
) -> None:
    """
    Positions a list of dividers between a list of layers.
    @param dividers: Divider layers to position, should contain 1 fewer objects than layers param.
    @param layers: Layers to position the dividers between.
    """
    for i in range(len(layers) - 1):
        position_between_layers(dividers[i], layers[i], layers[i + 1])

space_layers_apart(layers, gap)

Position list of layers apart using a given gap. @param layers: List of ArtLayers or LayerSets. @param gap: Gap in pixels.

Source code in src/helpers/position.py
196
197
198
199
200
201
202
203
204
205
def space_layers_apart(layers: list[Union[ArtLayer, LayerSet]], gap: Union[int, float]) -> None:
    """
    Position list of layers apart using a given gap.
    @param layers: List of ArtLayers or LayerSets.
    @param gap: Gap in pixels.
    """
    # Position each layer relative to the one above it
    for i in range((len(layers) - 1)):
        delta = (layers[i].bounds[3] + gap) - layers[i + 1].bounds[1]
        layers[i + 1].translate(0, delta)

spread_layers_over_reference(layers, ref, gap=None, inside_gap=None, outside_matching=True)

Spread layers apart across a reference layer. @param layers: List of ArtLayers or LayerSets. @param ref: Reference used as the maximum height boundary for all layers given. @param gap: Gap between the top of the reference and the first layer, or between all layers if not provided. @param inside_gap: Gap between each layer, calculated using leftover space if not provided. @param outside_matching: If enabled, will enforce top and bottom gap to match.

Source code in src/helpers/position.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def spread_layers_over_reference(
    layers: list[ArtLayer],
    ref: ArtLayer,
    gap: Optional[Union[int, float]] = None,
    inside_gap: Union[int, float, None] = None,
    outside_matching: bool = True
) -> None:
    """
    Spread layers apart across a reference layer.
    @param layers: List of ArtLayers or LayerSets.
    @param ref: Reference used as the maximum height boundary for all layers given.
    @param gap: Gap between the top of the reference and the first layer, or between all layers if not provided.
    @param inside_gap: Gap between each layer, calculated using leftover space if not provided.
    @param outside_matching: If enabled, will enforce top and bottom gap to match.
    """
    # Calculate outside gap if not provided
    outside_gap = gap
    if not gap:
        total_space = get_layer_dimensions(ref)['height'] - sum(
            [get_text_layer_dimensions(layer)['height'] for layer in layers]
        )
        outside_gap = total_space / (len(layers) + 1)

    # Position the top layer relative to the reference
    delta = (ref.bounds[1] + outside_gap) - layers[0].bounds[1]
    layers[0].translate(0, delta)

    # Calculate inside gap if not provided
    if gap and not inside_gap:
        # Calculate the inside gap
        ignored = 2 if outside_matching else 1
        spaces = len(layers) - 1 if outside_matching else len(layers)
        total_space = get_layer_dimensions(ref)['height'] - sum(
            [get_text_layer_dimensions(layer)['height'] for layer in layers]
        )
        inside_gap = (total_space - (ignored * gap)) / spaces
    elif not gap:
        # Use the outside gap uniformly
        inside_gap = outside_gap

    # Position the bottom layers relative to the top
    space_layers_apart(layers, inside_gap)