vue3 hook 小球拖拽

vue3 hook 小球拖拽

先用react试了下, 搞了几个小时都没做出来想要的样子, 用vue3半个小时弄好了

react很多时候你觉得这么做没问题, 但是当你写了代码就会出问题, vue很多时候很符合直觉, 就算出错了, 也能根据经验和直觉快速定位

也可能是react用的太少, 毕竟也就不到一个月….

 

<template>
  <div ref="startRef" class="box"></div>
  <div ref="endRef" class="box"></div>
  <svg class="svg">
    <line
      class="line"
      :x1="linePosition.x1"
      :x2="linePosition.x2"
      :y1="linePosition.y1"
      :y2="linePosition.y2"
    ></line>
  </svg>
</template>

<script>
import { ref, onMounted, reactive, onUpdated, watch, computed } from "vue";

const useDrag = (dom, positionRef) => {
  let mouseStart = reactive({ x: 0, y: 0 });
  const { x, y, width, height } = dom.getBoundingClientRect();
  let domStart = reactive({ x, y });
  const down = ({ pageX, pageY }) => {
    console.log("down");
    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", up);
    const { x, y } = dom.getBoundingClientRect();
    domStart = { x, y };
    mouseStart = { x: pageX, y: pageY };
  };

  const up = () => {
    console.log("up");
    document.removeEventListener("mousemove", move);
    document.removeEventListener("mouseup", up);
  };

  const move = ({ pageX, pageY }) => {
    const nx = domStart.x + pageX - mouseStart.x;
    const ny = domStart.y + pageY - mouseStart.y;
    dom.style.left = nx + "px";
    dom.style.top = ny + "px";
    positionRef.value = {
      x: nx + width / 2,
      y: ny + height / 2,
    };
    console.log("move");
  };
  positionRef.value = {
    x: x + width / 2,
    y: y + height / 2,
  };
  dom.addEventListener("mousedown", down);
};

export default {
  name: "A",
  setup() {
    const startRef = ref(null);
    const endRef = ref(null);
    const startPositionRef = ref({ x: 0, y: 0 });
    const endPositionRef = ref({ x: 0, y: 0 });
    onMounted(() => {
      useDrag(startRef.value, startPositionRef);
      useDrag(endRef.value, endPositionRef);
    });

    watch([startPositionRef, endPositionRef], () => {
      console.log("position changed");
    });

    const linePosition = computed(() => {
      return {
        x1: startPositionRef.value.x,
        y1: startPositionRef.value.y,
        x2: endPositionRef.value.x,
        y2: endPositionRef.value.y,
      };
    });

    return {
      startRef,
      endRef,
      linePosition,
    };
  },
};
</script>

<style>
body,
html {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
}

.box {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  position: absolute;
  cursor: pointer;
  background: black;
  user-select: none;
}

.svg {
  width: 100vw;
  height: 100vh;
}

.line {
  stroke: deeppink;
  stroke-width: 2px;
}
</style>

 

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » vue3 hook 小球拖拽