0

I have created a fiddle here that you can play with: http://codepen.io/anon/pen/pvOKey

I want to center the dragged object vertically/horizontally to the cursor that means when I drag an object at its corners I want then that the object is centered under the cursor else the user experience is very bad dragging large objects.

I have googled for SO solutions and found some but they do not work.

I use the create function of a draggable to set the top/left position , but it does not work.

Anyone can help?

<div id="itemContainer1"> 
  <div class="item i2">2</div>
</div>

<div id="itemContainer2"> 
  <div class="item i4">4</div>
</div>


<!-- border-box => IE9+ -->
* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

body, html { 
  padding:0;
  margin:0;
  height:100%; 
}

.start-dragging{
  transform: scale(0.25); /* Standard syntax */
  transition: transform .3s ease-out; 
}
.stop-dragging{
  transform: scale(1); /* Standard syntax */
  transition: transform .3s ease-out; 
}


.item{
  position:absolute; 
} 

#itemContainer1{
  background:green;
  height:100%; 
  position:relative; 
  right:50%;

}

#itemContainer2{
  background:blue;
  height:100%; 
  width:50%;
  position:relative; 
  left:50%;
  top:-100%;

}
.item.i2 {
  top:50%;
  left:50%;
   width: 44%; 
   height:44%;
   background:lightgreen;  
}

.align-vertical-colums {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}



$(document).ready(function () {
    $("#itemContainer1 > div").each(function (index, element) {

      $(element).addClass("stop-dragging"); 

      $(element).draggable({cursor: 'move', stack: ".item",helper: "original",
        create: function(e,x){
          $(this).draggable("option", "cursorAt", {
                 left: Math.floor(ui.helper.width() / 2),
                 top: Math.floor(ui.helper.height() / 2)
               }); 
        },

                            start: function() {

           // $(this).css({"z-index": 100000 }); // the highest z-index
            $(this).toggleClass( 'stop-dragging start-dragging');
          },
          drag: function() {
          },
          stop: function() {
           //  $(this).css("z-index", ''); // remove the z-index
              $(this).toggleClass( 'start-dragging stop-dragging');

          }
       });   

        $(element).addClass("align-vertical-colums");
    });

  $("#itemContainer1").droppable({       
        activeClass: "ui-state-hover",
        hoverClass: "ui-state-active",
        drop: function (event, ui) {
     var element = document.elementFromPoint(event.clientX, event.clientY);        

        }
    });
});
Pascal
  • 12,265
  • 25
  • 103
  • 195

2 Answers2

2

I think you're having a problem finding ui.helper, if you check the console you will see that message:

Uncaught ReferenceError: ui is not defined

I edited your code and used only width() and height() functions of JQuery, and it seems to work. Check it out on this CodePen

Edited: Also you have to included the cursorAt option inside the drag callback, in order to update width() and height() in case of resizing window.

drag: function(e,x){
    addCursorAtOption(this);
}

function addCursorAtOption(element){
    $(element).draggable("option", "cursorAt", {
      left: $(element).width()/2,
      top: $(element).height()/2
    }); 
  }

For dealing with resizing screen problem, you could call the function addCursorAtOption on window resize callback, check this CodePen

create: function(e,x){
    var self = this;
    $(window).resize(function() {
       addCursorAtOption(self);
    });
    addCursorAtOption(self);
}
jmartins
  • 991
  • 4
  • 16
  • It works! but only on the codepen :/ In my prod env. with complicated layout etc... the init drag problem remains :/ Any idea? I used your latest code! with the window resize! – Pascal Mar 09 '15 at 13:38
  • In this case, the question you answered was solved. Now, you should either create another question with the actual code you need help with (cause you're probably having another issue) or update this question. You should also detail any other library you're using into prod env. like bootstrap, etc. It could be related to that. – jmartins Mar 09 '15 at 13:41
  • 1
    Thanks for the help. Never was a help better but in the end I gotta figure it out :( – Pascal Mar 09 '15 at 13:43
0

The problem here is the event you addresses. create: function() this doesn't work. You need to use the drag function.

     drag: function( e,ui) {
        $(element).draggable("option", "cursorAt", {
             left: Math.floor(ui.helper.width() / 2),
             top: Math.floor(ui.helper.height() / 2)
           });
      },

also you used ui without specifying it in the function statements, and you used this instead of here used element. Replace this in your code where you have currently

drag: function() {
      },` 

and it works as you desire.

Edwin Krause
  • 1,766
  • 1
  • 16
  • 33
  • I considered your comments and here is the changed pen: http://codepen.io/anon/pen/vEzaGB I can not drag the draggable anymore due to: console error: Uncaught Error: cannot call methods on draggable prior to initialization; attempted to call method 'option' – Pascal Mar 09 '15 at 13:20
  • You cant double use the `element` Please leave the function as I wrote with `(e,ui)` then it works as a charm. `drag: function(e, ui) {` – Edwin Krause Mar 09 '15 at 14:01
  • Where do I double use element? sorry do not understand you. – Elisabeth Mar 10 '15 at 09:35
  • Just change `drag: function(element, ui) {` to `drag: function(e, ui) {` in your http://codepen.io/anon/pen/vEzaGB :-) – Edwin Krause Mar 10 '15 at 15:21