Skip to main content

Navigating the canvas

The surface widget offers a number of methods you can use to assist your users in navigating their way around the canvas. You'll need to access the surface to use these methods programmatically - expand the section below for details.

How to access the surface

From your app component​

To access the surface from inside a component that uses a SurfaceComponent, declare a ref and then use the getSurface() method on it:



import { SurfaceComponent, SurfaceComponentRef } from "@visuallyjs/browser-ui-react"
import "@visuallyjs/browser-ui/css/visuallyjs.css"
import {useRef} from "react"

export default function App() {

const surfaceRef = useRef<SurfaceComponentRef>(null)

const data = { ... }

const renderOptions = {...}

function doSomething() {
const surface = surfaceRef.current.getSurface()
// now you can invoke methods on "surface"
}

return <div style={{width:"100%", height:"500px"}}>
<SurfaceComponent data={data} renderOptions={renderOptions} ref={surfaceRef}/>
</div>
}

From a different component​

If you have a component somewhere in your tree from which you wish to interact with the surface, you can use the useSurface() hook in conjunction with a SurfaceProvider to access the surface. Your app component should look something like this:

import { useRef } from "react"
import { SurfaceComponent } from "@visuallyjs/browser-ui-react"

export default function MyComponent() {

return <SurfaceProvider>
<SurfaceComponent ref={surfaceRef}/>
<MyOtherComponent/>
</SurfaceProvider>
}

Then the implementation of MyOtherComponent can use the useSurface hook:

import { useRef } from "react"
import { SurfaceComponent, useSurface } from "@visuallyjs/browser-ui-react"

export default function MyOtherComponent() {

const surfaceRef = useRef<Surface>(null)
useSurface().then(s => surfaceRef.current = s)

function centerContent() {
surfaceRef.current.centerContent()
}

return <div><button onClick={() => centerContent()}>Center content!</button></div>
}
info

Note the difference between the ref type in the above example from the first example: when you use the useSurface hook the value passed into the promise is a Surface, not a SurfaceComponentRef.

Positioning​

centerOn​

Takes a single node/group, or an array of nodes/groups, and positions the surface canvas such that the given vertex/vertices is/are at the center in both axes. It does NOT change the zoom.
Signature
centerOn(element:string | Element | Vertex | Array<string | Element | Vertex>, doNotAnimate:boolean)
Parameters
elementstring | Element | Vertex | Array<string | Element | Vertex>The element(s) to center. Can be a DOM element, vertex id, or a Node/Group, or an array of these.
doNotAnimateboolean
Return value
void

centerOnHorizontally​

Takes a node/group as argument and positions the surface canvas such that the given node is at the center in the horizontal axis.
Signature
centerOnHorizontally(element:string | Element | Vertex)
Parameters
elementstring | Element | VertexThe element to center. Can be a DOM element, vertex id, or a Node/Group
Return value
void

centerOnVertically​

Takes a node/group as argument and positions the surface canvas such that the given node is at the center in the vertical axis.
Signature
centerOnVertically(element:string | Element | Vertex)
Parameters
elementstring | Element | VertexThe element to center. Can be a DOM element, vertex id, or a Node/Group
Return value
void

centerContent​

Centers the tracked content inside the viewport, but does not adjust the current zoom (so the content may still extend past the viewport bounds)
Signature
centerContent(options:CenterContentOptions)
Parameters
optionsCenterContentOptionsMethod parameters.
Return value
void

pan​

Pans the canvas by a given amount in X and Y.
Signature
pan(dx:number, dy:number, doNotAnimate:boolean)
Parameters
dxnumberAmount to pan in X direction
dynumberAmount to pan in Y direction
doNotAnimatebooleanBy default this operation uses animation.
Return value
void

setPan​

Sets the position of the panned content's origin.
Signature
setPan(left:number, top:number, animate:boolean, onComplete:(p:PointXY) => any)
Parameters
leftnumberPosition in pixels of the left edge of the panned content.
topnumberPosition in pixels of the top edge of the panned content.
animatebooleanWhether or not to animate the pan. Defaults to false.
onComplete(p:PointXY) => anyIf animate is set to true, an optional callback for the end of the pan
Return value
void

alignContent​

Pan the canvas to align the content in one or both axes.
Signature
alignContent(options:AlignContentOptions)
Parameters
optionsAlignContentOptions
Return value
void

alignContentLeft​

Pan the canvas to align the content such that the left edge of the leftmost element is at the left of the viewport.
Signature
alignContentLeft(options:AlignContentToFaceOptions)
Parameters
optionsAlignContentToFaceOptions
Return value
void

alignContentRight​

Pan the canvas to align the content such that the right edge of the rightmost element is at the right of the viewport.
Signature
alignContentRight(options:AlignContentToFaceOptions)
Parameters
optionsAlignContentToFaceOptions
Return value
void

alignContentTop​

Pan the canvas to align the content such that the top edge of the topmost element is at the top of the viewport.
Signature
alignContentTop(options:AlignContentToFaceOptions)
Parameters
optionsAlignContentToFaceOptions
Return value
void

alignContentBottom​

Pan the canvas to align the content such that the bottom edge of the bottom element is at the bottom of the viewport.
Signature
alignContentBottom(options:AlignContentToFaceOptions)
Parameters
optionsAlignContentToFaceOptions
Return value
void

Zooming​

You can zoom the canvas in a number of different ways:

zoomToFit​

Zooms the display so that all the tracked elements fit inside the viewport. This method will also, by default, increase the zoom if necessary - meaning the default behaviour is to adjust the zoom so that the content fills the viewport. You can suppress zoom increase by setting doNotZoomIfVisible:true on the parameters to this method.
Signature
zoomToFit(params:ZoomToFitOptions)
Parameters
paramsZoomToFitOptions
Return value
void

zoomToFitIfNecessary​

Zooms the display so that all the tracked elements fit inside the viewport, but does not make any adjustments to zoom if all the elements are currently visible (it still does center the content though).
Signature
zoomToFitIfNecessary(params:ZoomToFitIfNecessaryOptions)
Parameters
paramsZoomToFitIfNecessaryOptions
Return value
void

zoomToElements​

Zooms the viewport so that all of the given elements are visible.
Signature
zoomToElements(zParams:ZoomToElementsOptions<BrowserElement>)
Parameters
zParamsZoomToElementsOptions<BrowserElement>
Return value
void

zoomToExtents​

Zooms the display to fit the given extents, which may be a single box or an array of boxes; in the latter case VisuallyJs will calculate a minimum bounding box for all the boxes provided.
Signature
zoomToExtents(zParams:ZoomToExtentsOptions)
Parameters
zParamsZoomToExtentsOptionsOptions for the zoom
Return value
void

zoomToBackground​

Zooms the display so that the background (if one is set) fits inside the viewport.
Signature
zoomToBackground(params:{
  doNotAnimate:boolean,
  onComplete:(p:PointXY) => any
}
)
Parameters
params{
  doNotAnimate:boolean,
  onComplete:(p:PointXY) => any
}
Return value
void

zoomToDecorator​

Zooms the display to fit the canvas and content plus any elements added by the given decorator.
Signature
zoomToDecorator(zParams:{
  decorator:string | Decorator,
  doNotAnimate:boolean,
  doNotFirePanEvent:boolean,
  doNotZoomIfVisible:boolean,
  fill:number,
  onComplete:(p:PointXY) => any,
  onStep:() => any
}
)
Parameters
zParams{
  decorator:string | Decorator,
  doNotAnimate:boolean,
  doNotFirePanEvent:boolean,
  doNotZoomIfVisible:boolean,
  fill:number,
  onComplete:(p:PointXY) => any,
  onStep:() => any
}
Return value
void

Finding elements​

Several methods are available to assist you to find elements in the canvas.

findIntersectingVertices​

Finds all of the vertices that intersect the rectangle described by origin and dimensions.
Signature
findIntersectingVertices(options:IntersectingVerticesOptions)
Parameters
optionsIntersectingVerticesOptionsOptions for the find operation.

Mapping coordinates​

Every now and then you'll likely want to map between the surface's coordinate system and the page coordinate system. The surface offers a few methods to assist with this.

isInViewport​

Returns whether or not the given point (relative to page origin) is within the viewport for the widget.
Signature
isInViewport(x:number, y:number)
Parameters
xnumberX location of point to test
ynumberY location of point to test
Return value
boolean

fromPageLocation​

Maps the given page location to a value relative to the canvas origin, allowing for zoom and pan of the canvas.
This takes into account the offset of the canvas in the page so that what you get back is the mapped position
relative to the target element's [left,top] corner
Signature
fromPageLocation(left:number, top:number, roundValues:boolean)
Parameters
leftnumberX location
topnumberY location
roundValuesbooleanIf true, the location is returned as integers for x/y.
Return value
PointXY

toPageLocation​

Maps the given canvas location to a page location, allowing for zoom and pan of the canvas. Note that page in this method takes scroll into account. If you wish to map to just the visible section of the browser, use toWindowLocation.
Signature
toPageLocation(left:number, top:number)
Parameters
leftnumberX location
topnumberY location
Return value
PointXY

fromWindowLocation​

Maps the given window location to a value relative to the canvas origin. The window means the browser's visible
window, and is not the same as the page, because of scroll.
Signature
fromWindowLocation(left:number, top:number, roundValues:boolean)
Parameters
leftnumber
topnumber
roundValuesboolean
Return value
PointXY