Skip to main content

Zoom and pan paper

Zooming and panning are provided by the PaperScroller plugin of JointJS+. The plugin acts as an interactive extension to JointJS Paper - it serves as a window to the (larger) Paper underneath.

Remember how we defined the <div id="paper"> HTML element as the host element for our JointJS Paper? We will change that initial part of our code in order to render our PaperScroller in that HTML element instead:

const namespace = shapes;

const graph = new dia.Graph({}, { cellNamespace: namespace })

const paper = new dia.Paper({
model: graph,
width: 2000,
height: 2000,
background: { color: '#F5F5F5' },
cellViewNamespace: namespace,
defaultRouter: { name: 'orthogonal' },
defaultConnector: { name: 'straight', args: { cornerType: 'line' }}
});

const paperScroller = new ui.PaperScroller({
paper: paper,
scrollWhileDragging: true
});
document.getElementById('paper').appendChild(paperScroller.render().el);
What changes did we make?
  • We removed our Paper's el option - we don't need it because the HTML element will be handled by the PaperScroller instead.
  • We are now free to make the Paper's width and height as large as we wish - so we changed both to 2000px.
  • We told our PaperScroller what paper it links to, so that the PaperScroller can automatically show an appropriate view into the Paper area according to user interaction.
  • Note that unlike the JointJS Paper, the JointJS+ PaperScroller does not need to have width and height specified - it automatically adjusts to the size of its host HTML element.
  • Finally, we added the scrollWhileDragging option to our PaperScroller - it provides more interactivity by letting us scroll the paper by dragging elements to the edge of the diagram.

Panning of the Paper is enabled by default. We will also enable our users to zoom the Paper via the pinch gesture:

paper.on('paper:pinch', (_evt, ox, oy, scale) => {
const zoom = paperScroller.zoom();
paperScroller.zoom(zoom * scale, { min: 0.2, max: 5, ox, oy, absolute: true });
});

Now, let's use the fact that we now have much more space in our Paper area to work with and reposition our two Elements to the middle of the Paper:

const rect1 = new shapes.standard.Rectangle();
rect1.position(870, 900);
rect1.resize(200, 50);
rect1.addTo(graph);

const rect2 = new shapes.standard.Rectangle();
rect2.position(930, 1050);
rect2.resize(200, 50);
rect2.addTo(graph);

To make sure our user doesn't get disoriented, we tell the PaperScroller to put our diagram content at the center of their viewport (after all Elements and Links are added to the Graph):

paperScroller.centerContent();

Let's also enhance our Toolbar component by adding a few PaperScroller interaction tools to it:

const toolbar = new ui.Toolbar({
tools: [
{
type: 'button',
name: 'json',
text: 'Export JSON'
},
{
type: 'button',
name: 'svg',
text: 'Export SVG'
},
'separator',
'zoomToFit',
'zoomSlider'
],
references: {
paperScroller: paperScroller
}
});
toolbar.render();
document.getElementById('toolbar').appendChild(toolbar.el);
What changes did we make?
  • We changed the position of our Elements within the Paper.
  • We centered the Paper content (Elements and Links) in PaperScroller via centerContent() function.
  • We added a divider and two pre-made JointJS+ buttons to the tools array of our Toolbar - separator, zoomToFit, zoomSlider.
  • We added a reference to our PaperScroller to references of our Toolbar - this allows our Toolbar to tell the PaperScroller about user interactions with its zoom buttons.

See it in action

The Paper area is now interactive - you can navigate around the Paper by using your computer's trackpad (or alternatively, via the two scrollbars). You can also try the scroll-while-dragging functionality by dragging a diagram element to the edge of the Paper area:

💡 Would you prefer to learn more about Zoom & pan? We have many demos illustrating it on our Demos & examples page.