Timelinx

CompositorPreview

Real-time canvas compositor for previewing the final timeline output

The CompositorPreview renders the composed output of all visible tracks and clips at the current playhead position using a canvas element. It handles compositing, scaling, and real-time playback preview.

Live Example

Loading...

Usage

import { CompositorPreview, TimelineProvider, MediaAssetsProvider } from '@timelinx/ui';

function App() {
  return (
    <TimelineProvider engine={engine}>
      <MediaAssetsProvider>
        <CompositorPreview />
      </MediaAssetsProvider>
    </TimelineProvider>
  );
}

Props

Prop

Type

Context Requirement

CompositorPreview must be inside both a TimelineProvider and a MediaAssetsProvider. The timeline provider supplies clip and track state for compositing; the media assets provider supplies blob URLs and file data for rendering media frames.

HiDPI / Retina Support

The compositor automatically handles high-DPI (Retina) displays for sharp rendering:

  • The canvas backing store is sized to match the physical pixel density (canvas.width = cssWidth × devicePixelRatio)
  • The drawing context is scaled so all draw calls use logical 1920×1080 coordinates
  • DPR changes are detected via window.matchMedia('(resolution: ...)') and resize events
  • No code changes are needed - existing ctx.drawImage() and ctx.fillText() calls work at logical coordinates

Coordinate System

LayerDimensionsDescription
Logical1920 × 1080All draw calls, transforms, and clip positions use this space
CSSAspect-ratio fitDisplay size scaled to fit container (preserving 16:9)
PhysicalCSS × DPRCanvas backing store pixels for sharp output
┌─────────────────────────────────────────┐
│ Container (CSS pixels)                  │
│  ┌─────────────────────────────────┐    │
│  │ Canvas display (CSS)            │    │
│  │  ┌─────────────────────────┐    │    │
│  │  │ Logical 1920×1080       │    │    │
│  │  │ (all draw calls)        │    │    │
│  │  └─────────────────────────┘    │    │
│  └─────────────────────────────────┘    │
│  Backing store: CSS.width × DPR         │
│                CSS.height × DPR         │
└─────────────────────────────────────────┘

Performance Notes

  • The canvas buffer is only reallocated when display size or DPR actually changes
  • ctx.setTransform() is called before each render to reset and reapply the scale
  • The requestAnimationFrame loop is unaffected by DPR changes

On this page