Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detecting multitouch longpress event using rxjs

Been playing around with rxjs. I find it really good, but it really took some time to get my head around it. Here's a little one I can't solve, so I'm looking for some insight.

Consider a multitouch interface where for each touchstart/touchmove/touchend you would have as params an object with {id:, x:x, y:y, t:t, current_pointers: }

I would like an observable that would trigger an event for each down pointer after 1500 ms unless touchmove or touchup happens for that pointer.

For a single touch it's straightforward, you would just takeUntil touch move or touchup, but how would you use takeUntil when the id of the pointer is within the first observable in the chain ?

like image 898
trokster Avatar asked Jun 09 '26 03:06

trokster


1 Answers

It helps to flatten the touches array so you can treat the touches individually. Here's the basic idea, using the Rx-jQuery bindings. I've not tested it so it might be a bit buggy:

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);
});
like image 198
Brandon Avatar answered Jun 10 '26 17:06

Brandon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!