Double clicks

by Andre Staltz

HTML

<div id="dragTarget">TARGET</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.2.26/rx.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.2.26/rx.async.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.2.26/rx.coincidence.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.2.26/rx.binding.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.2.26/rx.time.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/2.0.7/rx.dom.js"></script>

CSS

body {
    font-family: sans-serif;
    padding: 10px;
}
#dragTarget {
    padding: 5px;
    background-color: #ECECFF;
    display: inline-block;
    position: absolute;
}

JavaScript

var dragTarget = document.getElementById('dragTarget');

// Get the three major events
var mouseup   = Rx.Observable.fromEvent(dragTarget, 'mouseup')
    .do(function() { console.log("mouse up"); });
var mousemove = Rx.Observable.fromEvent(document,   'mousemove').publish().refCount()
    .do(function() { console.log("mouse move"); });
var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown')
    .do(function() { console.log("mouse down"); });

var mousedrag = mousedown.flatMap(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();
        
        return {
            left: mm.clientX - startX,
            top: mm.clientY - startY
        };
    }).takeUntil(mouseup);
});

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