Skip to main content

Dragging Nodes and Groups

By default, all node/group elements rendered by a surface will be made draggable, and the default behaviour of a draggable element is that it can be dragged to anywhere on the canvas. No special treatment is needed for touch devices - the surface abstracts that away.

Drag options

You can provide dragOptions when you render a surface. The most common reason for doing this is that you want to restrict the areas of your elements that your users can use to drag the element, for which you can provide a filter:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"dragOptions": {
"filter": ".someClass, .someClass *, .someOtherClass *"
}
});

This instructs JsPlumb to not allow dragging to start when the mousedown event occurs on an element that matches the given selector.

The full list of options is:

Interface SurfaceDragOptions

NameTypeDescription
addHelperClasses?booleanDefaults to true, meaning that when element dragging is occurring a class is added to the document body and also to the surface container.
autoPan?booleanDefaults to true, meaning the canvas will pan automatically to track elements that have been dragged out of the visible area.
autoPanDelta?numberWhen auto-panning, this is the number of pixels that the canvas repositions itself on each tick. Defaults to 5.
autoPanRepeat?numberWhen auto-panning, this is the speed (in milliseconds) at which the canvas repositions itself. Defaults to 15ms.
constrainFunction?Optional function to use to constrain element dragging.
filter?stringOptional CSS3 selector identifying parts of nodes/groups that should not cause a drag to start.

Preventing dragging

Dragging can be switched off in a few ways.

All elements

If you wish to switch off dragging for all elements you can set that in your render params:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"elementsDraggable": false
});

Per element

You can also control element dragging by writing a data-jtk-not-draggable attribute onto your node/group DOM element:

<div data-jtk-not-draggable="true">
This vertex is not draggable.
</div>

Programmatically

If you want to enable/disable dragging for some specific element on an ad-hoc basis you can use the setDraggable method:


surface.setDraggable("1", false) // mark node "1" as not draggable, using its id

setDraggable takes as argument either a vertex id, a vertex object, or a DOM element.

Dragging on a grid

You can impose a grid on the elements in a surface:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"grid": {
"size": {
"w": 50,
"h": 50
}
}
});

The full list of options supported by grid are defined in the SurfaceGridOptions interface:

Interface SurfaceGridOptions

NameTypeDescription
fitGroupsToGrid?booleanWhether or not to ensure calculated group sizes (from auto sized groups) are a multiple of the grid size in each axis. Defaults to false.
size?Gridwidth/height of the grid
snap?booleanWhether or not to snap elements to the grid when dragging. Defaults to false.

Drag events

The surface posts a few events to which you can subscribe in order to track the movement of vertices on your canvas. These events can be subscribed to either when creating the surface:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance,
EVENT_NODE_MOVE_END } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"dragOptions": {
"events": {
[EVENT_NODE_MOVE_END]: (params) => {
// a node was moved
}
}
}
});

or you can bind to them after creating the surface:


surface.bind(EVENT_NODE_MOVE_END, (params) => {
// a node was moved
})

Auto pan

JsPlumb will auto pan a canvas when a node/group is dragged outside of the visible bounds. This can be controlled with a few flags set inside the dragOptions on a render call (shown above):

  • autoPan Set to false if you wish to switch off auto panning.
  • autoPanDelta Defaults to 5 pixels. This is the amount by which the canvas will pan on each tick of the timer.
  • autoPanRepeat The time in milliseconds between each tick of the auto pan timer. Defaults to 10 milliseconds.

Switching off auto pan

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"dragOptions": {
"autoPan": false
}
});

Changing auto pan repeat time

Here we tell JsPlumb to pan the canvas every 5ms instead of the default:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"dragOptions": {
"autoPanRepeat": 5
}
});

Changing auto pan delta

Here we tell JsPlumb to move 15 pixels on each step instead of the default:

Vanilla JS
React
Angular
Vue
Svelte
import { newInstance } from "@jsplumbtoolkit/browser-ui"

const toolkit = newInstance()

const surface = toolkit.render(someElement, {
"dragOptions": {
"autoPanDelta": 15
}
});