JounQin / blog

a Blog system built on GitHub GraphQL API with Vue SSR
https://blog.1stG.me
MIT License
13 stars 2 forks source link

使用 rxjs 实现一个简易拖拽元素功能 #419

Open JounQin opened 2 years ago

JounQin commented 2 years ago
const { fromEvent, map, switchMap, takeUntil } = rxjs

const mousedown$ = fromEvent(document.getElementById('drag'), 'mousedown')
const mousemove$ = fromEvent(document, 'mousemove')
const mouseup$ = fromEvent(document, 'mouseup')

mousedown$
  .pipe(
    switchMap(downEv => {
      const startX = downEv.clientX
      const startY = downEv.clientY
      const originalLeft = +drag.style.left.replace('px', '')
      const originalTop = +drag.style.top.replace('px', '')
      return mousemove$.pipe(
        map(moveEv => {
          const moveX = moveEv.clientX
          const moveY = moveEv.clientY
          const deltaX = moveX - startX
          const deltaY = moveY - startY
          return {
            originalLeft,
            originalTop,
            deltaX,
            deltaY,
          }
        }),
        takeUntil(mouseup$), // `takeUntil` 不能移到外面,否则触发一次 `mouseup` 后整个流就终止了
      )
    }),
  )
  .subscribe(({ originalLeft, originalTop, deltaX, deltaY }) => {
    drag.style.left = originalLeft + deltaX + 'px'
    drag.style.top = originalTop + deltaY + 'px'
  })

https://jsfiddle.net/rj5odeh6/24/