I encountered a similar issue (and faced resistance from clients unwilling to pay for rappid which provides this functionality for jointjs). Here is a helpful snippet that might assist others (details below).
The steps align with your observations:
1. Generate a div dynamically.
2. Establish a third paper, referred to as "flypaper," within the new div. Duplicate the desired element and append it to "flypaper."
3. Implement a mousemove listener to move the div containing "flypaper" in sync with the mouse movement.
4. Incorporate a mouseup event that places a clone of the element onto "paper2" upon releasing the mouse button.
5. Tidy up the "flypaper" div along with associated events.
The resolution involved utilizing cellView.model.clone()
for adding the appropriate element, followed by calculations leveraging $.offset
, $.width()
, and $.height()
to determine the accurate flying paper position and confirm if the drop event happened on the target paper.
Access on codepen
<body>
<div id="paper" class="paper" style="border-style: solid;border-width: 5px;width:600px"></div>
<div id="paper2" class="paper" style="border-style: solid;border-width: 5px;width:600px;display:inline-block"></div>
<script>
// Canvas where shapes are dropped
var graph = new joint.dia.Graph,
paper = new joint.dia.Paper({
el: $('#paper'),
model: graph
});
// Canvas providing shapes
var stencilGraph = new joint.dia.Graph,
stencilPaper = new joint.dia.Paper({
el: $('#stencil'),
height: 60,
model: stencilGraph,
interactive: false
});
var r1 = new joint.shapes.basic.Rect({
position: {
x: 10,
y: 10
},
size: {
width: 100,
height: 40
},
attrs: {
text: {
text: 'Rect1'
}
}
});
var r2 = new joint.shapes.basic.Rect({
position: {
x: 120,
y: 10
},
size: {
width: 100,
height: 40
},
attrs: {
text: {
text: 'Rect2'
}
}
});
stencilGraph.addCells([r1, r2]);
stencilPaper.on('cell:pointerdown', function(cellView, e, x, y) {
$('body').append('<div id="flyPaper" style="position:fixed;z-index:100;opacity:.7;pointer-event:none;"></div>');
var flyGraph = new joint.dia.Graph,
flyPaper = new joint.dia.Paper({
el: $('#flyPaper'),
model: flyGraph,
interactive: false
}),
flyShape = cellView.model.clone(),
pos = cellView.model.position(),
offset = {
x: x - pos.x,
y: y - pos.y
};
flyShape.position(0, 0);
flyGraph.addCell(flyShape);
$("#flyPaper").offset({
left: e.pageX - offset.x,
top: e.pageY - offset.y
});
$('body').on('mousemove.fly', function(e) {
$("#flyPaper").offset({
left: e.pageX - offset.x,
top: e.pageY - offset.y
});
});
$('body').on('mouseup.fly', function(e) {
var x = e.pageX,
y = e.pageY,
target = paper.$el.offset();
// Dropped over paper ?
if (x > target.left && x < target.left + paper.$el.width() && y > target.top && y < target.top + paper.$el.height()) {
var s = flyShape.clone();
s.position(x - target.left - offset.x, y - target.top - offset.y);
graph.addCell(s);
}
$('body').off('mousemove.fly').off('mouseup.fly');
flyShape.remove();
$('#flyPaper').remove();
});
});
</script>
</body>