Search code examples
javascripthtmlvue.jsdrag-and-dropdraggable

Drag n drop in block area


I ran into this problem and don't know how to solve it. I need to drag and drop a point inside the map and save its new coordinates relative to the map.

Let's say I have a layout like in the picture I've attached. How can I get information about exactly where x or y in relation to this map I moved the element? I really need help!

I'm using HTML Drag And Drop, but I don't understand how to use the data that the event gives me to calculate thisenter image description here


Solution

  • After many attempts, I found a solution. My code turned out like this. This way I keep the position of my points within my map!

    P.S. I used Vue.js. Hope it's can help somebody.

    <div class="map">
      <div>
          <img :src="props.currentItem.map_image" alt="Map" />
        </div>
        <div
          @drop.prevent="onDrop($event)"
          @dragenter.prevent
          @dragover.prevent
          class="map__container map__dropzone"
        >
          <map-item
            v-for="item in itemsData"
            :class="[`item-${item.id}`, { editable: props.isEditMapMode }]"
            :key="item.id"
            draggable
            @dragstart="startDrag($event, sensor)"
          />
      </div>
    </div>
    
    const offsetX = ref(0);
    const offsetY = ref(0);
    
    const startDrag = (event: DragEvent, item: IItemInterface) => {
      const rect = (event.target as HTMLElement).getBoundingClientRect();
    
      offsetX.value = event.clientX - rect.x;
      offsetY.value = event.clientY - rect.y;
    
      if (event.dataTransfer) {
        event.dataTransfer.dropEffect = 'move';
        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData('itemId', item.id.toString());
      }
    };
    
    const onDrop = (event: DragEvent) => {
      const dropZoneRect = (event.target as HTMLElement).getBoundingClientRect();
      const left = dropZoneRect.left;
      const top = dropZoneRect.top;
    
      const itemId = event.dataTransfer?.getData('itemId');
      const item = document.querySelector(`.item-${itemId}`);
    
      (sensor as HTMLElement).style.left =
        event.clientX - left - offsetX.value + 'px';
    
      (sensor as HTMLElement).style.top =
        event.clientY - top - offsetY.value + 'px';
    };