Engine, Panes, and Cameras

Create a framework-free surface, size panes, navigate cameras and release rendering resources.

Navigate linked panes

Pan either pane or zoom with the wheel. Both share a Y window; their X windows stay independent.

Preparing view…
Pane A · Camera APane B · Camera B
const unlink = linkAxes([cameraA, cameraB], 'y')
// Call unlink() when the linked group is removed.

Build several navigable plots on one canvas. Each pane owns its rectangle, camera, layers and overlays.

Mount a Plot

Call on the client with an empty container styled height: 480px; position: relative. Catch construction failure to show a WebGL2 fallback.

import { Camera, Controls, Engine, PointsLayer } from '@bs/outkrop-core'

export function mountPlot(host: HTMLElement) {
  const canvas = document.createElement('canvas')
  canvas.style.cssText = 'display:block;width:100%;height:100%'
  host.append(canvas)
  const engine = new Engine(canvas, {
    onResize: ({ width, height }) => {
      pane.setRect({ x: 0, y: 0, width, height })
    },
  })
  const pane = engine.addPane({
    id: 'plot',
    rect: { x: 0, y: 0, width: host.clientWidth, height: host.clientHeight },
    camera: new Camera({ x: [0, 4], y: [0, 10], flipY: false }),
  })
  pane.add(new PointsLayer({ x: [1, 2, 3], y: [2, 8, 5], size: 10 }))
  const controls = new Controls(engine, host)
  engine.requestRender()

  return () => {
    controls.dispose()
    engine.dispose({ loseContext: true })
    canvas.remove()
  }
}

Call the returned cleanup when removing the plot. The engine creates its 2D overlay canvas; controls need separate disposal.

Choose the Coordinate System

Setting Meaning
x, y World-coordinate ranges
flipY Default downward; false makes Y increase upward
Log axis Positive values only
lockX, lockY Disable navigation on an axis
Camera limits Bound movement and zoom span
pane.setRect Plot area in CSS pixels; reserve margins for axes

Share an Axis

flowchart TD
  accTitle: Compose views on a shared canvas
  accDescr: One engine owns a canvas with several panes. Each pane has a camera and its own layers and overlays.
  Engine["Engine and canvas"] --> A["Pane A"]
  Engine --> B["Pane B"]
  A --> CameraA["Camera A"]
  B --> CameraB["Camera B"]
  A --> DrawA["Layers and overlays"]
  B --> DrawB["Layers and overlays"]

linkAxes(cameras, 'y') synchronizes Y windows. Use the same units and call the returned unsubscribe function when removing the group. Lock X for well tracks whose value scale should remain fixed.

Draw, Pick and Export

Action API
Request a frame engine.requestRender(); camera and pane changes already do this
Wait for visible work await engine.settled()
Pick a point engine.pick(x, y) in canvas-relative CSS pixels
Export canvas + overlays await engine.toBlob()
Discard the canvas engine.dispose({ loseContext: true })

Rendering is on demand. Your app still cancels async work and disposes its own sources, workers and subscriptions. React apps can use OutkropSurface for canvas ownership.