JSFiddle - React, Tailwind, and code Playground

by bfelda

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/black-tie/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.6/jquery.mousewheel.min.js"></script>
<script src="http://jsplumbtoolkit.com/demo/js/jquery.jsPlumb-1.5.5-min.js"></script>
<div id="viewport">
   <div id="board">
       <div id="foo" class="d">
           <span class="handle">TARGET</span>
       </div>
      <div id="bar" class="d">
           <span class="handle">DRAG</span>
       </div>
      <div id="baz" class="d">
           <span class="handle">SOURCE</span>
       </div>
   </div>
</div>

CSS

#viewport {
    border: 5px solid #000;
    position: fixed; left: 0; right: 0; top: 0; bottom: 0;
}

#board { 
    border: 5px solid blue;
    width: 2000px; height: 2000px;
    position: absolute;
}

.d {
    width:100px; height:100px;border:1px solid black;
    position:absolute;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-o-user-select: none;
	user-select: none;    
}

.handle { background-color: grey; cursor: move; }

#foo { top:50px;left:50px; }
#bar { top:250px;left:250px; }
#baz { top:50px;left:250px; }

JavaScript

jsPlumb.ready(function() {
    
    $('.d').each(function () {
        var $this = $(this);
        jsPlumb.makeSource($this, { 
            scope: "scope",
            //filter: ':not(span)' // does not work
            filter: function(event, element) {
                return event.target.tagName !== "SPAN";
            }
        });
        jsPlumb.makeTarget($this, { 
            scope:"scope" 
        });
        
        jsPlumb.draggable($this, {
            scope: "scope", 
            handle: ".handle"
        });        
    });
            
    jsPlumb.bind("click", function (c, e) {
        jsPlumb.detach(c);
    });
    
    jsPlumb.bind("beforeDrop", function (info) {
	    return info.sourceId != info.targetId;
    }); // info
    
    // Change Zoom Level to see different cases
	var level = 1, zooming = false;
        $board = $('#board'), 
        $viewport = $('#viewport');
        p = ["-webkit-", "-moz-", "-ms-", "-o-", ""];
            
    $viewport.bind('mousewheel', function(e, delta, dx, dy) {
        if (zooming) return;
        zooming = true;
        if (dx > 0 || dy > 0) {
            level = Math.min(3, level + 0.1);
        } else {
            level = Math.max(0.1, level - 0.1);
        }
        zoomTo(1); // a bug occurs if not zoom to 1
        zoomTo(level);
        zooming = false;
	});
    function zoomTo(level) {
        var s = "scale(" + level + ")";
        for (var i = 0; i < p.length; i++) {
            $board.css(p[i] + "transform", s);
        }
        jsPlumb.setZoom(level, true);
        if (level == 1) $board.css({top:0,left:0});
        else {
            var pos = $board.position();
            $board.css({ top: -pos.top, left: -pos.left });
        }
    }
});