技术就餐

导航

利用插槽写屏幕按钮随意拖动控件,页面滚动消失,停止显示

<template>
  <transition>
    <div ref="dragIcon"
         class="drag-icon-wrapper"
         @touchstart="handleTouchStart"
         @touchmove.prevent="handleTouchMove"
         @touchend="handleTouchEnd"
         :style="{left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px'}"
         v-if="isShow"
    >
      <slot></slot>
    </div>
  </transition>
</template>

<script>
export default {
  name: 'drag-icon',
  props: {
    itemWidth: {
      type: Number,
      default: 60
    },
    itemHeight: {
      type: Number,
      default: 60
    }
  },
  data () {
    return {
      left: 5,
      top: 0,
      startToMove: false,
      isShow: true,
      timer: null,
      currentTop: null,
      clientW: document.documentElement.clientWidth,
      clientH: document.documentElement.clientHeight
    }
  },
  created () {
    this.left = (this.clientW - this.itemWidth - 5)
    // this.top = (this.clientH / 2 - this.itemHeight / 2)
    this.top = (this.clientH - this.itemHeight*3)
  },
  mounted () {
    this.bindScrollEvent()
  },
  beforeDestroy () {
    // 记得销毁一些全局的的事件
    this.removeScrollEvent()
  },
  methods: {
    handleTouchStart () {
      this.startToMove = true
      this.$refs.dragIcon.style.transition = 'none'
    },
    handleTouchMove (e) {
      const clientX = e.targetTouches[0].clientX
      const clientY = e.targetTouches[0].clientY
      const isInScreen = clientX <= this.clientW && clientX >= 0 && clientY <= this.clientH && clientY >= 0
      if (this.startToMove && e.targetTouches.length === 1) {
        if (isInScreen) {
          this.left = clientX - this.itemWidth / 2
          this.top = clientY - this.itemHeight / 2
        }
      }
    },
    handleTouchEnd () {
      if (this.left < (this.clientW / 2)) {
        this.left = 5
        this.handleIconY()
      } else {
        this.left = this.clientW - this.itemWidth - 5
        this.handleIconY()
      }
      this.$refs.dragIcon.style.transition = 'all .3s'
    },
    handleIconY () {
      if (this.top < 0) {
        this.top = 0
      } else if (this.top + this.itemHeight > this.clientH) {
        this.top = this.clientH - this.itemHeight
      }
    },
    bindScrollEvent () {
      window.addEventListener('scroll', this.handleScrollStart)
    },
    removeScrollEvent () {
      window.removeEventListener('scroll', this.handleScrollStart)
    },
    handleScrollStart () {
      this.isShow = false
      this.timer && clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.handleScrollEnd()
      }, 300)
      this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
    },
    handleScrollEnd () {
      this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      // 判断是否停止滚动的条件
      if (this.scrollTop === this.currentTop) {
        this.isShow = true
      }
    }
  }
}
</script>

<style scoped lang="scss">
.drag-icon-wrapper {
  position: fixed;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-image: linear-gradient(180deg, #F7AB98 0%, #F49A87 6%, #ED725F 65%);
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  z-index: 100;
}

.v-enter {
  opacity: 1;
}
.v-leave-to {
  opacity: 0;
}
.v-enter-active,
.v-leave-active {
  transition: opacity 0.3s;
}
</style>

posted on 2021-10-22 11:46  技术就餐  阅读(46)  评论(0编辑  收藏  举报