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可拖动缩放问题的主要内容,如果未能解决你的问题,请参考以下文章