Architecture
Annota follows a clean, layered architecture that separates concerns for maintainability and performance.
Overview
Section titled “Overview”┌─────────────────────────────────────────────────────┐│ React Layer ││ Components, Hooks, Context │├─────────────────────────────────────────────────────┤│ Core Engine ││ Store, R-tree Index, Layer Manager, Events │├─────────────────────────────────────────────────────┤│ Rendering Engine ││ PixiJS WebGL, Viewport Culling, LOD, Caching │├─────────────────────────────────────────────────────┤│ OpenSeadragon Adapter ││ Viewport Integration, Coordinate Transform │└─────────────────────────────────────────────────────┘React Layer
Section titled “React Layer”The React layer provides the developer-facing API:
- AnnotaProvider: Context provider for annotation state
- AnnotaViewer: OpenSeadragon viewer wrapper
- Annotator: Annotation overlay component
- Hooks:
useAnnotator,useAnnotations,useTool, etc.
Core Engine
Section titled “Core Engine”The core engine manages annotation data and state:
Observable Store
Section titled “Observable Store”The store holds all annotation data and emits events on changes:
store.on("createAnnotation", handler);store.on("updateAnnotation", handler);store.on("deleteAnnotation", handler);R-tree Spatial Index
Section titled “R-tree Spatial Index”Sub-millisecond spatial queries using an R-tree:
// Find annotations at pointconst hits = spatialIndex.query({ x: 100, y: 200 });
// Find annotations in boundsconst inView = spatialIndex.queryBounds({ x: 0, y: 0, width: 1000, height: 1000 });Layer Manager
Section titled “Layer Manager”Manages annotation layers with visibility, opacity, and locking:
layerManager.createLayer({ id: "tumor", name: "Tumor Regions" });layerManager.updateLayer("tumor", { visible: false });Rendering Engine
Section titled “Rendering Engine”High-performance rendering with PixiJS:
Viewport Culling
Section titled “Viewport Culling”Only renders annotations visible in the current viewport:
// On viewport changeconst visible = spatialIndex.queryBounds(viewportBounds);renderer.render(visible);Level of Detail (LOD)
Section titled “Level of Detail (LOD)”Simplifies rendering when zoomed out:
- High zoom: Full detail with all vertices
- Medium zoom: Simplified polygons
- Low zoom: Bounding boxes or points
Smart Caching
Section titled “Smart Caching”Graphics are cached and only re-rendered when:
- Annotation data changes
- LOD level changes
- Significant scale change
OpenSeadragon Adapter
Section titled “OpenSeadragon Adapter”Bridges OpenSeadragon and the annotation system:
Coordinate Transform
Section titled “Coordinate Transform”Converts between image coordinates and viewport coordinates:
// Image → Viewportconst viewportPoint = adapter.imageToViewport(imagePoint);
// Viewport → Imageconst imagePoint = adapter.viewportToImage(viewportPoint);Event Handling
Section titled “Event Handling”Intercepts OpenSeadragon events for annotation tools:
adapter.on("pointerdown", handlePointerDown);adapter.on("pointermove", handlePointerMove);adapter.on("pointerup", handlePointerUp);Performance Optimizations
Section titled “Performance Optimizations”Key optimizations:
- R-tree indexing — O(log n) spatial queries
- Viewport culling — Only render what’s visible
- LOD rendering — Simplify when zoomed out
- Graphics caching — Reuse PixiJS graphics objects
- Batch rendering — Combine draw calls
- WebGL acceleration — Hardware-accelerated rendering