jquery draggable包含缩放容器的数组值

时间:2015-07-10 17:25:56

标签: javascript jquery jquery-ui jquery-draggable jquery-droppable

如果有人可以帮我弄清楚如何使可拖动元素包含在根据窗口大小改变比例的div中,我真的很感激任何指导。

如果我这样做:

element.draggable({ 
    cursor: "move",
    containment: '#container'
});

它会发生什么,它会让我对容器的常规尺寸进行遏制。因此,如果我有transform: scale(1.5),则容器中将有可拖动元素无法运行的空间。

我也试过了containment: 'parent',但这很麻烦。

修改

我已经找到了如何获得顶部和左侧的收容,但我无法弄清楚如何获得正确和最低限度。

var containmentArea = $("#container");

containment:  [containmentArea.offset().left, containmentArea.offset().top, ???, ???]

我已尝试containmentArea[0].getBoundingClientRect()宽度身高,但这似乎也不是正确的举动。

Here is a jsfiddle of some example code.

3 个答案:

答案 0 :(得分:4)

一个版本,用于重置拖动事件中的坐标(因为它们已经为比例转换重新计算),而不使用包含:

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)

Fiddle

在示例中,容器的宽度和高度是在dragevent中获得的,您还可以在缩放时存储它们以获得更好的性能。通过在事件内部计算它们,它们在重新缩放后仍然可以工作,尽管仍然必须设置百分比变量。要真正通用,它也可以在事件内部获得(而不是固定容器,可以使用ui.helper.parent()) 由于dragevent中的偏移量是与容器相关的(0,0)(至少是当前设置),因此可以自由地将originalleft + (position - originalposition)/percent简化为position / percent 开始偏移似乎不再是必要的,所以把它留在小提琴中,但如果需要可以重新添加。

答案 1 :(得分:0)

看看这个:

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 ) )

你的右边最大位置是:主容器左偏移量+容器的真实宽度(带刻度) - 项目的真实宽度(让它在容器内)。

(提示:可以根据需要随意更改“百分比”var值)

regex ref

答案 2 :(得分:0)

这是我的解决方案:

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

        }

    }
});

Link to fiddle