Bounds
NiiVue supports rendering multiple independent instances into a single shared <canvas>
by constraining each instance to a normalized bounds rectangle. Bounds are specified in fractions of the canvas, with [0,0]
as the bottom-left corner and [1,1]
as the top-right corner.
Setting bounds
Bounds are defined as a 4-element array:
nv.setBounds([x1, y1, x2, y2])
x1, y1
= lower-left corner (fractions of width/height)x2, y2
= upper-right corner (fractions of width/height)
For example:
// Bottom-left quarter of the canvas
nv.setBounds([0.0, 0.0, 0.5, 0.5])
// Top-right quarter
nv.setBounds([0.5, 0.5, 1.0, 1.0])
// Full canvas
nv.setBounds([0.0, 0.0, 1.0, 1.0])
Configuring at initialization
You can also set bounds directly when constructing a Niivue
instance:
const nv1 = new Niivue({
bounds: [[0.0, 0.0], [0.5, 0.5]], // bottom-left quarter
})
const nv2 = new Niivue({
bounds: [[0.5, 0.5], [1.0, 1.0]], // top-right quarter
})
Note: the object form [[x1, y1], [x2, y2]]
is supported for options, but when calling setBounds
you must pass [x1, y1, x2, y2]
.
Interactive demo
Below you can try adjusting the bounds of two NiiVue instances that share a single canvas. Use the dropdowns to reposition each instance.
Bounds border
Each instance can optionally show a border rectangle to visualize its bounds. The border is white by default and can be configured via:
nv.opts.showBoundsBorder = true
nv.opts.boundsBorderColor = [1, 0, 0, 1] // RGBA red
nv.opts.boundsBorderThickness = 2 // in pixels
This is useful for debugging or when overlaying multiple synchronized views in a single canvas.
Bounds and layouts
When customLayout
or multiplanar layouts are active, the layout tiles are constrained inside the instance’s bounds region. That means:
- Layout positions are relative within the instance’s bounds, not the full canvas.
- You can safely combine multiple instances with bounds and each one will handle its own multiplanar/custom layout internally.
Example: Two instances
// First instance: bottom-left quarter
const nv1 = new Niivue({ bounds: [[0.0, 0.0], [0.5, 0.5]] })
await nv1.attachTo('gl1')
await nv1.loadVolumes([{ url: './images/mni152.nii.gz', colormap: 'gray' }])
nv1.setSliceType(SLICE_TYPE.MULTIPLANAR)
// Second instance: top-right quarter
const nv2 = new Niivue({ bounds: [[0.5, 0.5], [1.0, 1.0]] })
await nv2.attachTo('gl1')
await nv2.loadVolumes([{ url: './images/mni152.nii.gz', colormap: 'hot' }])
nv2.setSliceType(SLICE_TYPE.MULTIPLANAR)
With bounds, you can partition a single WebGL canvas into multiple independent NiiVue viewports, each synchronized or controlled individually.