我正在处理一个页面,其所有内容都通过缩放来缩放。 问题是当我在页面中拖动某些东西时,拖动项会得到一个看似相对于缩放量的坏位置。
为了解决这个问题,我尝试对可拖动组件的位置进行一些数学计算,但是看起来甚至在视觉上它的修正,“真实”位置都没有重新计算。
这里有一些代码可以更好地解释:
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);
非常感谢任何帮助
答案 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);
}
});