I'm binding together SVG graphics and mouse/touch events, using RxJS.
One of the challenges is that on iOS, a single touchstart
event can carry multiple touch data. When it's just one, I can trivially use select
and convert each TouchEvent
to an observable of coordinates (i.e. each touch start initiates a new drag). But how can I add 2 or 3 entries to the observable, from just the single event?
Not sure if flatMap
is the thing. Maybe selectMany
is? I've read the manuals but they are ... a bit entangled and full of streamy language.
The lines in question are these. If you are interested in making interactive SVG graphics in a browser easier to program for, welcome to help with the project!
selectMany
is the same as flatMap
.
RxJS provides some examples, also for Drag'n'Drop, you can find it here.
If this doesn't fit your needs, you can use a Rx.Subject to send notifications around, e.g.
var oneSubject = new Rx.Subject();
var otherSubject = new Rx.Subject();
someObservable.subscribe(function(x) {
oneSubject.onNext('hello');
otherSubject.onNext(42);
});
// subscribe to oneSubject or otehrSubject
EDIT
If you mean with "one event to multiple items" that you get an x and want to send n times x, then you can also use repeat, e.g. n = 10
someObservable.flatMap(function(x) { return Rx.Observable.repeat(x, 10); });
The .selectMany
is really rather trivial to use, it seems.
Whereas for select
one would convert an input value to an output (emitted) value, for .selectMany
one returns an array or observable (both work) of the 0..n values one wishes to emit. That's it. :)
My code ended up being like this:
return range( 0, ev.changedTouches.length ).map( function (i) {
return touchDragObs( ev, i );
} );
The range
is a helper function to create an 0..n-1 seed array:
// JavaScript does not have an Array for range constructor.
//
function range( start, count ) { // (Int,Int) -> Array of Int
var arr = [];
for (var i=0; i<count; i++ ) {
arr[i]= start+i;
}
return arr;
}
Another option would be this (both work):
return Rx.Observable
.range(0,ev.changedTouches.length) // (start, count)
.select( function (i) {
return touchDragObs( ev, i );
});
If anyone knows the performance indications of the above options, I'd like to know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With