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.
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.