如何用jQueryUI draggable模拟阻力?

时间:2012-02-02 15:04:11

标签: javascript jquery-ui geometry draggable

我正在寻找一种使用jQueryUI draggable插件模拟阻力的方法(类似于this effect)。在可拖动文档的底部提到:

  

“要在拖动过程中操纵可拖动的位置,您可以   使用包装器作为可拖动的帮助器并定位包裹的元素   绝对定位,或者您可以更正内部值:   $(this).data('draggable')。offset.click.top - = x“。

几何不是我强大的西装我正在寻找帮助,以便在拖动东西时如何最好地达到阻力的效果。我认为使用上面的这个提示,我可以使用几何函数更改可拖动移动的距离。我不确定最好的术语是阻力还是弹性,但我正在寻找一种感觉,好像一个元素通过橡皮筋或蹦极绳附着在一个点上,这样你拖得越远,物体移动的越少

例如,假设我要将对象拖动到500像素的总距离(在任何方向上)。我希望阻力效应增加距离我得到的起点更近的500像素。我环顾四周,没有见过这样的事情。

更新

我创建了一个基本的jsFiddle来计算项目在http://jsfiddle.net/Z8m4B/拖动的距离

计算结果如下:

var x1=x2=y1=y2=0;
$("#draggable").draggable({
    start: function(e, ui) {
        y1 = ui.position.top;
        x1 = ui.position.left;
    },
    stop: function(e, ui) {
        y2 = ui.position.top;
        x2 = ui.position.left;        
        dist = parseInt(Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)), 10);
        console.log(dist);
    }
});

显然我想在拖动事件期间改变距离而不是停止。有谁知道如何创造这种阻力或拉伸效应的功能?

4 个答案:

答案 0 :(得分:15)

您可以使用此http://jsfiddle.net/sAX4W/尝试拖动事件,您可以计算距离并从实际距离获得%

var x1 = x2 = y1 = y2 = 0;
$("#draggable").draggable({
    revert: true,
    revertDuration: 100,
    axis: 'y',
    drag: function(e, ui) {
        y2 = ui.position.top;
        x2 = ui.position.left;
        dist = parseInt(Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)), 10);
        ui.position.top = ui.position.top * (1 - (dist / 1000));
    },
    start: function(e, ui) {
        y1 = ui.position.top;
        x1 = ui.position.left;
    },
    stop: function(e, ui) {
    }
});​

修改

您可以使用轴http://jsfiddle.net/2QndJ/

进行尝试
var x1 = x2 = y1 = y2 = 0;
$("#draggable").draggable({
    revert: true,
    revertDuration: 100,

    drag: function(e, ui) {
        y2 = ui.position.top;
        x2 = ui.position.left;
        dist = parseInt(Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)), 10);

        ui.position.top = ui.position.top * (1 - (dist / 1000));
        ui.position.left = ui.position.left * (1 - (dist / 1000));
    },
    start: function(e, ui) {
        y1 = ui.position.top;
        x1 = ui.position.left;
    },
    stop: function(e, ui) {
    }
});​

答案 1 :(得分:9)

Here's a quick jsfiddle

基本上,它使用简单的公式1 / (x+1)。这是一个渐近曲线,意味着y → 0 x → infinityx >= 0)。所以y永远接近零,但永远不会到达那里。

在这种情况下,

x是鼠标拖动的距离,y用于缩放拖动矢量。因此,当y越来越接近零时,鼠标移动得越远,可拖动的移动就越少。

因此,如果拖动鼠标只有一点点,那么拖动鼠标就会保持不变。但是你拖得越远,它就会越少。

asymptote

顺便说一句,看起来您链接的示例只是将拖动距离减半。因此,如果将其拖动100像素,则会移动50像素。这是一个更简单的解决方案,但是行为不同,因为它是线性的。我的解决方案是使可拖动的指数移动得越少(尝试)拖动它,这是一种不同的行为。


<强>的jQuery

var halfDist = 150, // the mouse distance at which the mouse has moved
                    // twice as far as the draggable

centerX = 150,      // where to anchor the draggable
centerY = 150;

$("#draggable").draggable({
    drag: function(event, ui) {
        var x, y, dist, ratio, factor;
        x = ui.position.left - centerX;
        y = ui.position.top - centerY;
        dist = Math.sqrt(x*x + y*y);
        ratio = dist / halfDist
        factor = 1 / (ratio + 1);
        x *= factor;
        y *= factor;
        ui.position.left = x + centerX;
        ui.position.top  = y + centerY;
    }
});​

<强> HTML

<div id="arena">
    <div id="draggable"/>
</div>​

<强> CSS

#arena {
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
}

#draggable {
    width: 20px;
    height: 20px;
    background: red;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -10px;
    margin-top:  -10px;
}

感谢j08691从jsfiddle获取代码并将其放在此处

答案 2 :(得分:3)

var x1=x2=y1=y2=0;
var maxdistance=1000;
var factor=2;
$(function() {
    $("#draggable").draggable({
        helper: function(){
            return $('<div></div>').css('opacity',0);
        },
        start: function(e, ui) {
            y1 = ui.position.top;
            x1 = ui.position.left;
        },
        stop: function(){
            var $this = $(this);
            $this.stop().animate({
                top: $this.data('starttop')
            },1000,'easeOutCirc');
        },
        drag: function(event, ui){
            y2 = ui.position.top;
            x2 = ui.position.left;        
            dist = parseInt(Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)), 10);
            ydist = (y2-y1);
            xdist = (x2-x1);
            $("#draggable").css("top", (y1+ydist*((maxdistance-ydist)/maxdistance)));
            $("#draggable").css("left", (x1+xdist*((maxdistance-xdist)/maxdistance)));
        }
    });
});​

http://jsfiddle.net/Lf5vc/

答案 3 :(得分:0)

有两种方法: 您可以获取元素的左侧值:

drag: function(event, ui ) {
  distance = $(element).css("left")
}

或者你可以计算出来:

start: function( event , ui ) {
    globalX = event.clientX
},

drag: function( event, ui ) {
    distance = Math.abs(event.clientX - globalX);
}