Jquery可拖动缩放问题

Posted

技术标签:

【中文标题】Jquery可拖动缩放问题【英文标题】:Jquery draggable with zoom problem 【发布时间】:2011-02-25 04:24:37 【问题描述】:

我正在处理一个页面,它的所有内容都使用缩放进行缩放。 问题是当我在页面中拖动某些东西时,拖动项目的位置似乎与缩放量有关。

为了解决这个问题,我尝试对可拖动组件的位置进行一些数学运算,但似乎即使在视觉上它已被纠正,“真实”位置也没有重新计算。

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

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

任何帮助将不胜感激

【问题讨论】:

供将来参考 - 如果有人遇到同样的问题 - 可以找到类似的问题 + 工作答案here。 【参考方案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

【讨论】:

这个答案与问题有什么关系? @sg7 OP 正在寻求使用 jQuery UI 进行错误定位拖动的解决方案。我的回答提供了一种解决方案,可以使用 jQuery UI 修复位置不佳的拖动。同步我的回答回答了我认为足够相关的问题。【参考方案2】:
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);    
                         
    );

【讨论】:

【参考方案3】:

我为此苦苦挣扎了几个小时。我有一个网格,我开始通过设置字体大小(容器上的 125% 等)来缩放它。这一直很好,直到我遇到不随网格缩放的图像。

我想我会改用缩放,结果效果很好。然后我觉得可拖动/可放置并没有随它缩放嗯.. 花了几个小时试图销毁和重新初始化 jqueryUI 对象,但没有任何效果。

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

希望这种方法对其他人有所帮助。 :-)

【讨论】:

【参考方案4】:

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

此解决方案适用于 Firefox 和 IE。 #canvas 是包含可拖动对象的 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);
  
);

【讨论】:

你能提供一个有效的 JSFiddle 链接吗?我们将在问题 8605439 中感谢它 我也有同样的问题。缩放是百分比还是实际值? 很久没做这个了,但是看代码,肯定是(float)值,其中1.0就是100%缩放。试试看! 太好了,这也解决了我的问题。唯一的问题是,在滚动拖动的项目后以某种方式移动到顶部。 对于未来的读者,请先尝试@Yusuf Demirag 回答(它在某处),因为它也适用于滚动。 (也很短)【参考方案5】:

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

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

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

【讨论】:

计算好,当zoom不是1.0时offset().top的返回值错误

以上是关于Jquery可拖动缩放问题的主要内容,如果未能解决你的问题,请参考以下文章

缩放容器的jquery可拖动包含数组值

jQuery 可拖动和 -webkit-transform: scale();

使用 CSS 变换缩放的 jQuery 拖动/调整大小

每天学一个jquery插件-缩放与拖动

如何实现拖动修改网页中div模块大小

Jquery 可通过 panzoom 拖动