Jquery可拖动与缩放问题

时间:2010-05-28 15:01:05

标签: javascript css jquery-ui zoom

我正在处理一个页面,其所有内容都通过缩放来缩放。 问题是当我在页面中拖动某些东西时,拖动项会得到一个看似相对于缩放量的坏位置。

为了解决这个问题,我尝试对可拖动组件的位置进行一些数学计算,但是看起来甚至在视觉上它的修正,“真实”位置都没有重新计算。

这里有一些代码可以更好地解释:

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

非常感谢任何帮助

6 个答案:

答案 0 :(得分:16)

花了很多时间和精力来解决这个问题,但最后,我有一个有效的解决方案。

此解决方案适用于Firefox和IE。 #canvas是包含draggable的div。请注意,我们必须确保元素手动保留在画布内。

如果画布的缩放级别与页面的其他部分不同,这也适用。

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

答案 1 :(得分:2)

供将来参考 - 如果有人遇到同样的问题 - 可以找到类似的问题+工作答案here

答案 2 :(得分:1)

如果专门在html主体上执行CSS Zoom,则有一个非常简单的修复,但它确实需要您修改源。对某些人来说这是不行的,但无论如何我都会在这里发布解决方案。

因此,jQuery UI的可拖动功能使用名为_generatePosition的方法计算出鼠标位置。问题是它不需要考虑缩放(duh),所以我们只需要将其结果除以缩放级别,一切都会有效

转过来:

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

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

这就是全部。我建议将其保存在特定名称下,以便轻松识别它已被修改。例如:jquery-ui.ZOOMFIX.js

我使用了以下软件包中的jquery-ui.js文件:https://jqueryui.com/resources/download/jquery-ui-1.12.1.zip

答案 3 :(得分:0)

您是否考虑了滚动位置,边距和填充?如:

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

然后根据需要调整缩放值?

答案 4 :(得分:0)

我在这里挣扎了几个小时。我有一个网格,我开始通过设置字体大小(容器上的125%等)来缩放它。这很有效,直到我进入不能与网格缩放的图像。

我以为我会使用缩放而非常出色。然后我重新使用draggable / droppable没有缩放它嗯..花几个小时试图破坏并重新启动jqueryUI对象但没有任何效果。

然后我终于意识到我可以使用font-size的组合来缩放网格和css-zoom的图像。现在一切正常,我可以使用相同的jQueryUI实例进行拖放。

希望这种方法有助于其他人。 : - )

答案 5 :(得分: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);    
        }                 
    });