Working with Annotations

When PSPDFKit for Web is initializing (while the load() promise resolves), it’ll start to load annotations from the server or the raw PDF. These annotations will be made available via the Instance#getAnnotations API.

The API will return an immutable snapshot of the currently available annotations in the UI. This means that the returned list could include invalid annotations. As an example, consider the following workflow:

  1. The user creates a new text annotation on a page.

  2. Now the user double-clicks the annotation and removes the text, making the annotation invalid since it doesn’t have any text. But since the annotation isn’t yet deselected, it remains visible.

  3. Next, the user updates the color of the text by using the annotation toolbar. The annotation will still be invalid even though a change occurred.

  4. At the end, the user decides to type more text and deselects the annotation again. The annotation is now valid.

To allow for very fine control, we decided to always expose a current snapshot that completely reflects the UI. Check out the Detecting If Annotations Have Changed guide to find out the difference between a UI update and a save callback.

Because of the fact that PSPDFKit for Web loads annotations on demand, the Instance#getAnnotations API returns a Promise that will resolve to the annotation once it’s loaded. For example, if you access annotations on the last page of a large PDF, we first make the HTTP request to load these annotations, since we don’t initialize all the data upfront. When the request is complete, we can resolve the Promise and return the annotations:

const { Point } = PSPDFKit.Geometry;

PSPDFKit.load(configuration).then(async (instance) => {
  const annotations = await instance.getAnnotations(0);
  annotations.forEach((annotation) => console.log(annotation.pageIndex));

  // Filter annotations by type.
  const inkAnnotations = annotations.filter(
    (annotation) => annotation instanceof PSPDFKit.Annotations.InkAnnotation
  );

  // Filter annotations at a specific point.
  const point = new Point({ x: 20, y: 30 });
  const annotationsAtPointInPage = annotations.filter((annotation) =>
    annotation.boundingBox.isPointInside(point)
  );

  // Get the number of annotations on the first page.
  const totalAnnotations = annotations.size;
});

Standalone Mode

In a PSPDFKit for Web installation that’s deployed in Standalone mode, annotations will be stored in memory until they’re exported. Please see the guide on importing and exporting for more information.