Controlling the Camera
The camera decides which part of your graph is on screen and at what scale and
angle. Everything camera-related lives on nodus.view. This guide is a set of
recipes: zooming, panning, rotating, fitting the graph, animating moves,
converting between screen and graph coordinates, hit-testing, and sizing.
For how the two coordinate spaces relate, see The Coordinate System. For the full method list, see API: View.
Zooming
// Set an absolute zoom level.nodus.view.setZoom(2);
// Relative zoom in / out (centred on the viewport).nodus.view.zoomIn();nodus.view.zoomOut();
// Read the current zoom.const z = nodus.view.getZoom();Panning
Move the camera by setting its centre, nudging it by a delta, or moving to a
target. getCenter() returns the current centre in graph coordinates.
// Centre the view on a specific graph point.nodus.view.setCenter({ x: 0, y: 0 });
// Nudge by a delta.nodus.view.move({ x: 50, y: 0 });
// Move to a target point or element.nodus.view.moveTo({ x: 120, y: 80 });
// Frame a specific bounding box.nodus.view.moveToBounds({ minX: 0, minY: 0, maxX: 200, maxY: 150 });Rotating
// Set an absolute angle (radians).nodus.view.setAngle(Math.PI / 6);
// Rotate by a delta.nodus.view.rotate(-Math.PI / 12);
// Read the current angle.const a = nodus.view.getAngle();Fitting the graph
locateGraph() zooms and pans so the entire graph fits the viewport. It returns
a promise — run it after a layout (or after adding nodes) to frame the final
positions.
await nodus.layouts.force({ duration: 0 });await nodus.view.locateGraph();To preview the framing for some data without loading it, use
locateRawGraph(graph).
Try it live — fit the whole graph, zoom, and focus a single node:
Animating camera moves
Most camera methods accept an options object that commonly carries
{ duration } (milliseconds) to animate the transition instead of jumping.
// Glide to a new centre over 600ms.nodus.view.setCenter({ x: 0, y: 0 }, { duration: 600 });
// Animate a zoom.nodus.view.setZoom(1.5, { duration: 400 });
// Animate the fit-to-graph.await nodus.view.locateGraph({ duration: 600 });You can wait for the renderer between frames with beforeNextFrame() /
afterNextFrame(), and check whether a transition is running with
animationInProgress().
Saving and restoring the full view
get() snapshots the complete camera state (zoom, centre, angle); set(view)
restores it. Handy for bookmarks or “reset to default” buttons.
// Remember where we are.const saved = nodus.view.get();
// ...user explores...
// Jump back, animated.nodus.view.set(saved, { duration: 500 });Converting coordinates
Graph coordinates are the data space your nodes live in; screen coordinates are pixels in the container. Convert both ways — for example to place a DOM tooltip next to a node, or to turn a click position into a graph point.
// Graph point -> screen pixels (e.g. to position an overlay).const screenPt = nodus.view.graphToScreenCoordinates({ x: 120, y: 80 });
// Screen pixels -> graph point (e.g. from a mouse event).const graphPt = nodus.view.screenToGraphCoordinates({ x: event.offsetX, y: event.offsetY });Try it live — set center and zoom, and convert between screen and world points:
Hit-testing and queries
Ask the view what’s under a point, or what falls inside a region.
// The element at a screen point (or null).const hit = nodus.view.getElementAt({ x: 200, y: 140 });
// Everything currently visible in the viewport.const visible = nodus.view.getElementsInView();
// Everything inside a rectangle. Pass coords as graph or screen space.const inBox = nodus.view.getElementsInside(0, 0, 200, 150, /* inGraphCoords */ true);
// The current visible bounds, and the graph's overall bounding box.const bounds = nodus.view.getBounds();const graphBox = nodus.view.getGraphBoundingBox();Locating a single element
Any node or edge can bring itself into view with element.locate(). It accepts
the same animation options as the camera methods.
nodus.getNode('ada').locate({ duration: 500 });Sizing and resizing
The view tracks the container’s pixel size. Read it with getSize(). When you
resize the container yourself (e.g. a panel collapses), set the new size or call
forceResize() to make the view re-measure.
// Current pixel size.const { width, height } = nodus.view.getSize();
// Set an explicit size (returns a promise).await nodus.view.setSize({ width: 800, height: 600 });
// Or re-measure the container after a CSS layout change.window.addEventListener('resize', () => nodus.view.forceResize());Fullscreen
nodus.view.setFullScreen(true);const isFull = nodus.view.isFullScreen();A snapshot of the canvas
For a raster image of the current view, use getImageData():
const imageData = nodus.view.getImageData();Next steps
- Drive the camera from user input in Handling Events.
- Use coordinate conversion with the tooltip in Interaction Tools.
- Arrange the graph first with Applying Layouts.