У меня есть код, который демонстрирует проблему.
У меня есть элемент, который можно перетаскивать, и он отлично работает. Я включил кнопку, которая позволяет пользователю «увеличить масштаб». Это тот случай, когда что-то идет не так.
Проблема заключается в том, что после того, как вы нажмете кнопку масштабирования, часть containment
draggable
больше не подчиняется ограничениям по левому краю/верху/ширине и высоте родительского элемента. Он по-прежнему ограничен, но неожиданным расположением границы.
<body style = "padding:50px">
<button id = "btn">Zoom in</button>
<div id = "wrapper" style = "background-color:aliceblue;padding:50px;">
<div id = "innerWrapper" style = "background-color: ivory; min-height: 200px; width: 400px; ">
<div id = "draggable" style = "background-color:burlywood;max-width:100px;">Move me</div>
</div>
</div>
<script src = "https://code.jquery.com/jquery-3.7.1.min.js" integrity = "sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo = " crossorigin = "anonymous"></script>
<script src = "https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" integrity = "sha256-lSjKY0/srUM9BE3dPm+c4fBo1dky2v27Gdjm2uoZaL0 = " crossorigin = "anonymous"></script>
<script>
$("#draggable").draggable({containment:"#innerWrapper"});
const btn = document.getElementById("btn");
btn.addEventListener("click", zoom);
function zoom() {
document.getElementById("innerWrapper").style.transform = "scale(1.2,1.2)";
}
</script>
</body>
Фактически, каждый раз, когда вы нажимаете кнопку масштабирования, граница сдерживания изменяется.
Я попытался добавить обратный вызов события drag
в перетаскиваемый элемент, но до сих пор не вижу, как это исправить.
Это происходит из-за scale()
, в некоторых композициях он ведет себя странно, и один из них — когда у вас есть перетаскиваемый элемент внутри вложения, и это вложение — scaled
, поэтому элемент внутри не обновляет свой фактический размер, даже если вы destroy
или disable
и enable
перетаскиваемый элемент.
Итак, что вы можете сделать, это рассчитать самостоятельно размер сдерживания:
const draggableElement = $("#draggable")
let containmentArea = $("#innerWrapper");
let percent = 1
draggableElement.draggable({
cursor: "move",
drag: dragFix,
});
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()));
}
function setScale(scalePercentage) {
percent = scalePercentage;
$("#innerWrapper").css({
'transform': 'scale(' + percent + ')',
'-moz-transform': 'scale(' + percent + ')',
'-webkit-transform': 'scale(' + percent + ')',
'-ms-transform': 'scale(' + percent + ')'
})
}
const btn = document.getElementById("btn");
btn.addEventListener("click", function() {
setScale(1.2)
});
#wrapper {
width: 100%;
height: 300px;
overflow: auto;
}
#innerWrapper {
width: 250px;
height: 250px;
position: relative;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform-origin: 0 0;
-ms-transform-origin: 0 0;
}
#draggable {
display: inline;
position: absolute;
top: 10px;
left: 10px;
}
<script src = "https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src = "https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<button id = "btn">Zoom in</button>
<div id = "wrapper" style = "background-color:aliceblue;padding:50px;">
<div id = "innerWrapper" style = "background-color: ivory; min-height: 200px; width: 400px; ">
<div id = "draggable" style = "background-color:burlywood;max-width:100px;">Move me</div>
</div>
</div>
Примечания:
1. Вы можете использовать только tranform
и transform-only
. Я сделал это, чтобы показать, что вы можете использовать все типы transform
.
2 - Чтобы не было глюков при нажатии на перетаскиваемый элемент нужно сделать его absolute
и обертку relative