最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Joint.js Drag and Drop Element between two papers - Stack Overflow

programmeradmin1浏览0评论

I am implementing drag and drop between two papers .But I am stuck with the syncing of offset of dragged element with cursor position as I have two papers in my html body.I have very minute experience with css which may be causing problem of positioning of elements.

Use Case:-

User clicks on element from paper 2 and starts dragging and go to paper 1. On Pointer up a clone of that element is added to paper 1 on the position of cursor in paper 1.

My strategy to handle this is :-

When the user clicks mousedown

1.Dynamically create a div

2.Create a third paper, say call it "flypaper" in the new div Make a copy of the element that you want to clone, and add it to "flypaper"

3.Create a mousemove listener that will move the div containing "flypaper" with the mouse

4.Add a mouseup event that will add a clone of the element to the "paper2" when the user releases the button.

5.Clean up the "flypaper" div and events.

<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" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<script>
    var graph = new joint.dia.Graph;
    var paper = new joint.dia.Paper({
        el: $('#paper'),
        width: 600,
        height: 200,
        model: graph,
        gridSize: 1

    });
    var rect = new joint.shapes.basic.Rect({
        position: { x: 100, y: 30 },
        size: { width: 100, height: 30 },
        attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
    });
    graph.addCells([rect]);
    ////////////////////////////////////////////////////////
    var graph2 = new joint.dia.Graph;
    var paper2 = new joint.dia.Paper({
        el: $('#paper2'),
        width: 600,
        height: 200,
        model: graph2,
        gridSize: 1
    });
    paper2.on('cell:pointerup',function (cellView, evt, x, y) {
        var rect4 = new joint.shapes.basic.Rect({
            position: { x: 10, y: 50 },
            size: { width: 100, height: 30 },
            attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
        });

        graph.addCells([rect4]);
    });
    paper2.on('cell:pointerdown',function (cellView, evt, x, y) {
        $('body').append('<div id="flyPaper" class="box" style="position: fixed;z-index: 100;display:block;opacity:.7;"></div>');
        var graph3 = new joint.dia.Graph;
        var paper3 = new joint.dia.Paper({
            el: $('#flyPaper'),
            width: 600,
            height: 200,
            model: graph3,
            gridSize: 1
        });
        var rect3 = new joint.shapes.basic.Rect({
            position: { x: 10, y: 50 },
            size: { width: 100, height: 30 },
            attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
        });

        graph3.addCells([rect3]);
        $('body').mousemove(function(e){
            var mouseX   =  e.pageX; //get mouse move position
            var mouseY   =  e.pageY;
            $( "div.box" ).offset({ top: mouseY, left: mouseX });
            // $('div.box',this).css({'top': boxPositionY,'left': boxPositionX})
        });

    });

    var rect2 = new joint.shapes.basic.Rect({
        position: { x: 10, y: 50 },
        size: { width: 100, height: 30 },
        attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
    });
    graph2.addCells([rect2]);
</script>
</body>

I am implementing drag and drop between two papers .But I am stuck with the syncing of offset of dragged element with cursor position as I have two papers in my html body.I have very minute experience with css which may be causing problem of positioning of elements.

Use Case:-

User clicks on element from paper 2 and starts dragging and go to paper 1. On Pointer up a clone of that element is added to paper 1 on the position of cursor in paper 1.

My strategy to handle this is :-

When the user clicks mousedown

1.Dynamically create a div

2.Create a third paper, say call it "flypaper" in the new div Make a copy of the element that you want to clone, and add it to "flypaper"

3.Create a mousemove listener that will move the div containing "flypaper" with the mouse

4.Add a mouseup event that will add a clone of the element to the "paper2" when the user releases the button.

5.Clean up the "flypaper" div and events.

<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" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<script>
    var graph = new joint.dia.Graph;
    var paper = new joint.dia.Paper({
        el: $('#paper'),
        width: 600,
        height: 200,
        model: graph,
        gridSize: 1

    });
    var rect = new joint.shapes.basic.Rect({
        position: { x: 100, y: 30 },
        size: { width: 100, height: 30 },
        attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
    });
    graph.addCells([rect]);
    ////////////////////////////////////////////////////////
    var graph2 = new joint.dia.Graph;
    var paper2 = new joint.dia.Paper({
        el: $('#paper2'),
        width: 600,
        height: 200,
        model: graph2,
        gridSize: 1
    });
    paper2.on('cell:pointerup',function (cellView, evt, x, y) {
        var rect4 = new joint.shapes.basic.Rect({
            position: { x: 10, y: 50 },
            size: { width: 100, height: 30 },
            attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
        });

        graph.addCells([rect4]);
    });
    paper2.on('cell:pointerdown',function (cellView, evt, x, y) {
        $('body').append('<div id="flyPaper" class="box" style="position: fixed;z-index: 100;display:block;opacity:.7;"></div>');
        var graph3 = new joint.dia.Graph;
        var paper3 = new joint.dia.Paper({
            el: $('#flyPaper'),
            width: 600,
            height: 200,
            model: graph3,
            gridSize: 1
        });
        var rect3 = new joint.shapes.basic.Rect({
            position: { x: 10, y: 50 },
            size: { width: 100, height: 30 },
            attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
        });

        graph3.addCells([rect3]);
        $('body').mousemove(function(e){
            var mouseX   =  e.pageX; //get mouse move position
            var mouseY   =  e.pageY;
            $( "div.box" ).offset({ top: mouseY, left: mouseX });
            // $('div.box',this).css({'top': boxPositionY,'left': boxPositionX})
        });

    });

    var rect2 = new joint.shapes.basic.Rect({
        position: { x: 10, y: 50 },
        size: { width: 100, height: 30 },
        attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
    });
    graph2.addCells([rect2]);
</script>
</body>
Share Improve this question edited Feb 12, 2016 at 10:41 xpy 5,6213 gold badges32 silver badges50 bronze badges asked Jul 8, 2015 at 5:06 AchillesAchilles 5197 silver badges27 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 25

I had the same problem (and have clients who won't pay for rappid which adds this feature to jointjs). So here's a snippet that may help others (see below).

The steps are th same as you pointed out:
1.Dynamically create a div
2.Create a third paper, say call it "flypaper" in the new div Make a copy of the element that you want to clone, and add it to "flypaper"
3.Create a mousemove listener that will move the div containing "flypaper" with the mouse
4.Add a mouseup event that will add a clone of the element to the "paper2" when the user releases the button.
5.Clean up the "flypaper" div and events.

The solution to your problem was to use cellView.model.clone() to add the right element and then some computation with $.offset, $.width() & $.height() to get the right flyingpaper postion and to check if the drop event occured on the target paper.

View 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 sape are dropped
    var graph = new joint.dia.Graph,
      paper = new joint.dia.Paper({
        el: $('#paper'),
        model: graph
      });

    // Canvas from which you take 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>
发布评论

评论列表(0)

  1. 暂无评论