Pan & Zoom
Panning
The surface widget is an 'infinite pan' canvas that does not use scrollbars. To pan the canvas, the user drags using the left mouse button, or, on touch devices, by dragging a single touch.
Disabling Panning
Panning is normally enabled, but a surface can be initialized with panning disabled by setting enablePan
to false:
const surface = toolkit.render(someElement, {
enablePan:false
});
You can also disable a surface entirely via the setMode
method:
surface.setMode(Surface.DISABLED);
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 has the panFilter
parameter. This is either a string that is a CSS selector representing elements that should allow a pan to begin, or a function from which you should return true if you would like a pan to begin.
CSS Selector Filter
let surface = toolkit.render(someElement, {
panFilter:".someClassName"
});
Function filter
const surface = toolkit.render(someElement, {
panFilter:(eventTarget) => {
return someLogic(eventTarget);
}
});
Zooming
The default behaviour of the surface is to support zooming via the mouse wheel, or on touch devices, via pinch to zoom.
Specifying zoom range
The surface can be zoomed within a given range, whose default value is:
[0.05, 3]
meaning the surface can zoom between 5% and 300%. You can set this when you create a surface:
const surface = toolkit.render(someElement, {
zoomRange:[1, 2]
});
You can also change the zoom range at runtime, via the setZoomRange
method:
Wheel zoom
const surface = toolkit.render(someElement, {
wheel{
zoom:false
}
});
zoom defaults to true. Whether or not zooming with the mouse wheel is enabled.
Filtering wheel events
const surface = toolkit.render(someElement, {
wheel:{
filter:".someElementClass"
}
});
filter is an optional CSS selector representing elements that should not respond to wheel zoom. Defaults to empty.
Wheel zoom meta key
const surface = toolkit.render(someElement, {
wheel:{
useMetaKey:true
}
});
wheelZoomMetaKey defaults to false. If true, the wheel zoom only fires when Ctrl (or CMD on Mac) is pressed and the wheel is rotated.
Wheel direction
const surface = toolkit.render(someElement, {
wheel:{
reverse:true
}
});
reverse Defaults to false. If true, the zoom direction is reversed: wheel up zooms out, and wheel down zooms in.
Zoom Methods
There are a few helper methods for zooming exposed on the surface.
zoomToFit(options)
Zooms the display so that all tracked elements fit inside the viewport (including invisible nodes). This method will also increase the zoom if necessary in order that the content fills the 90% of the shortest axis of the viewport.
The most basic call you can make is this:
surface.zoomToFit();
zoomToFit
supports a number of parameters:
- fill A decimal indicating how much of the viewport to fill with the zoomed content. Defaults to 0.9.
- padding Padding to leave around all elements. Default is 20 pixels.
- onComplete Optional function to call on operation complete (centering may be animated).
- onStep Optional function to call on operation step (centering may be animated).
- doNotAnimate By default, the centering content step does not use animation (this parameter is set to true). This is due to this method being used most often to initially setup a UI.
- doNotZoomIfVisible Defaults to false. If true, no action is taken if the content is currently all visible.
An example showing the surface animating the content until it fits 80% of the viewport and then popping up an alert:
surface.zoomToFit({
fill:0.8,
doNotAnimate:false,
onComplete:function() { alert("done!"); }
});
To zoom to show only visible nodes, see zoomToVisible.
zoomToFitIfNecessary(options)
Works like zoomToFit
but if all tracked elements are currently visible does not adjust the zoom.
surface.zoomToFitIfNecessary();
All of the parameters supported by zoomToFit
are supported by zoomToFitIfNecessary
.
zoomToBackground(options)
If a background was set, zooms the widget such that the entire background is visible.
surface.zoomToBackground({
onComplete:() => { alert("done!"); }
});
This method also supports onStep
and doNotAnimate
.
zoomToSelection(options)
Zoom to either the current selected set of nodes in the Toolkit (defaults to the current selection filling 90% of the shortest axis in the viewport):
surface.zoomToSelection();
or provide a selection of your own to which to zoom:
surface.zoomToSelection({
fill:0.8,
selection:some Toolkit Selection
});
To find our more about Selections, see here.
This method also supports an optional filter
function, which is used to create a Selection by running it through the Toolkit's filter
method. For instance, this is how you could create what the zoomToVisible
method (described below) does:
surface.zoomToSelection({
filter:(obj) => { return obj.objectType === "Node" && surface.isVisible(obj); }
});
zoomToVisible(options)
Zooms to display all the currently visible nodes. All animation options are supported by this method - it is a wrapper around zoomToSelection
in which we first create a selection representing all the visible nodes.
zoomToVisibleIfNecessary(options)
This method is to zoomToVisible
as zoomToFitIfNecessary
is to zoomToFit
- the content will be centered, but the zoom level will be changed only if all of the currently visible nodes are not visible in the viewport.
setZoom(value)
Sets the current zoom level. This must be a positive decimal number. If it is outside of the current zoom range, it will be clamped to the zoom range.
surface.setZoom(0.5);
Here we have set the zoom to 50%.
nudgeZoom(amount)
Nudges the current zoom level by some value (negative or positive).
// nudge the zoom by 5%
surface.nudgeZoom(0.05);
// nudge the zoom by -15%
surface.nudgeZoom(-0.15);
setZoomRange(range, doNotClamp)
Sets the current zoom range. By default, this method checks if the current zoom is within the new range, and if it is not then setZoom
is called, which will cause the zoom to be clamped to an allowed value in the new range. You can disable this by passing true
for doNotClamp
.
surface.setZoomRange(0.5, 2);
here we have set the zoom range to be 50% minimum, 200% maximum. If the current zoom was outside of this range, it was clamped to be within.
Let's set the zoom to 2, the top of our current range, and then adjust the zoom range without affecting the widget's zoom:
surface.setZoom(2);
surface.setZoomRange([0.5, 1], true);
Clamping
Pan Movement
By default, the surface will clamp movement when panning so that some content is always visible. This can be overridden:
const surface = toolkit.render(someElement, {
...
clamp:false,
...
});
Zoom Movement
It is also default behaviour to clamp the movement of the canvas when the user zooms such that some content is always visible. Without this, it's quite easy for a user to accidentally zoom in such a way that all of the content disappears (consider the case that the canvas is zoomed out a long way and the user then zooms in on some whitespace that is a long way from any content).
As with pan clamping, you can also switch off zoom clamping if you wish:
const surface = toolkit.render(someElement, {
...
clampZoom:false,
...
});
Background
Backgrounds are discussed in a separate page, but a brief mention should be made of the fact that you can also tell the surface to clamp movement such that part of the background is always visible:
const surface = toolkit.render(someElement, {
...
clampToBackground:true,
...
});