2010-05-28 9 views
11

Estoy trabajando en una página en la que todos sus contenidos se escalan utilizando el zoom. El problema es que cuando arrastro algo en la página, el elemento que se arrastra obtiene una posición incorrecta que parece relativa a la cantidad del zoom.Jquery que se puede arrastrar con el problema de zoom

Para resolver esto traté de hacer algunos cálculos sobre la posición del componente que se puede arrastrar, pero parece que incluso si se corrige visualmente, la posición "verdadera" no se vuelve a calcular.

Aquí hay un código para explicar mejor:

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); 

Cualquier ayuda sería muy apreciada

Respuesta

0

¿Está tomando la posición de desplazamiento, margen y el relleno en cuenta? Tales como:

x.left + 
parseInt($(this).css('margin-left')) + 
parseInt($(this).css('padding-left')) + 
parseInt($(this).parent().scrollLeft()); 

x.top + 
parseInt($(this).css('margin-top')) + 
parseInt($(this).css('padding-top')) + 
parseInt($(this).parent().scrollTop()); 

¿Luego ajustando el valor del zoom según sea necesario?

+0

la caclulation es buena, el valor de regresar de desplazamiento() superior está mal cuando el zoom no es 1.0 –

12

Tomé mucho tiempo y esfuerzo para solucionar esto, pero finalmente, tengo una solución que funciona.

Esta solución funciona tanto para Firefox como para IE. #canvas es el div que contiene el arrastrable. Tenga en cuenta que debemos asegurarnos de que los elementos permanezcan dentro del lienzo de forma manual.

Esto también funciona si el lienzo tiene un nivel de zoom diferente que el resto de la página.

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); 
    } 
}); 
+0

¿Puede proporcionar un enlace jsFiddle que ¿trabajos? lo agradeceríamos en la pregunta 8605439 –

+1

Parece que alguien ya ha copiado mi código a esa pregunta. :-) – torke1

+0

Tengo el mismo problema. ¿El zoom es un porcentaje o el valor real? –

2

Para referencia futura - si alguna vez alguien se tropieza con el mismo problema - una pregunta similar + respuesta de trabajo se puede encontrar here.

0

Estuve luchando con esto durante algunas horas. Tenía una grilla donde comencé con escalar estableciendo el tamaño de fuente (125% etc. en el contenedor). Esto funcionó bien hasta que entré en imágenes que no se escalaron con la cuadrícula.

Pensé que usaría el zoom en su lugar y funcionó brillantemente. Luego volví a tener en cuenta que arrastrable/droppable no estaba escalando con él hmm .. Pasé varias horas intentando destruir y reiniciar los objetos jqueryUI pero nada funcionó.

Entonces, finalmente me di cuenta de que podía usar una combinación de tamaño de letra para hacer zoom en la cuadrícula y css-zoom para las imágenes. Ahora todo funciona y puedo arrastrar/soltar con la misma instancia de jQueryUI.

Espero que este enfoque ayude a alguien más. :-)

0
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);  
     }     
    }); 
0

Si CSS zoom se realiza específicamente en el cuerpo HTML, hay una solución muy fácil, pero sí requiere que modifique la fuente. Eso es un no-ir para algunos, pero voy a publicar la solución aquí de todos modos.

Así que la funcionalidad de la jQuery UI determina la posición de la mouse usando un método llamado _generatePosition. El problema es que no tiene en cuenta el zoom (duh), por lo que simplemente tenemos que dividir su resultado por el nivel de zoom y todo funcionará.

Así girar esto:

return { 
     top: (

      // The absolute mouse position 
      pageY - 

      // Click offset (relative to the element) 
      this.offset.click.top - 

      // Only for relative positioned nodes: Relative offset from element to offset parent 
      this.offset.relative.top - 

      // The offsetParent's offset without borders (offset + border) 
      this.offset.parent.top + 
      (this.cssPosition === "fixed" ? 
       -this.offset.scroll.top : 
       (scrollIsRootNode ? 0 : this.offset.scroll.top)) 
     )/ , 
     left: (

      // The absolute mouse position 
      pageX - 

      // Click offset (relative to the element) 
      this.offset.click.left - 

      // Only for relative positioned nodes: Relative offset from element to offset parent 
      this.offset.relative.left - 

      // The offsetParent's offset without borders (offset + border) 
      this.offset.parent.left + 
      (this.cssPosition === "fixed" ? 
       -this.offset.scroll.left : 
       (scrollIsRootNode ? 0 : this.offset.scroll.left)) 
     ) 
    }; 

en

var zoomLevel = parseFloat($('body').css("zoom") || "1.0"); 

    return { 
     top: (

      // The absolute mouse position 
      pageY - 

      // Click offset (relative to the element) 
      this.offset.click.top - 

      // Only for relative positioned nodes: Relative offset from element to offset parent 
      this.offset.relative.top - 

      // The offsetParent's offset without borders (offset + border) 
      this.offset.parent.top + 
      (this.cssPosition === "fixed" ? 
       -this.offset.scroll.top : 
       (scrollIsRootNode ? 0 : this.offset.scroll.top)) 
     )/zoomLevel, 
     left: (

      // The absolute mouse position 
      pageX - 

      // Click offset (relative to the element) 
      this.offset.click.left - 

      // Only for relative positioned nodes: Relative offset from element to offset parent 
      this.offset.relative.left - 

      // The offsetParent's offset without borders (offset + border) 
      this.offset.parent.left + 
      (this.cssPosition === "fixed" ? 
       -this.offset.scroll.left : 
       (scrollIsRootNode ? 0 : this.offset.scroll.left)) 
     )/zoomLevel 
    }; 

eso es todo. Sugiero guardarlo bajo un nombre específico para que se reconozca fácilmente que ha sido modificado. Por ejemplo: jquery-ui.ZOOMFIX.js

que utiliza el archivo jquery-ui.js del siguiente paquete:. https://jqueryui.com/resources/download/jquery-ui-1.12.1.zip

+0

¿Cómo esta respuesta se relaciona con la pregunta? – sg7

+0

@ sg7 OP está pidiendo una solución para el arrastre mal ubicado con jQuery UI. Mi respuesta proporciona una solución para arreglar el arrastre mal posicionado con jQuery UI. Synce, mi respuesta responde a la pregunta, creo que es lo suficientemente relevante. – kragovip

Cuestiones relacionadas