Операция перетаскивания с помощью jquery-ui при увеличенном перемещении контейнера при первом движении мыши

Я создаю контейнер с двумя маленькими дочерними элементами. Я делаю контейнер и дочерние элементы перетаскиваемыми. Дочерние элементы перетащить, как ожидалось Внешний контейнер перетаскивается, как ожидается, когда коэффициент масштабирования равен 1,0, но при увеличении операции перетаскивания переходят при первом перемещении контейнера. Есть некоторые другие связанные вопросы и возможные ответы, но те, которые я пробовал, только исправляли проблемы с дочерними контейнерами, а не с родительскими контейнерами.

В частности, я попробовал все предложения здесь: jQuery Drag / Resize с CSS Transform Scale

И я рассмотрел это: jQuery UI Перетаскиваемый прыжок при первом перетаскивании, который не имеет никакого полезного ответа.

jsfiddle здесь: http://jsfiddle.net/nigelt/w521gv0j/5/

HTML:

<!-- Create an area where we will allow items to be moved -->
<div id=mycontainer>Press '+' to zoom in, '-' to zoom out, 'r' to reset.
    <br>This pane is draggable
    <!-- create a couple of boxes -->
    <div class="mybox" id="source">Draggable</div>
    <div class="mybox" id="dest">Draggable</div>
</div>

CSS:

#mycontainer {
    width: 600px;
    height: 400px;
    background: #ddd;
    position: absolute;
    top: 0;
    left: 0;
    float: none;
    border: solid 1px;
}
.mybox {
    position: absolute;
    background: #fff;
    border: 1px solid;
    border-radius: 6px;
    width: 100px;
    height: 75px;
    float: none;
    text-align: center;
}
#source {
    top: 50px;
    left: 100px;
}
#dest {
    top: 100px;
    left: 250px;
}
body {
    margin: 0px;
    /* force mycontainer to edge */
    overflow: hidden;
    /* no scrolling of body area. Clip the contents if moved */
}

JavaScript:

// global to set the zoomscale
zoomScale = 1;

// Set the zoom scale
var setZoomScale = function (zoom) {
    zoomScale = zoom;

    var container = $("#mycontainer");
    var scaleval = 'scale(' + zoom + ',' + zoom + ')';
    container.css('-ms-transform', scaleval);
    container.css('-webkit-transform', scaleval);
    container.css('transform', scaleval);
}

// Make the boxes draggable
// apply the stackru fix
$("#source, #dest").draggable({
    start: function (event, ui) {
        ui.position.left = 0;
        ui.position.top = 0;
    },
    drag: function (event, ui) {
        // drag handle fix
        var changeLeft = ui.position.left - ui.originalPosition.left; // find change in left
        var newLeft = ui.originalPosition.left + changeLeft / ((zoomScale)); // adjust new left by our zoomScale

        var changeTop = ui.position.top - ui.originalPosition.top; // find change in top
        var newTop = ui.originalPosition.top + changeTop / zoomScale; // adjust new top by our zoomScale

        ui.position.left = newLeft;
        ui.position.top = newTop;

    }
});

// make the virtual window draggable
// apply the stackru fix
$("#mycontainer").draggable({
    start: function (event, ui) {
        ui.position.left = 0;
        ui.position.top = 0;
    },
    drag: function (event, ui) {
        // drag handle fix
        var changeLeft = ui.position.left - ui.originalPosition.left; // find change in left
        var newLeft = ui.originalPosition.left + changeLeft / ((zoomScale)); // adjust new left by our zoomScale

        var changeTop = ui.position.top - ui.originalPosition.top; // find change in top
        var newTop = ui.originalPosition.top + changeTop / zoomScale; // adjust new top by our zoomScale

        ui.position.left = newLeft;
        ui.position.top = newTop;
    },
    stop: function (event, ui) {}
});

// add a keypress handler so we can change the zoom
$(document).keypress(function (ev) {
    var key = String.fromCharCode(ev.charCode);
    if (key == '+') {
        setZoomScale(zoomScale *= 1.5);
    } else if (key == '-') {
        setZoomScale(zoomScale /= 1.5);
    } else if (key == 'r') {
        // reset
        setZoomScale(1.0);
        $("#mycontainer").css({
            "top": 0,
                "left": 0
        });
    }
});

setZoomScale(1.5);

В скрипте коэффициент масштабирования изначально установлен на 1,5. Чтобы сбросить его до 1,0, установите фокус на демонстрационное окно и нажмите "R". После этого перетаскивание контейнера работает правильно

1 ответ

Ну, в конце концов, на создание скрипки и написание вопроса потребовалось больше времени, чем на поиск ответа. Этот пост: Jquery, перетаскиваемый с проблемой увеличения, исправил мою проблему отлично.

Модифицированный код для моей скрипки:

var pointerX;
var pointerY;
$("#mycontainer").draggable({
    start: function(evt, ui) {
        pointerY = (evt.pageY - $('body').offset().top) / zoomScale - parseInt($(evt.target).css('top'));
        pointerX = (evt.pageX - $('body').offset().left) / zoomScale - parseInt($(evt.target).css('left'));
        //console.log('pointer: ' + pointerX + ',' + pointerY);
    },
    drag: function(evt,ui) {
        var canvasTop = $('body').offset().top;
        var canvasLeft = $('body').offset().left;
        var canvasHeight = $('body').height();
        var canvasWidth = $('body').width();
        //console.log('canvas: ' + canvasLeft + ',' + canvasTop + '  ' + canvasWidth + 'x' + canvasHeight);

        // Fix for zoom
        ui.position.top = Math.round((evt.pageY - canvasTop) / zoomScale - pointerY); 
        ui.position.left = Math.round((evt.pageX - canvasLeft) / zoomScale - 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);
    },
    stop: function(event, ui) {
    }
});

Это было моим решением:

var highestTopHeight = 10;
var leftestLeftWidth = 10;
function resizeFix(event, ui) {
    let curWidth = ui.position.left + ui.size.width;
    if (curWidth > ui.element.parent().width() || curWidth === ui.element.parent().width()) {
        ui.size.width = ui.element.parent().width() - ui.position.left;
    }

    let curHeight = ui.position.top + ui.size.height;
    if (curHeight > ui.element.parent().height() || curWidth === ui.element.parent().height()) {
        ui.size.height = ui.element.parent().height() - ui.position.top;
    }

    if (ui.position.top >= 0)
        highestTopHeight = ui.size.height;

    if (ui.position.top < 0) {
        ui.position.top = 0;
        ui.size.height = highestTopHeight;
    }

    if (ui.position.left >= 0)
        leftestLeftWidth = ui.size.width;

    if (ui.position.left < 0) {
        ui.position.left = 0;
        ui.size.width = leftestLeftWidth;
    }
}

Примените это к изменению размера изменяемого размера:

$('#yourID').resizable({... resize: resizeFix,...})

изменить размер: resizeFix,

Другие вопросы по тегам