rxjs6 简单拖拽

原文链接: rxjs6 简单拖拽

上一篇: rxjs6 Utility Operators

下一篇: rxjs6 拖拽接龙

效果

使用rxjs为dom添加拖拽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./rxjs.umd.js"></script>
  <style>
    .box {
      width: 50px;
      height: 50px;
      background: deepskyblue;
      position: relative;
    }

    .circle {
      border-radius: 50%;
    }
  </style>
</head>
<body>

<div class="box" id="box1"></div>
<div class="box circle" id="box2"></div>

<script>
  const {range, fromEvent} = rxjs;
  const {map, mapTo, filter, throttleTime, debounceTime, repeat, switchMap, takeUntil} = rxjs.operators;

  function setPosition(elem, position) {
    elem.style['left'] = position.x + 'px'
    elem.style['top'] = position.y + 'px'
  }

  function getPosition(elem) {
    return {
      x: +elem.style.left.replace('px', ''),
      y: +elem.style.top.replace('px', ''),
    }
  }

  function addDrag(elem, container) {
    let mousedown = fromEvent(elem, 'mousedown')
    let mouseup = fromEvent(container, 'mouseup')
    let mousemove = fromEvent(container, 'mousemove')

    mousedown.pipe(
      map(e => {
        let {x, y} = getPosition(elem)
        return {
          clickX: e.x,
          clickY: e.y,
          initX: x,
          initY: y,
          clickTime: +new Date()
        }
      }),
      switchMap(({clickX, clickY, initX, initY, clickTime}) =>
        mousemove.pipe(
          throttleTime(40),
          map(
            e => {
              let x = initX + e.x - clickX
              let y = initY + e.y - clickY
              let time = +new Date() - clickTime
              return {
                x,
                y,
                time
              }
            }
          )
        )
      ),
      takeUntil(mouseup),
      repeat()
    ).subscribe(position => {
      console.log(position)
      setPosition(elem, position)
    })
  }

  addDrag(document.getElementById('box1'), document)
  addDrag(document.getElementById('box2'), document)
</script>
</body>
</html>

可以看出, rxjs拥有极强的封装能力, 将状态和改变状态的行为隔离, 并且提供统一的流式事件和数据处理能力

添加延迟动画, 在mousedown时, 持续按住一段时间, 触发移动动画, 然后再进行移动, 禁止直接移动

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./rxjs.umd.js"></script>
  <style>
    .box {
      width: 50px;
      height: 50px;
      background: deepskyblue;
      position: relative;
    }

    .circle {
      /*border-radius: 50%;*/
      background: greenyellow;

    }

    .blink {
      animation: .5s linear blinking;
    }

    @keyframes blinking {
      0% {
        /*opacity: 1;*/
        transform: rotate(0);
      }
      25% {
        /*opacity: 0;*/
        transform: rotate(-30grad);
      }
      50% {
        /*opacity: 0;*/
        transform: rotate(0);
      }
      75% {
        /*opacity: 0;*/
        transform: rotate(30grad);
      }
      100% {
        /*opacity: 1;*/
        transform: translateZ(0);
      }
    }
  </style>
</head>
<body>

<div class="box" id="box1"></div>
<div class="box circle" id="box2"></div>

<script>
  const {range, fromEvent,of} = rxjs;
  const {map, mapTo, filter,delay,tap, throttleTime, debounceTime, repeat, switchMap, takeUntil} = rxjs.operators;

  function setPosition(elem, position) {
    elem.style['left'] = position.x + 'px'
    elem.style['top'] = position.y + 'px'
  }

  function getPosition(elem) {
    return {
      x: +elem.style.left.replace('px', ''),
      y: +elem.style.top.replace('px', ''),
    }
  }

  function addDrag(elem, container) {
    let mousedown = fromEvent(elem, 'mousedown')
    let mouseup = fromEvent(container, 'mouseup')
    let mousemove = fromEvent(container, 'mousemove')

    mousedown.pipe(
      switchMap(e => {
        let {x, y} = getPosition(elem)
        return of({
          clickX: e.x,
          clickY: e.y,
          initX: x,
          initY: y,
          clickTime: +new Date()
        })
      }),
      delay(200),
      tap(() => {
        console.log('move start')
        elem.classList.add("blink")
      }),
      takeUntil(mousemove),
      repeat(),
      switchMap(({clickX, clickY, initX, initY, clickTime}) => {
          console.log('tap2', elem.className)
          return mousemove.pipe(
            throttleTime(40),
            map(
              e => {
                let x = initX + e.x - clickX
                let y = initY + e.y - clickY
                let time = +new Date() - clickTime
                return {
                  x,
                  y,
                  time
                }
              }
            ),
          )
        }
      ),
      takeUntil(mouseup.pipe(
        tap(() => {
          console.log('move end')
          elem.classList.remove("blink")
        })
      )),
      repeat()
    ).subscribe(position => {
      console.log(position)
      setPosition(elem, position)
    })
  }

    addDrag(document.getElementById('box1'), document)
  addDrag(document.getElementById('box2'), document)
</script>
</body>
</html>

采用combine实现

 mousedown.pipe(
    switchMap(e => {
      let {x, y} = getPosition(box)
      return of({
        clickX: e.x,
        clickY: e.y,
        initX: x,
        initY: y,
        clickTime: +new Date()
      })
    }),
    delay(200),
    tap(() => {
      console.log('move start')
      box.classList.add("blink")
    }),
    takeUntil(mousemove),
    repeat(),
    switchMap(({clickX, clickY, initX, initY, clickTime}) => {
        console.log('tap2', box.className)
        return mousemove.pipe(
          throttleTime(40),
          map(
            e => {
              let x = initX + e.x - clickX
              let y = initY + e.y - clickY
              let time = +new Date() - clickTime
              return {
                x,
                y,
                time
              }
            }
          ),
        )
      }
    ),
    takeUntil(mouseup.pipe(
      tap(() => {
        console.log('move end')
        box.classList.remove("blink")

      })
    )),
    repeat()
  ).subscribe(position => {
    console.log(position)
    setPosition(box, position)
  })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值