Search code examples
javascripthtmlimagedrag-and-drop

How to change an image when a moveable element touches it?


I want to create a function so that when an object(img1) is on img2a it will make it turn into img2b. I have to pieces of code that do the 2 things separately by I can't seem to combine them.

I found the code for changing the image (bellow)

<img id="myImg" src="image1.jpg">
<button id="myButton">Change Image</button>
// JavaScript code
const myImg = document.getElementById("myImg");
const myButton = document.getElementById("myButton");

myButton.addEventListener("click", function() {
  myImg.src = "image2.jpg";
});

and I have the code to move the object (bellow)

     <img src="https://en.js.cx/clipart/soccer-gate.svg" id="gate" class="droppable">
   
     <img src="https://en.js.cx/clipart/ball.svg" id="ball">
   
     <script>
       let currentDroppable = null;
   
       ball.onmousedown = function(event) {
   
         let shiftX = event.clientX - ball.getBoundingClientRect().left;
         let shiftY = event.clientY - ball.getBoundingClientRect().top;
   
         ball.style.position = 'absolute';
         ball.style.zIndex = 1000;
         document.body.append(ball);
   
         moveAt(event.pageX, event.pageY);
   
         function moveAt(pageX, pageY) {
           ball.style.left = pageX - shiftX + 'px';
           ball.style.top = pageY - shiftY + 'px';
         }
   
         function onMouseMove(event) {
           moveAt(event.pageX, event.pageY);
   
           ball.hidden = true;
           let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
           ball.hidden = false;
   
           if (!elemBelow) return;
   
           let droppableBelow = elemBelow.closest('.droppable');
           if (currentDroppable != droppableBelow) {
             if (currentDroppable) { // null when we were not over a droppable before this event
               leaveDroppable(currentDroppable);
             }
             currentDroppable = droppableBelow;
             if (currentDroppable) { // null if we're not coming over a droppable now
               // (maybe just left the droppable)
               enterDroppable(currentDroppable);
             }
           }
         }
   
         document.addEventListener('mousemove', onMouseMove);
   
         ball.onmouseup = function() {
           document.removeEventListener('mousemove', onMouseMove);
           ball.onmouseup = null;
         };
   
       };
   
       function enterDroppable(elem) {
         elem.style.background = 'pink';
       }
   
       function leaveDroppable(elem) {
         elem.style.background = '';
       }
   
       ball.ondragstart = function() {
         return false;
       };
     </script>
   
   
   </body>
   </html>

I would appreciate any and all help I could get. Specifically what I am looking for is help with the attribute used as instead of a color change I want an image change I've tried a couple of thing like img but it hasn't worked yet.


Solution

  • Based on your description, I changed your code and you can see the result in the sample code which I've provided for you.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <img src="https://en.js.cx/clipart/soccer-gate.svg" style="width: 100px;" id="gate" class="droppable">
    
        <img src="https://en.js.cx/clipart/ball.svg" id="ball">
    
        <script>
            let currentDroppable = null;
            let gateAddr = "https://en.js.cx/clipart/soccer-gate.svg";
    
            ball.onmousedown = function(event) {
    
                let shiftX = event.clientX - ball.getBoundingClientRect().left;
                let shiftY = event.clientY - ball.getBoundingClientRect().top;
    
                ball.style.position = 'absolute';
                ball.style.zIndex = 1000;
                document.body.append(ball);
    
                moveAt(event.pageX, event.pageY);
    
                function moveAt(pageX, pageY) {
                    ball.style.left = pageX - shiftX + 'px';
                    ball.style.top = pageY - shiftY + 'px';
                }
    
                function onMouseMove(event) {
                    moveAt(event.pageX, event.pageY);
    
                    ball.hidden = true;
                    let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
                    ball.hidden = false;
    
                    if (!elemBelow) return;
    
                    let droppableBelow = elemBelow.closest('.droppable');
                    if (currentDroppable != droppableBelow) {
                        if (currentDroppable) { // null when we were not over a droppable before this event
                            leaveDroppable(currentDroppable);
                        }
                        currentDroppable = droppableBelow;
                        if (currentDroppable) { // null if we're not coming over a droppable now
                            // (maybe just left the droppable)
                            enterDroppable(currentDroppable);
                        }
                    }
                }
    
                document.addEventListener('mousemove', onMouseMove);
    
                ball.onmouseup = function() {
                    document.removeEventListener('mousemove', onMouseMove);
                    ball.onmouseup = null;
                };
    
            };
    
            function enterDroppable(elem) {
                elem.src = "https://www.svgrepo.com/download/116991/goal-label.svg";
            }
    
            function leaveDroppable(elem) {
                elem.src = gateAddr;
            }
    
            ball.ondragstart = function() {
                return false;
            };
        </script>
    </body>
    
    </html>

    Good Luck!