移动端实现拖拽效果

385 阅读1分钟

使用vue自定义指令实现移动端拖拽效果

<template>
  <div class="box">
    <div id="drag" v-drag="drag">
      <img src="../assets/logo.png" alt="" srcset="" />
    </div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  directives: {
    drag: {
      bind(el, binding) {
        binding.value(el);
      },
    },
  },
  props: {
    msg: String,
  },
  methods: {
    get_el_size(el) {
      // 获取元素大小
      return new Promise((resolve) => {
        let size = {
          width: 0,
          height: 0,
        };
        this.$nextTick(() => {
          size.width = el.offsetWidth;
          size.height = el.offsetHeight;
          resolve(size);
        });
      });
    },
    async drag(el) {
      let is_click = false;
      const size = await this.get_el_size(el);

      let clientWidth = document.body.clientWidth; // 可视窗口宽度
      let clientHeight = document.body.clientHeight; // 可视窗口高度

      let start = {
        x: 0,
        y: 0,
      };
      let move = {
        x: 0,
        y: 0,
      };
      let trans = {
        x: clientWidth - size.width,
        y: clientHeight / 2,
      };
      let disP = {
        x: 0,
        y: 0,
      };

      // 初始化元素位置
      el.style.transform = `translate(${trans.x}px, ${trans.y}px)`;

      el.addEventListener("touchstart", function (e) {
        is_click = true;
        e.preventDefault();
        disP.x = trans.x;
        disP.y = trans.y;

        // changedTouches  触发当前事件的手指列表
        start.x = e.changedTouches[0].clientX; // 获取鼠标 X 轴位置
        start.y = e.changedTouches[0].clientY; // 获取鼠标 Y 轴位置
      });
      el.addEventListener("touchmove", function (e) {
        is_click = false;
        move.x = e.changedTouches[0].clientX - start.x; // 鼠标移动  x轴  大小
        move.y = e.changedTouches[0].clientY - start.y; // 鼠标移动  y轴  大小

        trans.x = disP.x + move.x;
        trans.y = disP.y + move.y;

        // 边界处理
        if (trans.x >= clientWidth - size.width) {
          trans.x = clientWidth - size.width;
        } else if (trans.x <= 0) {
          trans.x = 0;
        }

        if (trans.y >= clientHeight - size.height) {
          trans.y = clientHeight - size.height;
        } else if (trans.y <= 0) {
          trans.y = 0;
        }

        el.style.transform = `translate(${trans.x}px, ${trans.y}px)`;
      });
      el.addEventListener("touchend", function (e) {
        if (is_click) {
          alert(111111);
        }
      });
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.box {
  background: #000;
}
#drag {
  position: fixed;
  // top: 0;
  // right: 0;
  width: 50px;
  height: 50px;
  overflow: hidden;
  background: red;
  border-radius: 10px;
  img {
    width: 100%;
    height: auto;
  }
}
</style>