JSFiddle - React, Tailwind, and code Playground

by Marcos vini

HTML

<div class="drop-area" id="dropArea">
        <!-- Aqui as imagens serão colocadas arrastando e soltando -->
    </div>
    
    <div class="image-list">
        <img class="draggable-image" src="https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492_1280.jpg" data-id="gato">
        <img class="draggable-image" src="https://cdn.pixabay.com/photo/2018/03/31/06/31/dog-3277416_1280.jpg" data-id="cachorro">
        <img class="draggable-image" src="https://cdn.pixabay.com/photo/2012/06/19/10/32/owl-50267_1280.jpg" data-id="outra">
    </div>

CSS

.drop-area {
            width: 400px;
            height: 400px;
            border: 2px dashed #ccc;
            position: relative;
        }
        
        .draggable-image {
            width: 100px;
            height: 100px;
            border: 1px solid #999;
            cursor: pointer;
            position: absolute;
        }
        
        .image-list {
            display: flex;
            justify-content: space-around;
            margin-top: 20px;
        }

JavaScript

const dropArea = document.getElementById('dropArea');
        const draggableImages = document.querySelectorAll('.draggable-image');

        draggableImages.forEach(image => {
            image.addEventListener('dragstart', handleDragStart);
        });

        dropArea.addEventListener('dragover', handleDragOver);
        dropArea.addEventListener('drop', handleDrop);

        function handleDragStart(e) {
            e.dataTransfer.setData('text/plain', e.target.dataset.id);
        }

        function handleDragOver(e) {
            e.preventDefault();
        }

        function handleDrop(e) {
            e.preventDefault();
            const dataId = e.dataTransfer.getData('text/plain');
            const image = document.querySelector(`[data-id="${dataId}"]`);

            const newImage = image.cloneNode(true);
            newImage.classList.remove('draggable-image');
            newImage.style.left = `${e.clientX - dropArea.getBoundingClientRect().left}px`;
            newImage.style.top = `${e.clientY - dropArea.getBoundingClientRect().top}px`;

            dropArea.appendChild(newImage);
        }