Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery draggable with zoom problem

I am working on a page in witch all its contents are scaled by using zoom. The problem is that when I drag something in the page the dragging item gets a bad position that seems relative to the zoom amount.

To solve this I tried to do some math on the position of the draggable component, but seems that even tho visually its corrected, the "true" position its not recalculated.

here is some code to explain better:

var zoom = Math.round((parseFloat($("body").css("zoom")) / 100)*10)/10;

var x = $(this).data('draggable').position;
$(this).data('draggable').position.left = Math.round(x.left/zoom);
$(this).data('draggable').position.top = Math.round(x.top/zoom);

Any help would be greatly appreciated

like image 377
Manuel Avatar asked May 28 '10 15:05

Manuel


People also ask

Why is draggable not working?

You have one of these problems: Your jQuery or jQuery UI Javascript path files are wrong. Your jQuery UI does not include draggable. Your jQuery or jQuery UI Javascript files are corrupted.

Does jQuery draggable work on mobile?

jQuery UI wasn't originally written to handle mobile devices. It won't even play nicely with jQuery Mobile. some parts of it may still work well in mobile devices, but anything that has anything to do with dragging will fail.

What is jQuery draggable?

jQueryUI provides draggable() method to make any DOM element draggable. Once the element is draggable, you can move that element by clicking on it with the mouse and dragging it anywhere within the viewport.


2 Answers

Took a lot of time and effort to fix this, but finally, I have a solution that works.

This solution works for both Firefox and IE. #canvas is the div that contains the draggable. Note that we have to make sure the elements stays inside the canvas manually.

This also works if if canvas has a different zoom level than the rest of the page.

var pointerX;
var pointerY;
$(c).draggable({
  start : function(evt, ui) {
    pointerY = (evt.pageY - $('#canvas').offset().top) / zoom - parseInt($(evt.target).css('top'));
    pointerX = (evt.pageX - $('#canvas').offset().left) / zoom - parseInt($(evt.target).css('left'));
  },
  drag : function(evt, ui) {
    var canvasTop = $('#canvas').offset().top;
    var canvasLeft = $('#canvas').offset().left;
    var canvasHeight = $('#canvas').height();
    var canvasWidth = $('#canvas').width();

    // Fix for zoom
    ui.position.top = Math.round((evt.pageY - canvasTop) / zoom - pointerY); 
    ui.position.left = Math.round((evt.pageX - canvasLeft) / zoom - pointerX); 

    // Check if element is outside 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();  

    // Finally, make sure offset aligns with position
    ui.offset.top = Math.round(ui.position.top + canvasTop);
    ui.offset.left = Math.round(ui.position.left + canvasLeft);
  }
});
like image 183
torke1 Avatar answered Nov 10 '22 01:11

torke1


var zoom = $('#canvas').css('zoom');    
$('#dragme').draggable({
        drag: function(evt,ui)
        {
             var factor = (1 / zoom) -1);

             ui.position.top += Math.round((ui.position.top - ui.originalPosition.top) * factor);
             ui.position.left += Math.round((ui.position.left- ui.originalPosition.left) * factor);    
        }                 
    });
like image 26
Yusuf Demirag Avatar answered Nov 10 '22 02:11

Yusuf Demirag