Skip to content

Core Concepts

Understanding these core concepts will help you work effectively with Annota.

An annotation is the fundamental unit in Annota. Each annotation contains:

interface Annotation {
id: string; // Unique identifier
shape: Shape; // Geometry (point, rectangle, polygon)
properties?: object; // Custom metadata
style?: AnnotationStyle; // Visual appearance
layerId?: string; // Layer assignment
}

Annota supports three primary shape types:

Point

Single coordinate for cell counting, nuclei detection, or markers.

{ type: "point", geometry: { x: 100, y: 200 } }

Rectangle

Axis-aligned bounding box for ROI selection.

{ type: "rectangle", geometry: { x: 0, y: 0, width: 100, height: 50 } }

Polygon

Arbitrary polygon for tumor boundaries, segmentation.

{ type: "polygon", geometry: { points: [{x: 0, y: 0}, ...] } }

All coordinates are in image space (pixels), not viewport space. This means:

  • Annotations stay fixed relative to the image
  • Zoom and pan don’t affect coordinate values
  • Easy to save/restore and share between sessions

Layers organize annotations into logical groups with independent controls:

interface Layer {
id: string;
name: string;
visible: boolean; // Show/hide all annotations
opacity: number; // 0-1 transparency
locked: boolean; // Prevent editing
style?: AnnotationStyle; // Default style for layer
}
  • Organization: Group annotations by type (tumors, cells, markers)
  • Visibility: Toggle layer visibility without deleting annotations
  • Styling: Apply consistent styles across all annotations in a layer
  • Locking: Protect annotations from accidental edits

Every annotation belongs to a layer. If no layer is specified, annotations go to the default layer.

Tools define how users interact with the viewer to create or modify annotations:

ToolCreatesInteraction
PointToolPoint annotationsSingle click
RectangleToolRectangle annotationsClick and drag
PolygonToolPolygon annotationsClick vertices, double-click to finish
PushToolN/A (edits polygons)Click and drag to push/pull vertices
ContourToolPolygon annotationsClick to auto-detect contours
SAMToolPolygon annotationsClick for AI segmentation
import { useTool, PolygonTool } from "annota";
function MyComponent({ viewer }) {
const polygonTool = new PolygonTool();
useTool({
viewer,
handler: polygonTool,
enabled: true, // Toggle to activate/deactivate
});
return null;
}

Selection represents the currently selected annotations. Selected annotations:

  • Display selection handles for resizing/moving
  • Can be deleted with the Delete key
  • Emit selectionChanged events
  • Single: Click an annotation to select it (clears previous selection)
  • Add: Ctrl/Cmd + Click to add to selection
  • Toggle: Shift + Click to toggle selection state
import { useSelection } from "annota";
function SelectionInfo() {
const selection = useSelection();
return <div>Selected: {selection.length} annotations</div>;
}

Annota uses an event-driven architecture for loose coupling:

annotator.on("createAnnotation", (annotation) => {
console.log("Created:", annotation);
});
annotator.on("updateAnnotation", (annotation) => {
console.log("Updated:", annotation);
});
annotator.on("deleteAnnotation", (annotation) => {
console.log("Deleted:", annotation);
});
annotator.on("selectionChanged", ({ selected, added, removed }) => {
console.log("Selection changed");
});
EventWhen FiredData
createAnnotationNew annotation createdAnnotation
updateAnnotationAnnotation modifiedAnnotation
deleteAnnotationAnnotation deletedAnnotation
selectionChangedSelection changes{ selected, added, removed }
hoverChangedHover state changesAnnotation | null
toolChangedActive tool changesTool | null

Every annotation can have custom visual styles:

interface AnnotationStyle {
fill?: string; // Fill color (CSS color)
fillOpacity?: number; // Fill transparency (0-1)
stroke?: string; // Stroke color
strokeWidth?: number; // Stroke width in pixels
strokeOpacity?: number; // Stroke transparency
}

Styles are applied in this order (later overrides earlier):

  1. Default styles — Built-in defaults
  2. Layer styles — Applied to all annotations in layer
  3. Annotation styles — Per-annotation overrides
  4. Selection styles — Applied to selected annotations
  5. Hover styles — Applied on mouse hover

Annota uses a sophisticated rendering pipeline for performance:

Annotations → Spatial Index → Viewport Culling → LOD → Caching → PixiJS → WebGL
  1. Spatial Index: R-tree for fast spatial queries
  2. Viewport Culling: Only render visible annotations
  3. Level of Detail: Simplify rendering when zoomed out
  4. Caching: Reuse graphics when nothing changed
  5. PixiJS: Hardware-accelerated WebGL rendering

Now that you understand the core concepts: