5.7 KiB
PREREQ-003: Document Canvas Overlay Pattern
Overview
Priority: HIGH
Estimate: 1-2 days
Status: Not started
Blocked by: PREREQ-001 (Webpack caching)
Can parallelize with: PREREQ-002
The Good News
CommentLayer already works as a React overlay on the canvas!
This proves the overlay pattern is viable. This task is about:
- Understanding how CommentLayer works
- Documenting the pattern
- Creating reusable infrastructure for other overlays
What CommentLayer Does
CommentLayer renders React components that:
- Float over the HTML5 Canvas
- Respond to pan/zoom (stay in correct position)
- Integrate with selection system
- Support user interaction (click, drag)
This is exactly what we need for:
- VIEW-005: Data Lineage (path highlighting + panel)
- VIEW-006: Impact Radar (dependency highlighting + panel)
- VIEW-007: Semantic Layers (node visibility filtering)
Investigation Tasks
1. Study CommentLayer Implementation
File: packages/noodl-editor/src/editor/src/views/nodegrapheditor/commentlayer.ts
Document:
- How it creates the overlay container
- How it subscribes to pan/zoom changes
- How it transforms coordinates between canvas space and screen space
- How it handles React rendering lifecycle
2. Identify Integration Points
Find where CommentLayer connects to:
- NodeGraphEditor (the main canvas class)
- Pan/zoom events
- Selection events
- Mouse events
3. Extract Reusable Patterns
Create shared utilities that any overlay can use:
- Coordinate transformation
- Pan/zoom subscription
- Overlay container management
Expected Findings
Coordinate Transformation
The canvas has its own coordinate system. Overlays need to convert between:
- Canvas coordinates - Position in the node graph space
- Screen coordinates - Position on the user's screen
// Expected pattern (to verify):
function canvasToScreen(point: Point, viewport: Viewport): Point {
return {
x: (point.x + viewport.pan.x) * viewport.scale,
y: (point.y + viewport.pan.y) * viewport.scale
};
}
function screenToCanvas(point: Point, viewport: Viewport): Point {
return {
x: point.x / viewport.scale - viewport.pan.x,
y: point.y / viewport.scale - viewport.pan.y
};
}
Pan/Zoom Subscription
The overlay needs to re-render when viewport changes:
// Expected pattern (to verify):
nodeGraphEditor.on('viewportChanged', ({ pan, scale }) => {
this.updateOverlayPositions(pan, scale);
});
React Rendering
The overlay renders React over the canvas:
// Expected pattern (to verify):
class CanvasOverlay {
private container: HTMLDivElement;
private root: Root;
constructor(parentElement: HTMLElement) {
this.container = document.createElement('div');
this.container.style.cssText = `
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none; // Allow clicks through to canvas
`;
parentElement.appendChild(this.container);
this.root = createRoot(this.container);
}
render(props: OverlayProps) {
this.root.render(<OverlayComponent {...props} />);
}
}
Deliverables
1. Documentation
Create CANVAS-OVERLAY-PATTERN.md documenting:
- How CommentLayer works
- The coordinate transformation system
- The event subscription pattern
- Common gotchas and solutions
2. Shared Infrastructure
Create reusable overlay utilities:
// packages/noodl-editor/src/editor/src/views/CanvasOverlays/
// CanvasOverlayBase.ts - Base class for overlays
export abstract class CanvasOverlayBase {
protected viewport: Viewport;
protected root: Root;
abstract render(): void;
protected canvasToScreen(point: Point): Point;
protected screenToCanvas(point: Point): Point;
protected subscribeToViewport(callback: ViewportCallback): Unsubscribe;
}
// OverlayContainer.tsx - React component for overlay positioning
export function OverlayContainer({
children,
viewport
}: OverlayContainerProps): JSX.Element;
// useViewportTransform.ts - Hook for overlays
export function useViewportTransform(): {
pan: Point;
scale: number;
canvasToScreen: (point: Point) => Point;
screenToCanvas: (point: Point) => Point;
};
3. Example Implementation
Create a minimal test overlay that:
- Renders a simple React component over the canvas
- Updates position correctly on pan/zoom
- Handles click events properly
Implementation Steps
Phase 1: Study (4-6 hours)
- Read through
commentlayer.tsthoroughly - Add comments explaining each section
- Trace the data flow from canvas events to React render
- Identify all integration points
Phase 2: Document (2-4 hours)
- Write
CANVAS-OVERLAY-PATTERN.md - Include code examples
- Document gotchas discovered
Phase 3: Extract Utilities (4-6 hours)
- Create
CanvasOverlays/directory - Extract coordinate transformation utilities
- Create base class or hooks for overlays
- Write tests for utilities
Phase 4: Verify (2 hours)
- Create minimal test overlay
- Verify it works with pan/zoom
- Verify click handling works
Files to Study
packages/noodl-editor/src/editor/src/views/nodegrapheditor/
├── commentlayer.ts # Main overlay implementation
├── CommentLayer/
│ ├── CommentLayerView.tsx # React component
│ ├── CommentForeground.tsx
│ └── CommentBackground.tsx
└── nodegrapheditor.ts # Integration point
Success Criteria
- CommentLayer pattern fully documented
- Coordinate transformation utilities created and tested
- Base overlay class/hooks created
- Test overlay works correctly with pan/zoom
- Documentation sufficient for implementing VIEW-005, 006, 007