'How to move an drag and drop item to a certain position, when located over canvas?

I am working on a Tablet-environment with draggable objects. The drag & drop works, it is even possible to drag several objects at once, when implemented.

References are :

Reference 1 & Reference 2

This is how the current version of my code looks like:

<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
    <meta 
     name='viewport' 
      content='width=50px, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,' 
     /> 
<!-- 

Refernces:
* https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Drag_and_Drop
* https://mobiforge.com/design-development/touch-friendly-drag-and-drop
-->
     
<style> 

#container {
  width: 200px;
  height: 200px;
  position: relative;
  background: yellow;
  top: 100px
}
  
main1 {
  position: relative;
  }

div1 {

  position: absolute;
  top: 0px;
  left: 100px;
  height: 72px;
  width: 72px;
  background: red;
  border: 0px solid #666;
  margin: 0;
  padding: 0;
} 

</style>  
  <title>Clean up</title>
</head>

<body>



<div id ="container">
</div> 
 
<main1 id="main1">
    <div1 class="draggable" id="d1-0""></div1>
</main1>

  
<script>

var nodeList = document.getElementsByClassName('draggable');
 
  for(var i=0;i<nodeList.length;i++) {
    var obj = nodeList[i];
    obj.addEventListener('touchmove', function(event) {
      var touch = event.targetTouches[0];
      
      // Place element where the finger is
      event.target.style.left = touch.pageX + 'px';
      event.target.style.top = touch.pageY + 'px';
      event.preventDefault();
    }, false);
  } 

</script>

</body>
</html>

The idea is, that the red box (div1) can be moved, dragged and dropped everywhere on the screen. But it needs to be moved to its very initial starting position, when it enters the yellow canvas. (The idea is to "clean up" and "move objects back to where they came from".)



Solution 1:[1]

You should use jQuery UI's draggable and touch punch for mobile friendliness

Let me know if this is close to what you're looking for and we can adjust as needed

$(document).ready(function() {
  $('#div1').draggable();
  $('#container').droppable({
    drop: function( event, ui ) {
       alert("You dropped the red on the yellow");
    }
  });
  $(document).on("click", "#animateBtn", function() {
    //Simple animate w/ just specifying the offsets
    //$('#div1').animate({top:"250px", left:"250px"});
    
    //Other animate options
    $('#div1').animate({
        top:"15px",
        left:"15px"
      }, {
        duration:555, //Animation time in pixels
        easing:"easeOutQuart"  //See https://api.jqueryui.com/easings/
      }); 
  });
});
#container {
  width: 200px;
  height: 200px;
  position: relative;
  background: yellow;
  top: 100px
}
  
body {
  position: relative;
}

#div1 {
  position: absolute;
  top: 0px;
  left: 100px;
  height: 72px;
  width: 72px;
  background: red;
  border: 0px solid #666;
  margin: 0;
  padding: 0;
}

#animateBtn {
  position:fixed;
  right:10px;
  bottom:10px;
  display:inline-block;
  padding:3px 5px;
  background-color:green;
  color:white;
  border-radius:6px
}
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
    <meta 
     name='viewport' 
      content='width=50px, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,' 
     /> 
  <title>Drag and Drop</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
</head>

<body>
  <div id="container"></div> 
  <div class="draggable" id="div1"></div>
  <div id="animateBtn">Animate</div>
</body>
</html>

Solution 2:[2]

<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
    <meta 
     name='viewport' 
      content='width=50px, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,' 
     /> 
  <title>Drag and Drop</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>


<style> 

#container {
  width: 200px;
  height: 200px;
  position: relative;
  background: yellow;
  top: 100px
}
  
body {
  position: relative;
}

#div1 {
  position: absolute;
  top: 100px;
  left: 100px;
  height: 72px;
  width: 72px;
  background: red;
  border: 0px solid #666;
  margin: 0;
  padding: 0;
}


</style>  
  <title>Clean up</title>
</head>

<body>

  <div id="container"></div> 
  <div class="draggable" id="div1"></div>
  <!--<div id="animateBtn">Animate</div>-->

<script>

$(document).ready(function() {
  $('#div1').draggable();
  $('#container').droppable({
    drop: function() {
    $('#div1').animate({top:"100px", left:"100px"});
    }
  });
 });
 


</script>

</body>
</html>

Solution 3:[3]

I didn't see a mention of jQuery but w3schools has a working example that goes without. Could you some touchup though:

/**
 * Make object draggable
 * @param {Element} element 
 */
const addDraggable = (element)=> {
    let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

  const dragMouseDown = e => {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    [pos3, pos4] = [e.clientX, e.clientY];
    document.onmouseup = closeDragElement;
    document.onmousemove = elementDrag;
  };

  const elementDrag = e => {
        console.log(e.clientX, e.clientY);
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    [pos1, pos2] = [pos3 - e.clientX, pos4 - e.clientY];
    [pos3, pos4] = [e.clientX, e.clientY];
    // set the element's new position:
    [element.style.top, element.style.left] = 
            [(element.offsetTop - pos2) + "px", (element.offsetLeft - pos1) + "px"];
  };

  const closeDragElement = _ => {
    // stop moving when mouse button is released:
    document.onmouseup = null;
    document.onmousemove = null;
  };

  element.onmousedown = dragMouseDown;
}

document.addEventListener("DOMContentLoaded", event=> {
  _('#logo-top').addEventListener('click', event=> {
    event.stopPropagation();
    _('#logo-top').classList.toggle('active');
    _('nav').forEach( n=> n.classList.toggle('collapsed') );
    _('main').classList.toggle('extended');
  });

    addDraggable( _('#help-text') );
    _( '#help' ).addEventListener( 'click', ()=>{ _('#help-text').classList.toggle('active')} );
    _( '#help-text-close' ).addEventListener( 'click', ()=>{_('#help-text').classList.toggle('active')}  );

});

Another way would be to use the Drag Operations

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 MelanieP
Solution 3 theking2