拖动锁定交互从首次双击开始,然后是一些鼠标移动,然后以第二次双击结束。它是拖放的一种变体。
我想在RxJS中编写这种交互,但我面临的一个大问题是同一事件(双击)开始和结束交互(编码拖放时我们没有的问题)。
如何使用RxJS实现拖锁? 我想订阅第一次点击,所有移动和最后双击。
答案 0 :(得分:1)
plunker:https://plnkr.co/edit/MXUtPzH9iD40VjVxLBwB?p=preview
让我们定义一个事件 - DragLockEvent,它包含" DragLockEventType"这可能是' initialClick',' move'或者' finalClick'以及鼠标移动事件,以防它类型为'移动'。
现在让我们创建一个可以发出这些事件的observable:dragLock $。
在观察者的内部,有一个标志 - "拖动",表明我们是否正在拖动。
现在我们需要听双击事件,对于每个这样的事件,我们需要切换拖动标志,并发出匹配事件。
然后,如果我们处于拖动模式,我们开始收听鼠标移动事件并报告它们,直到我们再次双击。
type DragLockEventType = 'initialClick' | 'move' | 'finalClick';
interface DragLockEvent {
type: DragLockEventType;
moveEvent?: MouseEvent;
}
const dragLock$: Observable<DragLockEvent> = Observable.create((observer: Observer<DragLockEvent>) => {
let dragging = false;
const doubleClick$ = fromEvent(document.documentElement, 'dblclick')
.pipe(takeWhile(() => !observer.closed));
const mouseMove$ = fromEvent(document.documentElement, 'mousemove')
.pipe(takeWhile(() => !observer.closed));
doubleClick$
.pipe(
tap(() => {
dragging = !dragging;
if (dragging) observer.next({ type: 'initialClick' });
else observer.next({ type: 'finalClick' });
}),
filter(() => dragging),
switchMap(() => mouseMove$.pipe(takeUntil(doubleClick$)))
)
.subscribe((e: MouseEvent) => observer.next({ type: 'move', moveEvent: e }))
});