VenueCanvas
A minimal venue heatmap — rounded-rectangle zones in a square 0–viewBoxSize space (default 0–100), status-colored, with a dotted seat texture, an amber STAGE marker derived from stage-kind zones, and N/S/E/W compass pins. Theme-token driven (works across amber-minimal light/dark and cinematic). Fully props-driven: focus and selection come from the consumer, no internal store.
Import
import { VenueCanvas, type VenueZoneShape } from "@roger-emerson/ploxum-venue";Peer deps: react, react-dom, motion, lucide-react; depends on @roger-emerson/ploxum-utils.
Usage
Give it a sized, overflow-hidden parent (it fills h-full w-full). Zones are rounded rectangles in viewBox units. Wrap in a zoom/pan host (e.g. MapViewport) if you want zoom.
const zones: VenueZoneShape[] = [
{ id: "stage", label: "Main Stage", kind: "stage", status: "ok", x: 38, y: 10, width: 24, height: 9 },
{ id: "floor", label: "GA Floor", kind: "generic", status: "warning", intensity: 0.8, x: 30, y: 30, width: 40, height: 28 },
{ id: "water", label: "Water", kind: "water", status: "critical", x: 20, y: 64, width: 8, height: 6 },
];
<div className="h-[480px] overflow-hidden">
<VenueCanvas
zones={zones}
focusedZoneId={focused}
onZoneSelect={setFocused}
badgeLabel="Live"
badgeAccent
/>
</div>;Props
VenueCanvas
| Prop | Type | Default | Description |
|---|---|---|---|
zones | VenueZoneShape[] | — | Zones rendered as rounded rectangles. |
viewBoxSize | number | 100 | Coordinate space of zone x/y/w/h (e2c2-compatible). |
focusedZoneId | string | null | null | Controlled focus — scales the focused zone up. |
onZoneSelect | (id: string | null) => void | — | Click handler; null when toggling focus off. |
showHeatmap | boolean | true | Dotted seat texture + amber radial glow (cinematic). |
showLabels | boolean | true | Render zone labels. |
showCompass | boolean | true | Render N/S/E/W compass pins. |
showStage | boolean | true | Give stage-kind zones the amber STAGE treatment. |
isolatedZoneId | string | null | null | Dim every zone except this id. |
badgeLabel | string | — | Top-left badge text (e.g. "Live" / "Last 15 min"). |
badgeAccent | boolean | false | Accent the badge value in amber. |
title | string | "Venue map" | Accessible <title> for the SVG. |
className | string | — | Merged onto the root <div>. |
VenueZoneShape
{ id, label?, kind?, status, x, y, width, height, rotation?, intensity? } — status is "ok" \| "warning" \| "critical" \| "offline"; kind is a VenueZoneKind (stage, vendor, water, security, parking, entry, vip, medical, restroom, art, gate, amenity, generic). intensity (0–1) drives fill opacity.
Design rules
- Status drives stroke color (success/warning/danger/muted);
stagezones render amber regardless of status. - It is the map, not the chrome — pan/zoom belongs to a host like
MapViewport. For meters-based layouts with rich footprints (polygons, roads, a track ring) and built-in semantic zoom, useVenueLayoutCanvas. - The amber radial glow is cinematic-only (
.cinematic-only); other themes drop the wash and keep the dotted texture.
