Skip to main content

Panning and zooming

VisuallyJs has the smoothest pan/zoom for miles around, and exposes a number of hooks for you to inject your own behaviour.

By default, the UI is setup to support an infinite canvas. This means the canvas element is positioned absolute, we set overflow:hidden on the container element (which disables the browser's scrolling mechanism), and the transform origin for the canvas is set to wherever the user last used the mouse or performed a pinch to zoom.

Panning​

In the default configuration, panning is performed by dragging the canvas with the mouse, or via touch, and more often than not you won't need to provide any pan options at all. If you want to, though, you can configure pan options via the pan property:

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

export default function MyComponent() {

const renderOptions = {
pan: {
axis: "x",
useMetaKey: true
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}
Auto pan

The default behaviour of the UI is to automatically pan the canvas whenever a vertex is dragged out of the viewport. We're mentioning it here as it is related to pan, but this is controlled in the vertex drag options.

For more information see this page.

Filtering Panning​

It's a fairly common use case that there be some set of elements in your canvas on which a drag should not cause a pan to occur. To handle this, the surface's pan options has the filter parameter. This is a function from which you should return true if you would like a pan to begin. You must return boolean true from this function in order for panning to be enabled.

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

export default function MyComponent() {

const renderOptions = {
pan: {
filter: (eventTarget:BrowserElement) => {
return someLogic(eventTarget);
}
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Pan Axis​

The surface will pan in both the horizontal and vertical axes by default, as you might expect! But you can instruct the surface to pan only in one direction, should you wish to, via the axis property:

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

export default function MyComponent() {

const renderOptions = {
pan: {
axis: "x"
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Valid values are x, y and both (which is the default).

Panning with wheel​

If you want to use the wheel for panning rather than zooming, you can:

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

export default function MyComponent() {

const renderOptions = {
pan: {
wheel: true
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Pan Options​

PanOptions
Options to control how a user pans the canvas.
NameTypeDescription
axis?PanAxisOptional axes in which to constrain pan - 'x', 'y' or 'both'. Defaults to 'both'.
enabled?booleanDefaults to true, meaning panning is enabled.
filter?(el:Element) => booleanOptional function which is called at the start of panning and can return false to reject pan starting.
useMetaKey?booleanOptional, defaults to false. When true, the user must hold down the meta key (ctrl on windows) in order to pan.
wheel?booleanDefaults to false, meaning panning works via canvas drag. If you set this to true, the mousewheel (or move events on a touchpad) will pan the canvas. This will also override any zoom wheel flag.

Zooming​

The canvas supports zooming both programmatically and via the mouse wheel (or pinch, on touch devices or a trackpad). A Surface has an associated zoom range, which is the minimum and maximum zoom that can be applied. When using the mouse wheel or pinch, these limits are applied automatically. If you attempt to set a zoom value outside of the zoom range programmatically (via setZoom), the zoom value will be clamped to the current range.

Zooming is configured via the zoom property.

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

export default function MyComponent() {

const renderOptions = {
zoom: {
range: [
0.1,
5
],
step: 0.1
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Zoom options​

ZoomOptions
Options to control how a user manages zoom on the canvas.
NameTypeDescription
fixedTransformOrigin?PointXYOptional fixed transform origin for the canvas. Defaults to null.When this is supplied the zoom function does not change the transform origin You can still zoom and pan but the zoom/pan is applied relative to the top/left corner of the content.
initialValue?numberInitial zoom value. Defaults to 1.
range?ZoomRangeZoom range to support. The default is [0.05, 3]
step?numberWhen zooming by step, this defines the change in zoom for each step. Defaults to 0.25.
wheel?booleanWhen true - which is the default - the wheel will be used for zoom.

Wheel​

You configure whether the wheel manages pan or zoom inside the pan and zoom options. To configure the wheel's behaviour, use the wheel section of the render options.

Filtering wheel events​

If you want to control what parts of your UI respond to wheel events, you can do that in one of two ways.

CSS Filter​

cssFilter lets you provide a CSS3 selector identifying elements that should not fire wheel events.

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

export default function MyComponent() {

const renderOptions = {
wheel: {
cssFilter: ".someElementClass"
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Filter​

If you need more fine-grained control than just specifying a CSS selector, filter lets you provide a function which can determine whether or not a wheel event should fire.

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

export default function MyComponent() {

const renderOptions = {
wheel: {
filter: (e:MouseEvent) => { return someLogic(e) }
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Meta key​

By default, wheel events fire whenever the wheel is manipulated. If you wish, you can tell VisuallyJs only to respond to wheel events when the "meta" key (Ctrl on Windows/Linux, CMD on Mac) is pressed:

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

export default function MyComponent() {

const renderOptions = {
wheel: {
useMetaKey: true
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

Wheel direction​

By default, wheel up zooms in and wheel down zooms out. If you want to switch that, set reverse:true, and then wheel up zooms out, and wheel down zooms in.

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

export default function MyComponent() {

const renderOptions = {
wheel: {
reverse: true
}
}
return <SurfaceComponent renderOptions={renderOptions}/>
}

The full list of wheel options is:

WheelOptions
Options for how to respond to wheel events.
NameTypeDescription
cssFilter?stringOptional CSS 3 selector to check if the wheel should be enabled for the current event target.
filter?(e:MouseEvent) => booleanOptional function to call to check if wheel zooming should be enabled for the current event target.
reverse?booleanDefaults to false. If true, the zoom direction is reversed: wheel up zooms out, and wheel down zooms in.
sensitivity?numberHow sensitive the wheel should be.
shiftToChangeMode?booleanDefaults to true. When true, holding the SHIFT key while using the mouse wheel will toggle the wheel's mode:
if the wheel is currently set to pan, it will zoom. If it is currently set to zoom, it will pan.
useMetaKey?booleanIf true, the "meta" key (CMD on Mac, Ctrl on windows/linux) must be pressed in order for wheel zoom to operate. This can be useful if your UI fills the screen in one or more axes and your users would not be able to scroll past the Surface widget.

Note that if you set wheel: true in panOptions, the mouse wheel will pan the canvas, and this will take precedence over any zoom wheel configuration.