jquery 缩放容器的可拖动包含数组值
jquery draggable containment array values for scaled container
如果有人能帮我弄清楚如何使 div 中包含的可拖动元素根据 window 大小改变比例,我将非常感谢任何指导。
如果我这样做:
element.draggable({
cursor: "move",
containment: '#container'
});
会发生什么情况是它为我提供了容器常规大小的容器。所以如果我有一个transform: scale(1.5)
,容器里就会有space是可拖动元素不能去的
我也试过 containment: 'parent'
但那很麻烦。
编辑
我找到了如何获得顶部和左侧的包含,但我不知道如何获得右侧和底部。
var containmentArea = $("#container");
containment: [containmentArea.offset().left, containmentArea.offset().top, ???, ???]
我试过 width 和 height 从 containmentArea[0].getBoundingClientRect()
但这似乎也不是正确的举动.
看看这个:
http://jsfiddle.net/z0gqy9w2/3/
编辑后的代码如下:
// Matrix regex to take the scale value property of $('#container') element
var matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/,
matches = $('#container').css('transform').match(matrixRegex);
// Matches have this value : ["matrix(1.5, 0, 0, 1.5, 0, 0)", "1.5", "1.5"] , so we need matches[1] value :
var scaleValue = matches[1];
$(".draggable").draggable({
cursor: "move",
start: startFix,
drag: dragFix,
containment: [containmentArea.offset().left, containmentArea.offset().top,
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) ) ,
( ( containmentArea.offset().top + ( containmentArea.height() * scaleValue ) ) - ( $(".draggable").height() * scaleValue ) ) ]
});
如您所见,这是诀窍:
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) )
您的右侧最大位置将为:主容器左偏移 + 容器的真实宽度(带比例)- 项目真实宽度(让它在容器内)。
(提示:请随意更改 "percent" var 值,您也可以查看结果)
regex ref
在拖动事件中重置坐标的版本(因为它们已经为缩放转换重新计算),而不使用包含:
var percent = 1, containmentArea = $("#container");
function dragFix(event, ui) {
var contWidth = containmentArea.width(), contHeight = containmentArea.height();
ui.position.left = Math.max(0, Math.min(ui.position.left / percent , contWidth - ui.helper.width()));
ui.position.top = Math.max(0, Math.min(ui.position.top / percent, contHeight- ui.helper.height()));
}
$(".draggable").draggable({
cursor: "move",
drag: dragFix,
});
//scaling here (where the percent variable is set too)
示例中容器的宽度和高度是在dragevent中获取的,您也可以在缩放时存储它们以获得更好的性能。通过在事件中计算它们,它们在重新缩放后仍然有效,尽管仍然需要设置百分比变量。为了真正通用,它也可以在事件内部获得(并且可以使用 ui.helper.parent() 而不是固定容器)
由于 dragevent 内的偏移量是 (0,0) 与容器相关(至少对于当前设置而言是这样),因此冒昧地将 originalleft + (position - originalposition)/percent
简化为 position / percent
开始偏移量似乎不再是必需的,因此在 fiddle 中将其省略,但如果需要可以重新添加。
这是我的解决方案:
var _zoom = 1.2,
$element = $('.draggable-element'),
$container = $('#container');
var containmentW,
containmentH,
objW,
objH;
$element.draggable({
start: function(evt, ui) {
ui.position.left = 0;
ui.position.top = 0;
containmentW = $container.width() * _zoom;
containmentH = $container.height() * _zoom;
objW = $(this).outerWidth() * _zoom;
objH = $(this).outerHeight() * _zoom;
},
drag: function(evt, ui) {
var boundReached = false,
changeLeft = ui.position.left - ui.originalPosition.left,
newLeft = ui.originalPosition.left + changeLeft / _zoom,
changeTop = ui.position.top - ui.originalPosition.top,
newTop = ui.originalPosition.top + changeTop / _zoom;
// right bound check
if(ui.position.left > containmentW - objW) {
newLeft = (containmentW - objW) / _zoom;
boundReached = true;
}
// left bound check
if(newLeft < 0) {
newLeft = 0;
boundReached = true;
}
// bottom bound check
if(ui.position.top > containmentH - objH) {
newTop = (containmentH - objH) / _zoom;
boundReached = true;
}
// top bound check
if(newTop < 0) {
newTop = 0;
boundReached = true;
}
// fix position
ui.position.left = newLeft;
ui.position.top = newTop;
// inside bounds
if(!boundReached) {
// do stuff when element is dragged inside bounds
}
}
});
如果有人能帮我弄清楚如何使 div 中包含的可拖动元素根据 window 大小改变比例,我将非常感谢任何指导。
如果我这样做:
element.draggable({
cursor: "move",
containment: '#container'
});
会发生什么情况是它为我提供了容器常规大小的容器。所以如果我有一个transform: scale(1.5)
,容器里就会有space是可拖动元素不能去的
我也试过 containment: 'parent'
但那很麻烦。
编辑
我找到了如何获得顶部和左侧的包含,但我不知道如何获得右侧和底部。
var containmentArea = $("#container");
containment: [containmentArea.offset().left, containmentArea.offset().top, ???, ???]
我试过 width 和 height 从 containmentArea[0].getBoundingClientRect()
但这似乎也不是正确的举动.
看看这个:
http://jsfiddle.net/z0gqy9w2/3/
编辑后的代码如下:
// Matrix regex to take the scale value property of $('#container') element
var matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/,
matches = $('#container').css('transform').match(matrixRegex);
// Matches have this value : ["matrix(1.5, 0, 0, 1.5, 0, 0)", "1.5", "1.5"] , so we need matches[1] value :
var scaleValue = matches[1];
$(".draggable").draggable({
cursor: "move",
start: startFix,
drag: dragFix,
containment: [containmentArea.offset().left, containmentArea.offset().top,
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) ) ,
( ( containmentArea.offset().top + ( containmentArea.height() * scaleValue ) ) - ( $(".draggable").height() * scaleValue ) ) ]
});
如您所见,这是诀窍:
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) )
您的右侧最大位置将为:主容器左偏移 + 容器的真实宽度(带比例)- 项目真实宽度(让它在容器内)。
(提示:请随意更改 "percent" var 值,您也可以查看结果)
regex ref
在拖动事件中重置坐标的版本(因为它们已经为缩放转换重新计算),而不使用包含:
var percent = 1, containmentArea = $("#container");
function dragFix(event, ui) {
var contWidth = containmentArea.width(), contHeight = containmentArea.height();
ui.position.left = Math.max(0, Math.min(ui.position.left / percent , contWidth - ui.helper.width()));
ui.position.top = Math.max(0, Math.min(ui.position.top / percent, contHeight- ui.helper.height()));
}
$(".draggable").draggable({
cursor: "move",
drag: dragFix,
});
//scaling here (where the percent variable is set too)
示例中容器的宽度和高度是在dragevent中获取的,您也可以在缩放时存储它们以获得更好的性能。通过在事件中计算它们,它们在重新缩放后仍然有效,尽管仍然需要设置百分比变量。为了真正通用,它也可以在事件内部获得(并且可以使用 ui.helper.parent() 而不是固定容器)
由于 dragevent 内的偏移量是 (0,0) 与容器相关(至少对于当前设置而言是这样),因此冒昧地将 originalleft + (position - originalposition)/percent
简化为 position / percent
开始偏移量似乎不再是必需的,因此在 fiddle 中将其省略,但如果需要可以重新添加。
这是我的解决方案:
var _zoom = 1.2,
$element = $('.draggable-element'),
$container = $('#container');
var containmentW,
containmentH,
objW,
objH;
$element.draggable({
start: function(evt, ui) {
ui.position.left = 0;
ui.position.top = 0;
containmentW = $container.width() * _zoom;
containmentH = $container.height() * _zoom;
objW = $(this).outerWidth() * _zoom;
objH = $(this).outerHeight() * _zoom;
},
drag: function(evt, ui) {
var boundReached = false,
changeLeft = ui.position.left - ui.originalPosition.left,
newLeft = ui.originalPosition.left + changeLeft / _zoom,
changeTop = ui.position.top - ui.originalPosition.top,
newTop = ui.originalPosition.top + changeTop / _zoom;
// right bound check
if(ui.position.left > containmentW - objW) {
newLeft = (containmentW - objW) / _zoom;
boundReached = true;
}
// left bound check
if(newLeft < 0) {
newLeft = 0;
boundReached = true;
}
// bottom bound check
if(ui.position.top > containmentH - objH) {
newTop = (containmentH - objH) / _zoom;
boundReached = true;
}
// top bound check
if(newTop < 0) {
newTop = 0;
boundReached = true;
}
// fix position
ui.position.left = newLeft;
ui.position.top = newTop;
// inside bounds
if(!boundReached) {
// do stuff when element is dragged inside bounds
}
}
});