Skip to main content

Backgrounds

The Surface widget supports the addition of backgrounds via the @jsplumbtoolkit/browser-ui-plugin-background package. Two different background types are supported - images, and generated grids.

Imports

You need to import the @jsplumbtoolkit/browser-ui-plugin-background package:


"dependencies":{
"@jsplumbtoolkit/browser-ui-plugin-background":"^5.10.8"
}

Note the version number here: this is the minimum version required that supports the scenarios discussed in this page.

Setup

As this is a plugin, you will provide its configuration in the plugins section of the render parameters for a Surface. On this page we show code snippets for "vanilla" Toolkit, ie without a library integration, but for users of a library integration just keep in mind that the render params here map to the render params you supply to the appropriate component when using a library integration.

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, SimpleBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:SimpleBackground.type,
url:"../img/351032562.jpg"
}
}
]

})

Image backgrounds

Images can be used as a background in one of two ways - either as an image that is retrieved in one piece and displayed, or as a set of tiles.

Simple backgrounds

These are backgrounds consisting of a single image, positioned at the Surface's origin. This type of background can be useful, for example, if you're building an app in which your users can markup drawings.

Single image example

In this example (using the code shown above) we load a simple background, ie. a static image:

Image background

Remember that we paste the image at the canvas origin, at its original size. So in this case the image has loaded but we cannot see all of it. It is possible to get a notification when the background image has loaded, though, so we can hook into that and have the image fully visible after load:

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, SimpleBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:SimpleBackground.type,
url:"../img/351032562.jpg",
onBackgroundReady: (bg, surface) => {
surface.zoomToBackground()
}
}
}
]

})
Image background

Tiled backgrounds

This type of background consists of a set of tiles, which the Surface element requests from you as the canvas is panned and zoomed. This type of background has various usages: if you have a large background image, for instance, you may wish to serve it in pieces as the Surface needs it. Alternatively, you may wish to change the background based on the current zoom (in the way that Google maps does). Another great use for this type of background is to provide a grid for your canvas.

Tiled image example

In this example we use a tiled background. Each of our tiles looks like this:

When the surface has rendered, only the required tiles will have been loaded. If you tap on one of the nodes, the display will pan left and up by 350 pixels in each axis, and you will (probably) see new tiles appearing as they get loaded (unless the network is too fast for the load to be evident):

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, TiledBackground, TilingStrategies } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:TiledBackground.type,
tiling:TilingStrategies.absolute,
url:"../img/tiles/0/{x}_{y}.jpg",
tileSize:{w:200, h:200 },
width:800,
height:800,
maxZoom:0
}
}
]

})
Image background

In this example we use TilingStrategies.absolute, in which the number of tiles in each axis is computed as the size of the image in that axis divided by the tile size in that axis. Thus, for each zoom level, there are the same number of tiles. You can also choose TilingStrategies.logarithmic, in which each layer is assumed to have a maximum of (2^level+1) tiles in each axis (for instance at level 0, tiles). This setup is how apps like Google maps arrange their tiles.

A tiled background is served as a series of layers, one for each zoom level supported. The number of zoom levels you intend to support is specified by the maxZoom option, which is a zero-indexed integer value. A value of 0 is the base value, covering the entire background. The background will determine which zoom level is appropriate based upon the current zoom of the surface.

There is no need to support any zoom level beyond 0; the background will retrieve tiles for the most appropriate level that is available to it, but serving up different tiles at different levels can allow you to implement things like serving more visual complexity the further a user zooms in.

Tiling strategies

You may have noticed that in the example above we declared tiling:TilingStrategies.absolute in the background options. The tiled background supports two different approaches to the way tiles are arranged:

  • TilingStrategies.absolute - Divides the entire image dimensions by the tile size. For instance, if you declare your background has a width and height of 800px, and your tiles are of width and height 50px, then - at zoom 0 - the background expects 16 tiles in each axis. At zoom 1, the expected value is doubled to 32, at zoom 2 it doubles again to 64, etc.

  • TilingStrategies.logarithmic - With this strategy, there are (2^level+1) tiles in each axis. For instance at zoom 0, there are 2 tiles. At zoom 1 there are 4. At zoom 2, 8. Etc. This strategy is how applications like Google maps operate.

URL pattern

The URL you supply for a tiled background should have a placeholder for each of zoom, x and y, as in the example above. Tiles are zero-indexed, so, for example, the top left tile at zoom level 0 would, in the previous example, generate this url:

tiles/0/tile_0_0.png

The surface's tiled background does not support the concept of a "continuous world", in which tiles with negative indices may be requested.


Generated grid backgrounds

Generated grid backgrounds place an SVG element into the background of a surface, repositioning and resizing it as needed as the bounds of your content changes. You can choose between a background using lines or dots. The default is for lines.

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, GeneratedGridBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...

grid:{
size:{w:50, h:50},
},
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:GeneratedGridBackground.type,
minWidth:1500,
minHeight:1500
}
}
]

})
Grid background

In this example we've setup a grid with a minimum width of 1500px (meaning a range from -750px to 750px) in both the X and Y axes, with 2 tick marks for each cell. We didn't specify the size of the grid in the background's options: the background will get this information from the surface, if possible. You can override the surface grid, however, should you wish to, or you may use the grid background on a surface that does not have a drag grid in effect.

Dotted backgrounds

The background in this example is rendered as lines, which is the default. Here's the same example with gridType:GridTypes.dotted:

Grid background, dotted

The full list of options for the generated grid background are:

Home > @jsplumbtoolkit/browser-ui-plugin-background > GeneratedGridBackgroundOptions

GeneratedGridBackgroundOptions interface

Options for the generated grid background. This background is still in beta as of 5.10.6.

Signature:

export interface GeneratedGridBackgroundOptions extends BackgroundOptions 

Extends: BackgroundOptions

Properties

PropertyModifiersTypeDescription
autoShrink?boolean(Optional) Defaults to true, and instructs the grid that if the grid has grown beyond any minimum value set in either axis, if the content bounds subsequently shrink in that axis below the minimum, the grid should shrink back to the minimum. If you set this to false the grid will never shrink back to its minimum values once they have been exceeded.
dotRadius?number(Optional) The radius for dots representing grid positions (when gridType id GridTypes.dotted). Defaults to 2.
grid?Grid(Optional) The grid to use. This is optional; if you do not supply one the background will attempt to read the grid definition from the Surface. If that is also not set then a default grid of 50x50 pixels will be used.
gridType?GridType(Optional) Type of grid - lines or dots. Defaults to lines.
maxHeight?number(Optional) The maximum height for the grid. The value you provided is divided by 2 and then the grid is guaranteed to never exceed the range of (-maxHeight / 2) - (maxHeight / 2). maxHeight takes precedence over minHeight.
maxWidth?number(Optional) The maximum width for the grid. The value you provided is divided by 2 and then the grid is guaranteed to never exceed the range of (-maxWidth / 2) - (maxWidth / 2). maxWidth takes precedence over minWidth.
minHeight?number(Optional) The minimum height for the grid. The value you provided is divided by 2 and then the grid is guaranteed to always at least span the range of (-minHeight / 2) - (minHeight / 2).
minWidth?number(Optional) The minimum width for the grid. The value you provided is divided by 2 and then the grid is guaranteed to always at least span the range of (-minWidth / 2) - (minWidth / 2).
showBorder?boolean(Optional) Whether or not to show a thick border around the entire background. Defaults to false.
showTickMarks?boolean(Optional) If true (which is the default), the grid will also draw tick marks between the grid lines.
tickDotRadius?number(Optional) The radius for dots representing grid tick marks (when gridType id GridTypes.dotted). Defaults to 1.
tickMarksPerCell?number(Optional) Number of tick marks to draw per cell. Defaults to 2.
visible?boolean(Optional) Whether or not the background is initially visible. Defaults to true.

Autoshrink

If you drag one of the nodes in the above example towards the edge of the grid, you'll see the grid expand in order to ensure there are always at least 2 grid squares between the content bounds and the edge of the grid. By default, though, the grid will also shrink back to any minimum boundaries if the content bounds shrinks appropriately.

You may not want this behaviour. You can turn it off via the autoShrink option:

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, GeneratedGridBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...

grid:{
size:{w:50, h:50},
},
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:GeneratedGridBackground.type,
minWidth:1500,
minHeight:1500,
autoShrink:false
}
}
]

})
Grid background

Tick marks

By default, the grid will be drawn with 2 tick marks in each cell. You can change this behaviour with the showTickMarks and tickMarksPerCell options. In this first example we hide the tick marks altogether:

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, GeneratedGridBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...

grid:{
size:{w:50, h:50},
},
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:GeneratedGridBackground.type,
minWidth:1500,
minHeight:1500,
autoShrink:false,
showTickMarks:false
}
}
]

})
Grid background

In this next example, we leave the drag grid at 50x50 on the Surface, but we expand the background grid to 250x250, and request 4 tick marks per cell:

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, GeneratedGridBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...

grid:{
size:{w:50, h:50},
},
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:GeneratedGridBackground.type,
minWidth:1500,
minHeight:1500,
autoShrink:false,
tickMarksPerCell:5,
grid:{w:250, h:250}
}
}
]

})
Grid background

Grid border

You can add a border to the background grid with the showBorder option:

import { newInstance } from "@jsplumbtoolkit/browser-ui-vanilla-2"
import { BackgroundPlugin, GeneratedGridBackground } from "@jsplumbtoolkit/browser-ui-plugin-background"

const toolkit = newInstance()
const surface = toolkit.render(someElement, {

...

grid:{
size:{w:50, h:50},
},
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:GeneratedGridBackground.type,
minWidth:500,
minHeight:500,
showBorder:true
}
}
]

})
Grid background

CSS classes

The generated grids are SVG elements, and each part of the grid is assigned a unique CSS class, allowing you to apply your own styles.

classvaluedescription
CLASS_BACKGROUND_BORDERjtk-background-borderAssigned to the rect element that provides the background border, if present
CLASS_BACKGROUND_GRIDjtk-background-gridAssigned to both the major and minor grid lines
CLASS_BACKGROUND_GRID_MINORjtk-background-grid-minorAssigned to the minor grid lines
CLASS_BACKGROUND_GRID_MAJORjtk-background-grid-majorAssigned to the major grid lines

Clamping to the background image

Depending on your use case, you may wish to force the surface to clamp the pan/zoom such that some portion of the background image is always visible. You do this by setting the clampToBackground parameter on a render call:

const surface = toolkit.render(someElement, {
clampToBackground:true,
plugins:[
{
type:BackgroundPlugin.type,
options:{
type:SimpleBackground.type,
url:"myBackground.png"
}
}
]
})

Zooming to the background image

If you wish to zoom out to the point that the entire background image is visible:

const surface = toolkit.render(someElement, { ... })
surface.zoomToBackground()