Reputation: 353
in case when user very fast dragging via observable mousemove event, we don't need to emit each px this events, only when he trying to aim before drop element (we can catch this moment bcs speed of mouse will be low), is there any trick for this?
mb some case to get speed via px/per seconds then filter or etc...
Upvotes: 0
Views: 329
Reputation: 5364
You could do a pairwise
comparison of the mouse position, measuring the distance between events and filtering out high velocity moves:
const { fromEvent } = rxjs;
const { pairwise, map, filter } = rxjs.operators;
const block = document.getElementById('block');
const mousemove$ = fromEvent(block, 'mousemove');
mousemove$.pipe(
// filter out high velocity movements
pairwise(),
map(([a, b]) => ({
d: getDistance(a,b),
x: b.x,
y: b.y
})),
filter(e => e.d < 10)
).subscribe(e => {
console.log(e.x, e.y);
});
function getDistance(a, b){
return Math.sqrt(
Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)
);
}
<script src="https://unpkg.com/[email protected]/bundles/rxjs.umd.min.js"></script>
<style>
#block {
margin: 3rem;
padding: 6rem;
background: rebeccapurple;
}
</style>
<div id="block"></div>
This depends on the rate of browser emitting and handling those events.
So you'll probably will need to add timeInterval
to calculate the speed, not just the delta.
--
OR you could achieve this by using debounceTime, throttleTime, auditTime or sampleTime.
Heres an example using sampleTime
300ms, that I would recommend:
const { fromEvent } = rxjs;
const { sampleTime } = rxjs.operators;
const block = document.getElementById('block');
const mousemove$ = fromEvent(block, 'mousemove');
mousemove$.pipe(
// sample only once per 300ms
sampleTime(300)
).subscribe(e => {
console.log(e.x, e.y);
});
<script src="https://unpkg.com/[email protected]/bundles/rxjs.umd.min.js"></script>
<style>
#block {
margin: 3rem;
padding: 6rem;
background: rebeccapurple;
}
</style>
<div id="block"></div>
Surely, you could also combine "delta move" measuring with "sampling"
Hope this helps
Upvotes: 2