Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get JqueryUI Sortable working with Zoom/Scale - mouse movements

I am trying to get Jquery UI Sortable working with the zoom. The issue is the mouse doesn't move with the same speed as the element you are dragging. There are quite a few examples posted about how to get this working with Draggable. Here is a example of the workaround for Draggable items:

http://jsfiddle.net/TqUeS/660/

var zoom = $('#canvas').css('zoom');
var canvasHeight = $('#canvas').height();
var canvasWidth = $('#canvas').width();

$('.dragme').draggable({
drag: function(evt,ui)
{
    // zoom fix
    ui.position.top = Math.round(ui.position.top / zoom);
    ui.position.left = Math.round(ui.position.left / zoom);

    // don't let draggable to get outside of the canvas
    if (ui.position.left < 0) 
        ui.position.left = 0;
    if (ui.position.left + $(this).width() > canvasWidth)
        ui.position.left = canvasWidth - $(this).width();  
    if (ui.position.top < 0)
        ui.position.top = 0;
    if (ui.position.top + $(this).height() > canvasHeight)
        ui.position.top = canvasHeight - $(this).height();  

}                 
});

I would expect the Drag event to be replaced by the Sort event in the Sortable version of this, but as you can see from the below fiddle, it doesn't work. Setting ui.position in the sort event has no effect - it seems to set it and discard it after the event fires.

http://jsfiddle.net/TqUeS/658/

var zoom = $('#canvas').css('zoom');
var canvasHeight = $('#canvas').height();
var canvasWidth = $('#canvas').width();

$('#canvas').sortable({
    items: "div",
sort: function(evt,ui)
{
    // zoom fix
    ui.position.top = Math.round(ui.position.top / zoom);
    ui.position.left = Math.round(ui.position.left / zoom);

    // don't let draggable to get outside of the canvas
    if (ui.position.left < 0) 
        ui.position.left = 0;
    if (ui.position.left + $(this).width() > canvasWidth)
        ui.position.left = canvasWidth - $(this).width();  
    if (ui.position.top < 0)
        ui.position.top = 0;
    if (ui.position.top + $(this).height() > canvasHeight)
        ui.position.top = canvasHeight - $(this).height();  

}                 
});

If anyone has another workaround, I'd be happy to hear it.

like image 349
Kelly W Avatar asked Jan 14 '16 12:01

Kelly W


1 Answers

Minor differences between draggable and sortable. In sort, the ui.helper is the item and position does not effect it in the same way, it's just a report of it's position.

For Draggable, in drag for ui.position, it states:

Current CSS position of the helper as { top, left } object. The values may be changed to modify where the element will be positioned. This is useful for custom containment, snapping, etc.

For Sortable, in sort for ui.position, it states:

The current position of the helper represented as { top, left }.

Try this:

Example: http://jsfiddle.net/Twisty/4nv60ob9/2/

HTML

<div id="canvas" data-zoom="0.5">
  <div class="dragme"></div>
  <div class="dragme"></div>
  <div class="dragme"></div>
</div>
<div id="report"></div>

JavaScript

var zoom = $("#canvas").data("zoom");
console.log(typeof zoom, zoom.toString());
var canvasHeight = $('#canvas').height();
var canvasWidth = $('#canvas').width();

$('#canvas').sortable({
  items: "div",
  start: function(e, ui) {
    console.log("Sort Start Triggered");
  },
  sort: function(evt, ui) {
    console.log("Sort Triggered");
    // zoom fix
    ui.position.top = Math.round(ui.position.top / zoom);
    ui.position.left = Math.round(ui.position.left / zoom);
    $("#report").html("Top: " + ui.position.top + " Left: " + ui.position.left);

    // don't let draggable to get outside of the canvas
    if (ui.position.left < 0) {
      ui.helper.css("left", 0);
    }
    if (ui.position.left + ui.helper.width() > canvasWidth) {
      ui.helper.css("left", (canvasWidth - ui.helper.width()) + "px");
    }
    if (ui.position.top < 0) {
      ui.helper.css("top", 0);
    }
    if (ui.position.top + ui.helper.height() > canvasHeight) {
      ui.helper.css("top", (canvasHeight - ui.helper.height()) + "px");
    }
    $("#report").html("Top: " + (canvasHeight - ui.helper.height()) + " Left: " + (canvasWidth - ui.helper.width()));
  }
});

I think that is working in the same way.

like image 159
Twisty Avatar answered Oct 23 '22 13:10

Twisty