缩放容器的jquery可拖动包含数组值

Posted

技术标签:

【中文标题】缩放容器的jquery可拖动包含数组值【英文标题】:jquery draggable containment array values for scaled container 【发布时间】:2015-09-29 13:26:30 【问题描述】:

如果有人能帮我弄清楚如何使 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() 尝试了 widthheight,但这似乎也不是正确的做法。


Here is a jsfiddle of some example code.

【问题讨论】:

没有详细查看 dragFix 函数(可能,你可以限制那里的值而不是使用包含),当我测试它时,边界本身似乎确实有效,但需要拖动的元素尺寸被减去:var bounds = container.getBoundingClientRect(); var dragrect = $('.draggable')[0].getBoundingClientRect() .... containment: [bounds.x,bounds.y, bounds.right - dragrect.width, bounds.bottom - dragrect.height](小提琴:jsfiddle.net/z0gqy9w2/4) @Me.Name 嗯,右边和底部似乎工作,但现在顶部和左边不工作。编辑 Dragfix 可能是一个可能的解决方案。好主意。 糟糕,使用 x 和 y 代替左右,x 和 y 在 firefox 中工作,所以没有问题。这也适用于 Chrome(尚未测试 ie):containment: [bounds.left,bounds.top, bounds.right - dragrect.width, bounds.bottom - dragrect.height] (jsfiddle.net/z0gqy9w2/5)(不过,在 dragfix 中进行工作感觉更通用,稍后可能会看一下) @Me.Name 感谢您对此进行破解!如果 draggable container is inside a scrollable container. 【参考方案1】:

在拖动事件中重置坐标的版本(因为它们已经为缩放转换重新计算),不使用包含:

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

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

【讨论】:

这是完美的边缘!太感谢了!!只要它允许我就会奖励赏金【参考方案2】:

看看这个:

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

【讨论】:

哇@Ser​​CrAsH 谢谢你!你似乎正朝着正确的方向前进。出于某种原因,如果容器位于可滚动的 div 中,则顶部和底部容器边界似乎会出现故障。 写一个console.log(matches) 告诉我matches[1]==[2] 我刚刚做了scaleValue = percent而不是匹配。这是个坏主意吗? 如果它对你来说是可以的,我虽然那个百分比将是一个动态值并且你硬编码它。 :) 感谢您的关注。这是一个动态值,但 var percent 会更新:)。我认为由于我的容器位于可滚动的 div 中,因此偏移量对我来说很糟糕。如果我在拖动.draggable 时没有看到页面底部,则它不会有底部边界。如果我在拖动页面时看到的是底部而不是顶部,那么如果这有意义的话,顶部边界会出现在页面的一半处。..【参考方案3】:

这是我的解决方案:

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

【讨论】:

以上是关于缩放容器的jquery可拖动包含数组值的主要内容,如果未能解决你的问题,请参考以下文章

jquery UI可拖动:在容器内水平拖动溢出:滚动?

包含到父级的JQuery Draggable和额外的一个

可拖动 | jQuery 用户界面。如何在拖动事件上添加类

Jquery可拖动缩放问题

可拖动的 Jquery 不适用于包含

隐藏的 jQuery 可拖动包含溢出