Legacy

A Fabric.js-based CAD viewer, published on npm.

Legacy CAD viewer placeholder showing a structural plan: column grid, rebar regions in orange, direction arrows, dimension annotations.
This is Legacy, running on this page. Pan with middle mouse, zoom with scroll. The viewer above is the same one used inside MyBlitz to mark up structural drawings, rendered here against a representative anonymized drawing.

Legacy is the Fabric.js-based CAD viewer Blitz built to render structural drawings in the browser. It covers three tiers — display only, region awareness, full editing — and is published as @karlantoun/legacy on npm. Internally, it’s the drawing surface behind region annotation in the E-Detailer workflow. Externally, anyone can use it as a standalone viewer.

StatusProduction. Used internally and externally.
Package@karlantoun/legacy
Version0.2.8
StackFabric.js · TypeScript
Three canvas tiers

Each tier extends the one above it. Pick the smallest tier that does what you need.

The API in two lines

The full surface is documented in the package. For context, this is what consuming Legacy looks like in practice:

import { LegacyComponent } from "@karlantoun/legacy";

<LegacyComponent
  options={{ canvasType: "region" }}
  onReady={() => ref.current?.displayBackground(entities)}
  requestDiameter={(region, done) => showDiameterModal(done)}
  onRegionSelected={(region) => setSelected(region)}
/>

The component is the only entry point. Every interaction — boundary drawing, direction selection, modifying regions — is exposed through ref methods or callbacks. No second prop tree, no internal state to manage from the outside.

Coordinate-system aware

CAD drawings live in AutoCAD-space, where Y goes up. Browser canvases live in Fabric.js-space, where Y goes down. Every coordinate that crosses the boundary has to be translated.

Legacy handles this. Inputs and outputs are always in CAD-space; internal rendering negates Y. You pass the coordinates that came from the structural model. You get back the coordinates that match the structural model. The browser part stays out of the way.

What makes it fast

CAD drawings are dense. A typical structural model has thousands of entities. Legacy is built to render and respond at that scale.

Level of detail (LOD)
At low zoom, complex polylines simplify; at high zoom, full geometry returns.
Spatial indexing
A grid-based index for entity lookup. Click handlers and snap searches check nearby cells, not every entity on the canvas.
Viewport culling
Entities outside the visible area aren't rendered at all.
Render batching
Repeated render calls coalesce into single frames.
Offscreen buffering
The canvas keeps an offscreen buffer for smooth zoom and pan without redraw flicker.
Snap throttle
The snap-point lookup is throttled to ~60fps with a 5-pixel motion threshold. Mouse moves below the threshold don't trigger recomputation.
Recent work — v0.2.8

The last release fixed a class of rendering bugs that came down to one root cause: stroke widths were being set in world-space coordinates, which became sub-pixel at typical CAD zoom levels. We added a screen-space stroke helper that divides by zoom, plus a render-with-stroke-update pass after every region operation. The result is immediate visual updates and consistent stroke thickness regardless of zoom.

This kind of work is the reason Legacy exists as its own library. CAD-grade rendering inside a browser canvas has its own constraints. We hit them, we name them, we fix them, we ship.

Where it's going

Legacy is in active development. Planned: better region-sync semantics for layer visibility, an alternative renderer for drawings at extreme density, and a tighter API around dimension annotations. The library is published; the roadmap is reactive to internal needs first, external feedback second.