If the paper is too big for the div it's shown in, I'd like to make the paper draggable.
I tried the papers blank:pointerdown and pointerup events but was not able to just follow the mousemovement. I also tried to make the element of the paper draggable via jquery, but nothing seems to do the trick...
Is there any way to do this?
This can be achieved with a combination of JointJS events and document events. The graph display is encapsulated in a div
:
<div id='diagram'></div>
Then add the event handlers for JointJS, first the pointerdown
event where we store the start position of the drag:
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = { x: x, y: y};
}
);
Then the end of the drag (pointerup) when we delete the variable we store the position in (it also acts as a flag whether there is an active drag in progress):
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
delete dragStartPosition;
});
As JointJS does not expose a "paper pointer move" event, we need to use the mousemove
document event. For example, with JQuery:
$("#diagram")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
We get the drag start coordinates and the current pointer position and update the paper position using the paper.translate()
call.
WARNING: if you scale the paper (using paper.scale()
), you have to also scale the starting position of the drag:
var scale = V(paper.viewport).scale();
dragStartPosition = { x: x * scale.sx, y: y * scale.sy};
The calls to paper.translate()
will then update to the proper position.
I know this is a slightly old thread, but I was stuck with this for a while and came across a neat solution using the SVG Pan and Zoom library. Git hub link here
EDIT - I created a plunker of the steps below (plus some extras) here: SVG panning with Jointjs
First step after creating the paper is to initialise SVG Pan and Zoom:
panAndZoom = svgPanZoom(targetElement.childNodes[0],
{
viewportSelector: targetElement.childNodes[0].childNodes[0],
fit: false,
zoomScaleSensitivity: 0.4,
panEnabled: false
});
Where targetElement is the div that the jointjs paper has gone into. Jointjs will create a SVG element within that (hence the childNodes[0]) and within that element the first element is the viewport tag (hence childNodes[0].childNodes[0] in the viewportselector). At this stage pan is disabled, because in my use case it would intefer with drag and drop elements on the paper. Instead what I do is keep a reference to the panAndZoom object and then switch pan on and off on the blank:pointerdown and blank:pointerup events:
paper.on('blank:pointerdown', function (evt, x, y) {
panAndZoom.enablePan();
});
paper.on('cell:pointerup blank:pointerup', function(cellView, event) {
panAndZoom.disablePan();
});
Just another way of tackling the issue I guess, but I found it a bit easier, plus it gives you zoom too and you can adjust the sensitivity etc.
I suggest the following:
blank:pointerdown event
that will initiate the paper dragging (store a flag which you'll use in your mousemove
handler to recognize the paper is in the "panning" state).<div>
container with CSS overflow: auto
. This <div>
will be your little window to the large paper.mousemove
event (because you most likely want the paper to be dragged even if the mouse cursor leaves the paper area?). In this handler, you'll be setting the scrollLeft
and scrollTop
properties of your <div>
container making the paper "panning". For adjusting the scrollLeft
and scrollTop
properties, you'll use the clientX
and clientY
properties of the event object together with the same properties that you stored previously in your blank:pointerdown
handler. (in other words, you need those to find the offset of the panning from the last mousemove
/blank:pointerdown
).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With