JSFiddle - React, Tailwind, and code Playground

by chicagogrooves

HTML

<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/bootstrap/2.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/bootstrap/2.3.1/css/bootstrap-responsive.min.css">
    <div id="dragTarget">Drag Me!</div>
    <div class="container">
        <div class="page-header">
            <h1>RxJS  Drag and Drop Example</h1>
            <p class="lead">Example to show coordinating events to perform drag and drop</p>
        </div>
    </div>  
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx.binding.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/2.0.7/rx.dom.js"></script>

CSS

#dragTarget {
    background-image: url(https://raw.github.com/Reactive-Extensions/RxJS/master/examples/dragndrop/logo.png);
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    height: 200px;
    width: 200px;
    background-color: #000000; 
    border: 1px solid #666666;
    color: #ffffff; 
    padding: 10px; 
    position: absolute;
    cursor: move;
}

JavaScript

(function (global) {

    function main () {
        var dragTarget = document.getElementById('dragTarget');

        // Get the three major events
        var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup');
        var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
        var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown');

        var mousedrag = mousedown.selectMany(function (md) {

            // calculate offsets when mouse down
            var startX = md.offsetX, startY = md.offsetY;

            // Calculate delta with mousemove until mouseup
            return mousemove.map(function (mm) {
                (mm.preventDefault) ? mm.preventDefault() : event.returnValue = false; 

                return {
                    left: mm.clientX - startX,
                    top: mm.clientY - startY
                };
            }).takeUntil(mouseup);
        });

        // Update position
        subscription = mousedrag.subscribe(function (pos) {          
            dragTarget.style.top = pos.top + 'px';
            dragTarget.style.left = pos.left + 'px';
        });
    }

    main();

}(window));