Skip to content

Annotation Dialog

The annotation dialog lets users place interactive pins on any image inside the Uhuu Editor — without touching the source image. It opens a full-screen annotation editor where users can add markers, text labels, and callout cards at precise positions.

Why SVG Overlay Instead of Merging Into the Image

Most annotation tools burn annotations directly into a rasterized copy of the image. Uhuu takes a different approach: annotations are rendered as an SVG layer on top of the base image, and saved as structured data.

This matters for three reasons:

Non-destructive editing. Because annotations are a separate data record, not pixels baked into the image, users can always reposition, relabel, recolor, or delete individual pins. Changing the underlying photo does not erase the annotation layout — the pins simply reappear on the new image.

Crisp print output. Uhuu templates produce PDFs. Rasterized annotations degrade at high DPI because they were created at screen resolution. SVG annotations are mathematical shapes — circles, lines, text — that the PDF renderer reproduces at full vector quality at any print size, with no blurring or pixelation.

Annotations are data. The saved payload is a structured JSON record (schema: "uhuu.annotation.v1"), not an image blob. This means annotations can be read, transformed, re-rendered, or exported as a standalone SVG overlay by the template — for instance to composite the base photo and the annotation layer separately during PDF generation.

Annotation Types

The editor provides three annotation tools:

Marker

A pin shape placed at a point on the image. Useful for highlighting specific locations or features.

  • Modes: numbered (auto-increments), fill, outline
  • Shapes: circle or rectangle
  • Sizes: sm, md, lg

Numbered markers are the most common choice for legend-style annotations (e.g. "1 = Main entrance, 2 = Parking").

Label

A floating text badge attached to a point.

  • Variants: pill, rounded, rectangle
  • Sizes: sm, md, lg
  • Modes: fill or outline

Use labels when you want inline text visible directly on the image without a separate legend.

Callout

A rich card connected to an anchor point by a line. The most expressive annotation type.

  • Modes:
    • minimal — compact, shows a single initial letter or icon
    • detailed — full card with title, description, optional image thumbnail, and stat rows
  • Connector: A line from the card to the anchor point on the image; can be enabled or disabled per callout.

Callouts work well for location maps where each pin needs a label and a short description, or for property photos where specific features are explained.

Parameters

The editDialog call for the annotation dialog accepts:

  • type: Set to 'annotation'.
  • path (string, required): Payload path where the annotation data will be stored.
  • image (string, required): URL of the base image to annotate. Use a reasonably sized version (e.g. 1200×1200) — not an original that may be tens of megabytes. This does not need to match the display URL exactly; it is only shown inside the annotation editor.
  • config.visualGallery (string[], optional): An array of SVG icon URLs shown as selectable icon tiles in the editor's visual picker. When provided, users can attach an icon from the gallery to a marker or callout. Omit if icons are not needed.
  • value (optional): The current annotation data from the payload. If omitted or empty, the editor starts with no annotations.

Saved Data Format

On save, the dialog writes the following structure to path:

json
{
  "schema": "uhuu.annotation.v1",
  "annotations": [
    {
      "id": "abc123",
      "type": "marker",
      "x": 42.5,
      "y": 31.0,
      "mode": "numbered",
      "variant": "circle",
      "size": "md",
      "number": 1,
      "color": "#ffffff"
    },
    {
      "id": "def456",
      "type": "label",
      "x": 68.0,
      "y": 55.5,
      "text": "Main entrance",
      "variant": "pill",
      "size": "sm",
      "mode": "fill",
      "color": "#1e293b"
    }
  ],
  "annotationSvg": "<svg>…</svg>"
}

x and y are percentages (0–100) relative to the image dimensions. annotationSvg is a pre-rendered SVG string of the full annotation layer — ready to use as an overlay image in the template without re-rendering.

Example

Opening the annotation dialog directly

js
$uhuu.editDialog({
  path: 'page.heroAnnotation',
  type: 'annotation',
  image: 'https://example.com/photos/hero-1200.jpg',
  config: {
    visualGallery: [
      'https://cdn.example.com/icons/hospital.svg',
      'https://cdn.example.com/icons/school.svg',
      'https://cdn.example.com/icons/bus-stop.svg',
    ]
  },
  value: payload.page?.heroAnnotation
});

With ImageBlock in a JSX template

When using ImageBlock from uhuu-components, pass the annotation config as the annotation prop. It coexists independently with the dialog prop (which opens the image picker):

jsx
import { ImageBlock } from 'uhuu-components';

<ImageBlock
  src={imageUrl}
  dialog={buildPageDialog(dataBinding, 'heroImage', { type: 'image' }, heroImage)}
  annotation={buildPageDialog(
    dataBinding,
    'heroImageAnnotation',
    {
      type: 'annotation',
      image: resolveImageSrc(heroImage),
      visualGallery: Object.values(mapIcons)
    },
    page.heroImageAnnotation
  )}
/>

The user sees two separate edit controls on the image block: one for changing the photo, one for editing the annotation overlay. Both store their data at independent payload paths.

Rendering Annotations in the Template

The annotationSvg field in the saved data is a pre-built SVG string you can overlay on the base image directly in the template:

jsx
{page.heroAnnotation?.annotationSvg && (
  <div className="relative">
    <img src={imageUrl} className="w-full h-full object-cover" />
    <div
      className="absolute inset-0"
      dangerouslySetInnerHTML={{ __html: page.heroAnnotation.annotationSvg }}
    />
  </div>
)}

For PDF output, the SVG overlay renders at full vector quality — pin shapes, text labels, and connector lines stay sharp at any print resolution.

Notes

  • The image URL inside the annotation dialog config is only used as the editor background. The base image displayed in the template comes from a separate field and must be managed independently.
  • annotationSvg is only present when at least one annotation has been saved. Always check for its existence before rendering.
  • Annotation positions are stored as percentages, so they remain correct if the display size of the image block changes between breakpoints or page sizes.
  • The visualGallery icons should be SVGs hosted on a publicly accessible URL, not local file paths.

Public developer documentation for Uhuu.