天天看点

[RxJS] Drag and Drop example

Improving our mouse drag event

Our mouse drag event is a little too simple. Notice that when we drag around the sprite, it always positions itself at the top-left corner of the mouse. Ideally we'd like our drag event to offset its coordinates, based on where the mouse was when the mouse down event occurred. This will make our mouse drag more closely resemble moving a real object with our finger.

spriteContainerMouseMoves =
    seq([ {x: 200, y: 400, offsetX: 10, offsetY: 15},,,{x: 210, y: 410, offsetX: 20, offsetY: 26},,, ])      
function(sprite, spriteContainer) {
    // All of the mouse event sequences look like this:
    // seq([ {pageX: 22, pageY: 3423, offsetX: 14, offsetY: 22} ,,, ])
    var spriteMouseDowns = Observable.fromEvent(sprite, "mousedown"),
        spriteContainerMouseMoves = Observable.fromEvent(spriteContainer, "mousemove"),
        spriteContainerMouseUps = Observable.fromEvent(spriteContainer, "mouseup"),
        // Create a sequence that looks like this:
        // seq([ {pageX: 22, pageY:4080 },,,{pageX: 24, pageY: 4082},,, ])
        spriteMouseDrags =
            // For every mouse down event on the sprite...
            spriteMouseDowns.
                concatMap(function(contactPoint) {
                    // ...retrieve all the mouse move events on the sprite container...
                    return spriteContainerMouseMoves.
                        // ...until a mouse up event occurs.
                        takeUntil(spriteContainerMouseUps).
                        map(function(movePoint) {
                            return {
                                pageX: movePoint.pageX - contactPoint.offsetX,
                                pageY: movePoint.pageY - contactPoint.offsetY
                            };
                        });
                });

    // For each mouse drag event, move the sprite to the absolute page position.
    spriteMouseDrags.forEach(function(dragPoint) {
        sprite.style.left = dragPoint.pageX + "px";
        sprite.style.top = dragPoint.pageY + "px";
    });
}