> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/annotation/rect-and-quads.md).

# Annotation Rects & Quads

Enhance your document annotations with Rects & Quads using Apryse Web SDK. Learn how to represent annotation bodies as rectangles or arrays for precise dimensions, intersections, and transformations.

Annotations take up a certain amount of space on a document page. Their "body" in the document is commonly represented as a rectangle or an array of rectangles. These rectangles are provided as either a [`Rect`](https://sdk.apryse.com/api/web/Core.Math.Rect.html) or [`Quad`](https://sdk.apryse.com/api/web/Core.Math.Quad.html) object in WebViewer.

Most annotations will use a `Rect` as their body, whereas `Quad` objects are typically for annotations that mark up text. With a `Quad`, you can convert it to a `Rect` and vice-versa. With a `Rect`, you can get more information from the shape such as its dimensions or checking for intersections with other rectangles.

## Rect

Most annotations will work with [`Rect`](https://sdk.apryse.com/api/web/Core.Math.Rect.html) objects. Specifically for resizing through the use of [`setRect`](https://sdk.apryse.com/api/web/Core.Annotations.Annotation.html#setRect).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const { Core } = instance;
const { Annotations, Math } = Core;
const rectAnnot = new Annotations.RectangleAnnotation({
    PageNumber: 1,
    X: 0,
    Y: 0,
    Width: 100,
    Height: 50,
});
const rect = rectAnnot.getRect();
const width = rect.getWidth();
rect.translate(5, 5); // Move right and down by 5 pixels
rect.x2 *= 2;
rectAnnot.setRect(rect);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Rect](https://sdk.apryse.com/api/web/Core.Math.Rect.html) [Rect.getWidth](https://sdk.apryse.com/api/web/Core.Math.Rect.html#getWidth) [Rect.translate](https://sdk.apryse.com/api/web/Core.Math.Rect.html#translate) [RectangleAnnotation](https://sdk.apryse.com/api/web/Core.Annotations.RectangleAnnotation.html) [Annotation.getRect](https://sdk.apryse.com/api/web/Core.Annotations.Annotation.html#getRect) [Annotation.setRect](https://sdk.apryse.com/api/web/Core.Annotations.Annotation.html#setRect)

### Collisions

There are two APIs for collision detection. You can use either [`intersect`](https://sdk.apryse.com/api/web/Core.Math.Rect.html#intersect) or [`contains`](https://sdk.apryse.com/api/web/Core.Math.Rect.html#contains) with another rectangle to check if the two rectangle bodies overlap. The difference, however, is that `contains` strictly checks whether one rectangle is inside another.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const { Core } = instance;
const { Annotations } = Core;
const rectAnnot1 = new Annotations.RectangleAnnotation({
    X: 0,
    Y: 0,
    Width: 100,
    Height: 50,
});
const rectAnnot2 = new Annotations.RectangleAnnotation({
    X: 50,
    Y: 50,
    Width: 100,
    Height: 50,
});
const rect1 = rectAnnot1.getRect();
const rect2 = rectAnnot2.getRect();
console.log(rect1.intersects(rect2)); // true
console.log(rect1.contains(rect2));   // false
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Rect.intersect](https://sdk.apryse.com/api/web/Core.Math.Rect.html#intersect) [Rect.contains](https://sdk.apryse.com/api/web/Core.Math.Rect.html#contains) [Annotation.getRect](https://sdk.apryse.com/api/web/Core.Annotations.Annotation.html#getRect)

### TransformationBuilder

Occasionally, you may need to transform a rectangle a certain way or perhaps you need a special transformation for your custom annotation. In this case, you can transform a `Rect` with a [`Matrix`](https://sdk.apryse.com/api/web/Core.Math.Matrix.html).

However, matrices are difficult to work with and are not easily recognizable. WebViewer provides a [`TransformationBuilder`](https://sdk.apryse.com/api/web/Core.Math.TransformationBuilder.html) to assist in building a transformation out. The operations you set with the `TransformationBuilder` is in the order you would perform them (not in reverse order).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const { Core } = instance;
const { Annotations, Math } = Core;
const rectAnnot = new Annotations.RectangleAnnotation({
    PageNumber: 1,
    X: 0,
    Y: 0,
    Width: 100,
    Height: 50,
});
const rect = rectAnnot.getRect();
const centerPoint = rect.getCenterPoint();
const builder = new Core.Math.TransformationBuilder();
// Rotate with respect to annotation origin
const transform = builder
                    .translate(-centerPoint.X, -centerPoint.Y) // Move annot origin to 0,0
                    .rotate(90)                                // Rotate 90 degrees
                    .translate(centerPoint.X, centerPoint.Y)   // Translate back
                    .getFinalTransform();
rect.transform(transform);
rectAnnot.setRect(rect);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Rect.getCenterPoint](https://sdk.apryse.com/api/web/Core.Math.Rect.html#getCenterPoint) [Rect.transform](https://sdk.apryse.com/api/web/Core.Math.Rect.html#transform) [TransformationBuilder](https://sdk.apryse.com/api/web/Core.Math.TransformationBuilder.html) [TransformationBuilder.translate](https://sdk.apryse.com/api/web/Core.Math.TransformationBuilder.html#translate) [TransformationBuilder.rotate](https://sdk.apryse.com/api/web/Core.Math.TransformationBuilder.html#rotate) [TransformationBuilder.getFinalTransform](https://sdk.apryse.com/api/web/Core.Math.TransformationBuilder.html#getFinalTransform)

If you want to use the transformation matrix with the Canvas context, you can use the [`toTransform`](https://sdk.apryse.com/api/web/Core.Math.Matrix.html#toTransform) API on the [`Matrix`](https://sdk.apryse.com/api/web/Core.Math.Matrix.html) to get an array of values to be used with [`setTransform`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform/) on the context.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
ctx.setTransform(...transform.toTransform());
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Matrix.toTransform](https://sdk.apryse.com/api/web/Core.Math.Matrix.html#toTransform) [CanvasRenderingContext2D.setTransform](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform/)

## Quad

[`Quads`](https://sdk.apryse.com/api/web/Core.Math.Quad.html) are commonly found with annotations that mark up text. In many of the cases, these annotations, like [`HighlightAnnotation`](/web/annotation/annotation-types/highlightannotation.md), contain a list of `Quad` objects representing the lines of text that are marked.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const { Core } = instance;
const { Annotations, Math } = Core;
const annot = new Annotations.TextHighlightAnnotation({
    PageNumber: 1,
    // This should actually be the location of actual text
    Quads: [
        new Math.Quad(
            0, 50,      // Lower left
            100, 50,    // Lower right
            100, 0,     // Upper right
            0, 0,       // Upper left
        ),
        // Annotation can have more quads representing additional lines of text
    ],
    StrokeColor: new Annotations.Color(255, 0, 0, 1),
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

[TextHighlightAnnotation](https://sdk.apryse.com/api/web/Core.Annotations.TextHighlightAnnotation.html) [Color](https://sdk.apryse.com/api/web/Core.Annotations.Color.html) [Quad](https://sdk.apryse.com/api/web/Core.Math.Quad.html)

### Conversion between `Rect`

`Quad` objects are limited in functionality, but you can convert them to a `Rect` where you will gain access to its APIs. After you are done, you can convert it back to a `Quad`.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const quad = new Math.Quad(
    0, 50,      // Lower left
    100, 50,    // Lower right
    100, 0,     // Upper right
    0, 0,       // Upper left
);
const rect = quad.toRect(); // Result is a rectangle 100w x 50h in the top left corner
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Quad.toRect](https://sdk.apryse.com/api/web/Core.Math.Quad.html#toRect)

To convert it back:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const otherQuad = rect.toQuad();
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Rect.toQuad](https://sdk.apryse.com/api/web/Core.Math.Rect.html#toQuad)

## Next steps

See how `Rect` and `Quad` objects are used in some of our annotation guides, specifically [`RectangleAnnotation`](/web/annotation/annotation-types/rectangleannotation.md) and [`HighlightAnnotation`](/web/annotation/annotation-types/highlightannotation.md)!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/annotation/rect-and-quads.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
