This guide describes how you size and position page elements using affine transforms. For a conceptual introduction to affine transforms, see the Transforms concept guide.

## Transforming elements

The Slides API lets you reposition and scale elements on a page. To do this, first determine what kind of transformation needs to be applied, then apply that transform using the presentations.batchUpdate method containing one or more UpdatePageElementTransformRequest elements.

Transforms can be made in one of two applyModes:

`ABSOLUTE`

transforms*replace*the element's existing transformation matrix. Any parameters you omit from the transform update request are set to zero.`RELATIVE`

transforms are*multiplied*with the element's existing transformation matrix (the order of multiplication matters):

Relative transforms move or scale the page element from where it currently is; for example, moving a shape 100 points to the left, or rotating it 40 degrees. Absolute transforms discard existing position and scale information; for example, moving a shape to the center of the page, or scaling it to be a specific width.

Complex transformations can usually be expressed as a sequence of simpler ones. Precalculating a transform—combining multiple transformations using matrix multiplication—can often reduce overhead.

For some operations, you must know what an element's existing transform parameters are. If you don't have these values, you can retrieve them with a presentations.pages.get request.

### Translation

Translation is simply the action of moving a page element to a new position on
the same page. *Absolute* translations move the element to a specific point,
while *relative* translations move the element a specific distance.

A basic translation transform matrix has the form:

When you use an UpdatePageElementTransformRequest to translate an element (without altering its size, shear, or orientation), you can use one of the following AffineTransform structures:

// Absolute translation: { 'transform': { 'scaleX':current scaleX value, 'scaleY':current scaleY value, 'shearX':current shearX value, 'shearY':current shearY value, 'translateX':X coordinate to move to, 'translateY':Y coordinate to move to, 'unit': 'EMU' // or 'PT' } } // Relative translation (scaling must also be provided to avoid a matrix multiplication error): { 'transform': { 'scaleX': 1, 'scaleY': 1, 'translateX':X coordinate to move by, 'translateY':Y coordinate to move by, 'unit': 'EMU' // or 'PT' } }

### Scaling

Scaling is the action of stretching or squeezing an element along the X and/or Y dimension to change its size. A basic scaling transform matrix has the form:

You can use this matrix form directly as a `RELATIVE`

transform to resize an
element, but this can also affect the element's rendered shear and translation.
To scale the element without affecting its shear or translation, shift to its
reference frame.

### Rotation

Rotation transforms rotate a page element around a point, using the scaling and shear parameters. The basic rotation transform matrix has the following form, where the angle of rotation (in radians) is measured from the X-axis, moving counterclockwise:

As with scaling, you can use this matrix form directly as a `RELATIVE`

transform to rotate an element, but this causes the element to be rotated
about the origin *of the page*. To rotate the element about its center or a
different point,
shift to that reference frame.

### Reflection

Reflection mirrors an element across a specific line or axis. The basic x- and y-axis reflection transform matrix has the following forms:

As with scaling, you can use this matrix form directly as a `RELATIVE`

transform to reflect an element, but this causes the element to translate as
well. To reflect the element without any translation,
shift to its reference frame.

### Element reference frames

Applying a basic scale, reflection, or rotation transform directly to a page element produces a transformation in the page's reference frame. For example, a basic rotation rotates the element about the page's origin (the upper-left corner). However, you can operate in the reference frame of the element itself, for example to rotate an element around its center point.

To transform an element within its own reference frame, enclose it between two
other translations: a preceding translation `T1`

that moves the element center
to the page origin, and a following translation `T2`

that moves the element
back to its original position. The full operation can be expressed as a matrix
product:

You can also switch to other reference frames, by translating different points to the origin instead. These points become the center of the new reference frame.

It's possible to perform each of these transformations individually as
sequential `RELATIVE`

transform requests. Ideally, you should precompute
`A'`

above with matrix multiplications and apply the result as a single
`ABSOLUTE`

transform. Alternatively, precompute the `T2 * B * T1`

product
and apply that as a single `RELATIVE`

transform. These are both more efficient,
in terms of API operations, then sending the transform requests individually.

## Limitations

Some sizing and positioning fields are incompatible with some types of page elements. The table below summarizes the compatibility of certain page elements with sizing and positioning fields.

Field | Shape | Video | Table |
---|---|---|---|

Translation |
✔ | ✔ | ✔ |

Scale |
✔ | ✔ | No** |

Shear |
✔ | No | No |

** To update table row and column dimensions, use
`UpdateTableRowPropertiesRequest`

and
`UpdateTableColumnPropertiesRequest`

.

All sizing and positioning fields might give unexpected results if the page element has shearing. All limitations are subject to change. For up to date information, see Google Slides API.

## The Slides API might refactor your values

When you create a page element, you can specify a size and transform that provide a certain visual result. However, the API may replace your provided values with other ones that yield the same visual appearance. In general, if you write a size using the API, you are not guaranteed to be returned the same size. However, you should get the same results if you take the transform into account.