# DiagramRenderBackend

Import it from `@grafloria/renderer`.

One diagram, two backends, one VNode tree.

The host owns a container element; the backend owns whatever goes inside it
(`<svg>` or `<canvas>`) and swaps that out on `setMode`.

```ts
class DiagramRenderBackend
```

**Methods**

- `constructor(engine: DiagramEngine, container: Element, options: RenderBackendOptions = {})`
- `getMode(): BackendMode`
- `getRenderer(): SVGRenderer | CanvasRenderer` — The renderer currently driving the picture.
- `getProducer(): SVGRenderer` — The shared VNode producer (identical object in both modes).
- `setMode(mode: BackendMode, options: { force?: boolean } = {}): boolean` — Switch backend on a LIVE diagram. The producer, the engine, the theme and
the camera all survive; only the paint target changes. The next `render()`
repaints from scratch into the new target.

A switch TO canvas is now REFUSED when it would take something away
(an AT surface is live, focus is inside the diagram, or the scene has HTML nodes
canvas cannot paint). Returns whether the switch happened. Going back to SVG is never
refused — that direction can only ever restore what canvas lacks.

`setMode('canvas', { force: true })` overrides the guard. A host that has taken the
decision knowingly can still have it; what it cannot do is take it by accident.
- `render(viewport: Rectangle, zoom: number): VNode`
- `canvasSafety(): CanvasSafety` — What canvas mode would cost this diagram right now. `safe` iff it would cost nothing.
- `setAccessibilityActive(active: boolean): void` — Tell the backend an assistive-technology surface is live for this diagram (an outline
view, a live region, keyboard navigation).

While it is, `setMode('canvas')` is refused — and if we are ALREADY on canvas, this
immediately returns the diagram to SVG rather than waiting for the next frame. A
screen reader that arrives mid-session gets its semantics back at once.
- `hitTest(worldX: number, worldY: number): CanvasPick | null`
- `setTheme(theme: Theme): void`
- `dispose(): void`
