Centering dragged elements inside a droppable using jquery-ui

Below is an example of what I've been able to achieve so far ...

$(document).ready(function() {
  $(".item").draggable({
    revert: 'invalid',
    snapMode: 'inner',
    scroll: false,
    stack: false,
    drag: function(event, ui) {
      $(".droparea").removeClass("highlight");
    }
  });
  $(".droparea").droppable({
    tolerance: 'intersect',
    drop: function(event, ui) {
      var drop_el = $(this).offset();
      var drag_el = ui.draggable.offset();
      var left_end = (drop_el.left + ($(this).width() / 2)) - (drag_el.left + (ui.draggable.width() / 2));
      var top_end = (drop_el.top + ($(this).height() / 2)) - (drag_el.top + (ui.draggable.height() / 2));
      $(this).addClass("highlight").find("p");
      ui.draggable.animate({
        top: '+=' + top_end,
        left: '+=' + left_end
      });
    }
  });
});
      

.item {
  position: relative;
  margin: 0 auto;
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin-top: 50%;
  top: -50px
}
.droparea {
  width: 150px;
  height: 150px;
  float: left;
  margin: 10px;
  border: 1px solid #000;
}
.highlight {
  border: 1px solid blue
}
      

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.js"></script>

<div class="droparea">
  <div class="item"></div>
</div>

<div class="droparea">

</div>
      

Run codeHide result


Sometimes it refuses to center the div.item div. The tag .item

needs to be dragged to the inside of the element .droparea

, otherwise it will not center the element .item

after dropping the element. Just wondering if there is an even more elegant way to make the draggable div centered on the nearest droppable element.

+3


source to share


2 answers


You can use the jQuery UI built-in position()

to center the dropped element like this:



$(document).ready(function() {
  $(".item").draggable({
    scroll: false,
    revert: 'invalid',
    stack: false,
    cursor: "pointer",
    drag: function(event, ui) {
      $(".droparea").removeClass("highlight");
    }
  });
  $(".droparea").droppable({
    accept: ".item",
    drop: function(event, ui) {
      var $this = $(this);
      $(".highlight").removeClass("highlight");
      $this.addClass("highlight");
      ui.draggable.position({
        my: "center",
        at: "center",
        of: $this,
        using: function(pos) {
          $(this).animate(pos, "slow", "linear");
        }
      });
    }
  });
});
      

.item {
  position: relative;
  margin: 0 auto;
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
.droparea {
  width: 150px;
  height: 150px;
  float: left;
  margin: 2px;
  border: 1px solid #000;
  outline: 1px solid transparent
}
.highlight {
  border: 1px solid blue
}
      

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.js"></script>

<div class="droparea">
  <div class="item"></div>
</div>


<div class="droparea"></div>
<div class="droparea"></div>
      

Run codeHide result


+3


source


I found a solution in this section, apologizing for the duplicate question.

How do I get jquery to center an element while dragging and snapping to another container?

So, in this case, the solution will look like this:



$( document ).ready(function() {
	$( ".item" ).draggable({
		scroll: false,
		revert: 'invalid',
		stack: false,
		create: function(){$(this).data('position',$(this).position())},
		cursor: "pointer",
		start:function(){$(this).stop(true,true)},
		drag: function(event, ui)
		{
			$( ".droparea" ).removeClass( "highlight" );
		}
	});
	$( ".droparea" ).droppable({
		accept: ".item",
		drop: function( event, ui ) {
			$( this ).addClass( "highlight" ).find( "p" );
			snapToMiddle(ui.draggable,$(this));
		}
	});
});

function snapToMiddle(dragger, target){
    var topMove = target.position().top - dragger.data('position').top + (target.outerHeight(true) - dragger.outerHeight(true)) / 2;
    var leftMove= target.position().left - dragger.data('position').left + (target.outerWidth(true) - dragger.outerWidth(true)) / 2;
    dragger.animate({top:topMove,left:leftMove},{duration:200,easing:'linear'});
}
      

.item { position: relative; margin: 0 auto; width: 100px; height: 100px; border: 1px solid red;}
.droparea { width: 150px; height: 150px; float: left; margin: 2px; border: 1px solid #000; outline: 1px solid transparent}
.highlight {border: 1px solid blue}
      

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.js"></script>

<div  class="droparea">
	<div class="item"> </div> 
</div>


<div class="droparea"> </div>
<div class="droparea"> </div>
      

Run codeHide result


+1


source







All Articles