drag на SVG элементе

Вот такой кусок кода работает в хроме, но не всегда. Начинает движение если как-то с 3-5ого раза сдернуть красный кружок с места, а потом начинает работать нормально.

Вроде начинает работать узел когда его выделяешь в хроме "как текст".

<template>
  <div class="relative drop-zone">
    <img :src="image" class="absolute" />
    <svg class="absolute" @click="addpoint" width="100%" height="100%" style="z-index: 999;">
      <path v-if="points.length > 1" :d="`M ${points.map(p => `${p.x} ${p.y}`).join(' L ')} Z`"
        fill="rgba(0, 0, 255, 0.5)" stroke="blue" stroke-width="3" />


      <circle class="side" v-if="points.length > 1" r="10" fill="blue" v-for="(point, index) in points" :key="index"
        :cx="(point.x + (points[index + 1]?.x ?? points[0]?.x)) / 2"
        :cy="(point.y + (points[index + 1]?.y ?? points[0]?.y)) / 2" @click.stop.prevent="() => splitline(index)">

        <title>{{ index }}</title>

      </circle>


      <circle class="corner" v-for="(point, index) in points" :cx="point.x" :cy="point.y" r="10" fill="red"
        @click.prevent.stop="console.log('click')" @contextmenu.stop.prevent="() => { points.splice(index, 1); }"
        :title="index" @drag="dragPoint($event, index)" :key="index"
        
        pointer-events="all"
        
        >
        <title>{{ index }}</title>
      </circle>


    </svg>

  </div>
</template>

<script lang="ts" setup>


const points = ref<{ x: number, y: number }[]>([]);


function dragPoint(event: MouseEvent, index: number) {
  console.log('drag', event, index);
  points.value[index] = { x: event.offsetX, y: event.offsetY };
}


function addpoint(event: MouseEvent) {
  if (points.value.length < 4) {
    points.value.push({ x: event.offsetX, y: event.offsetY });
    return;
  }
}


function splitline(index: number) {

  if (index === points.value.length - 1) {
    points.value.push({ x: (points.value[index].x + points.value[0].x) / 2, y: (points.value[index].y + points.value[0].y) / 2 });
    return;
  }

  points.value.splice(index + 1, 0, { x: (points.value[index].x + points.value[index + 1]?.x) / 2, y: (points.value[index].y + points.value[index + 1]?.y) / 2 });
}


const image = ref<string>('');


function onFile(file: File) {
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      image.value = e.target?.result as string;
    };
    reader.readAsDataURL(file);
  }
}

document.addEventListener('dragover', (e) => {
  console.log('doc dragover');
  e.preventDefault()
});

document.addEventListener('drop', (e) => {
  if (e.dataTransfer?.files.length) {
    console.log(e.dataTransfer.files);
    onFile(e.dataTransfer.files[0]);
    e.preventDefault()
  }
});


</script>

<style>
html,
body {
  height: 100vh;
  margin: 0;
  display: flex;
}

.relative {
  position: relative;
}

.absolute {
  position: absolute;
}

.drop-zone {
  width: 100vw;
  height: 100vh;
  display: flex;
}

#file {
  display: none;
}

circle.side {
  cursor: copy;
}



circle.corner {
  cursor: move;
}
</style>

Если убрать картинку (таг) (даже пустую), то перестаёт работать вообще.

Хочу картинку внедрить в svg и чтоб узлы двигались сразу.

Как вариант конечно подвесить маленькие дивы на слой выше...


Ответы (1 шт):

Автор решения: eri

@drag не годится для перемещения объектов. @mousedown + @mousemove работают хорошо.

→ Ссылка