Bacon.js:用鼠标选择,拖放并触摸并使用箭头键移动

时间:2014-10-08 12:25:23

标签: javascript drag-and-drop touch onkeyup bacon.js

我们正在编写像powerpoint这样的应用程序,我们正在考虑使用bacon.js。有图片,文字等元素可以拖动到屏幕上,然后选择,使用鼠标拖放或触摸事件和使用箭头键移动。

我使用之前的一些指导原则制作了这个简单的样本,可以使用鼠标拖动2个div:http://jsfiddle.net/5y6qqqg2/3/

// allKeyUps :: Observable KeyEvent
var keyDown = $(document)
.asEventStream('keyDown')
.filter(function(ev){
    return ev.keyCode==37 || 
        ev.keyCode==38 ||
        ev.keyCode==39 ||
        ev.keyCode==40
}).log()






function xyFromEvent(v) {
    return {
        x: v.clientX,
        y: v.clientY
    }
}

function getDelta(t) {
    var a = t[1];
    var b = t[0];
    return {
        x: a.x - b.x,
        y: a.y - b.y
    };
}

function add(p1, p2) {
    return {
        x: p1.x + p2.x,
        y: p1.y + p2.y
    };
}

$().ready(function () {
    var onMove = $("html").asEventStream('mousemove')
    addDraggable($("#1"), onMove);
    addDraggable($("#2"), onMove);
});

function addDraggable(block, onMove) {
    var startDrag = block.asEventStream('mousedown')
    var endDrag = block.asEventStream('mouseup')


    var draggingDeltas = startDrag.flatMap(function () {
        return onMove.map(xyFromEvent)
            .slidingWindow(2, 2)
            .map(getDelta)
            .takeUntil(endDrag)
    })



    var blockPosition = draggingDeltas.scan({
        x: 0,
        y: 0
    }, add);

    blockPosition.onValue(function (pos) {
        block.css({
            top: pos.y + "px",
            left: pos.x + "px"
        });
    });
}

但我对bacon.js的经验不足以能够挂钩事件流以便keydown只移动一个元素而不是所有元素。

1 个答案:

答案 0 :(得分:1)

我会做这样的事情:

  • 对于每个可移动元素,创建一个选定的流(来自我猜测的点击),并将每次点击映射到元素的id。
  • 合并所有这些流以创建当前所选元素的属性。
  • keyDown信息流映射到增量值,最后为{x: 0, y: -1},让我们称它为例如keyDelta
  • 组合selectedElement和keyDelta流以创建移动事件流,例如{id: 37, delta: {x: 0, y: -1},我们称之为keyDeltas
  • 重构您拖动代码以生成具有相同类型值(id& delta)的流
  • 合并keyDeltas并拖动流,现在您有一个包含所有对象的所有移动的流
  • 扫描该流,现在是一个包含所有对象位置的流
  • 位置流的
  • onValue,进行渲染。