使用rxjs检测多点触摸长按事件

时间:2013-10-17 10:38:38

标签: javascript system.reactive rxjs

一直在玩rxjs。我发现它真的很棒,但它真的花了一些时间来解决它。 这是一个我无法解决的问题,所以我正在寻找一些见解。

考虑一个多点触控界面,对于每个touchstart / touchmove / touchend,你可以使用{id:,x:x,y:y,t:t,current_pointers:}

作为对象的参数

我想要一个可以在1500毫秒之后触发每个向下指针的事件的observable,除非触发了该指针的touchmove或touchup。

对于单次触摸它很简单,你只需要进行触摸移动或触摸,但是当指针的id在链中的第一个observable中时,你将如何使用takeUntil?

1 个答案:

答案 0 :(得分:3)

它有助于平整触摸阵列,因此您可以单独处理触摸。这是使用Rx-jQuery绑定的基本思想。我没有对它进行测试,因此可能有点儿错误:

var flattenTouches = function (ev) {
    return ev.changedTouches.map(function(t) { return { ev: ev, touch: t }; });
};
var starts = $element.bindAsObservable("touchstart")
    .selectMany(function (ev) { return Rx.Observable.fromArray(flattenTouches(ev)); });
var moves = $element.bindAsObservable("touchmove")
    .selectMany(function (ev) { return Rx.Observable.fromArray(flattenTouches(ev)); })
    .publish().refCount(); // to prevent multiple subscriptions
var ends = $element.bindAsObservable("touchend")
    .selectMany(function (ev) { return Rx.Observable.fromArray(flattenTouches(ev)); })
    .publish().refCount(); // to prevent multiple subscriptions

var moveOrEnds = Rx.Observable.mergeObservable(moves, ends);
var timer = Rx.Observable.timer(1500);

var longpresses = starts
    .selectMany(function (start) {
        var thisPointerMovesOrEnds = movesOrEnds.where(function(t) {
            return t.touch.identifier === start.touch.identifier;
        });
        return timer
            .takeUntil(thisPointerMovesOrEnds)
            .select(start);
    });

longpresses.subscribe(function (t) {
    console.log("longpress", t.touch.pageX, t.touch.pageY, t.touch.identifier);
});