Sizing and Positioning Page Elements

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):

$$A' = BA$$

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:

$$T=\begin{bmatrix} 1 & 0 & translate\_x\\ 0 & 1 & translate\_y\\ 0 & 0 & 1 \end{bmatrix}$$

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:

$$S=\begin{bmatrix} scale\_x & 1 & 0\\ 1 & scale\_y & 0\\ 0 & 0 & 1 \end{bmatrix}$$

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:

$$R=\begin{bmatrix} cos(\theta) & sin(\theta) & 0\\ -sin(\theta) & cos(\theta) & 0\\ 0 & 0 & 1 \end{bmatrix}$$

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:

$$F_x=\begin{bmatrix} 1 & 0 & 0\\ 0 & -1 & 0\\ 0 & 0 & 1\\ \end{bmatrix}\qquad\qquad F_y=\begin{bmatrix} -1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\\ \end{bmatrix}$$

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:

$$A' = T2 \times B \times T1 \times A$$

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.

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.

Send feedback about...