个人学习记录 rxjs操作符 concatMap 做盒子拖拽

124 阅读1分钟

这是学习记录, 使用 rxjs操作符 concatMap 做盒子拖拽

concatMap 是按顺序触发,上游Observable完成才会触发下游Observable

  import { fromEvent, merge } from 'rxjs';
  import { concatMap, map, takeUntil } from 'rxjs/operators';

  ngOnInit(){
    setTimeout(() => {
      const box = <HTMLElement>document.querySelector('#box');
      const mouseDown$ = fromEvent(box, 'mousedown');
      const mouseUp$ = fromEvent(box, 'mouseup');
      const mouseOut$ = fromEvent(box, 'mouseout');
      const mouseMove$ = fromEvent(box, 'mousemove');
    
      const drag$ = mouseDown$.pipe(
        concatMap((startEvent:any)=> {
          const initialLeft = box.offsetLeft;
          const initialTop = box.offsetTop;
          // 鼠标弹出或滑出去了 都要结束, 先到先执行
          const stop$ = merge(mouseUp$,mouseOut$)
          return mouseMove$.pipe(
            // takeUntil的 stop$参数任一Observable触发完成, 这个鼠标移动的Observable便结束
            takeUntil(stop$), 
            map((moveEvent:any) => {
              return {
                x: moveEvent.x - startEvent.x + initialLeft,
                y: moveEvent.y - startEvent.y + initialTop,
              };
            })
          )
        })
      )
      drag$.subscribe((event:any) => {
        box.style.left = event.x + 'px';
        box.style.top = event.y + 'px';
      });
    },2000)
  }