如何使用 jQueryUI 拖动来模拟阻力?

发布于 2025-01-01 08:51:42 字数 1154 浏览 0 评论 0原文

我正在寻找一种使用 jQueryUI 可拖动插件来模拟阻力的方法(类似于 这种效果)。在可拖动文档的底部,它提到:

“要在拖动过程中操纵可拖动对象的位置,您可以 使用包装器作为可拖动的帮助器并定位包装的元素 使用绝对定位,或者您可以像这样更正内部值: $(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);
    }
});

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

I’m looking for a way to simulate resistance using the jQueryUI draggable plugin (similar to this effect). At the bottom of the draggable documentation it mentions:

“To manipulate the position of a draggable during drag, you can either
use a wrapper as the draggable helper and position the wrapped element
with absolute positioning, or you can correct internal values like so:
$(this).data('draggable').offset.click.top -= x”.

Geometry not being my strong suit I was looking for help on how to best achieve the effect of resistance when dragging something. I thought that using this tip above, I could change the distance the draggable is moved using a geometric function. I’m not sure if the best term is resistance or elasticity, but I’m looking for the feel as if an element is attached to a point by a rubber band or bungee cord so that the further you drag, the less the object moves.

For example, say I want to drag an object a total distance of 500 pixels (in any direction). I would like the resistance effect to increase the closer to 500 pixels away from the starting point I get. I’ve looked around and haven’t seen anything like this.

Update:

I created a basic jsFiddle that calculates the distance an item has been dragged at http://jsfiddle.net/Z8m4B/

The calculation is:

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

Obviously I would want to change the distance during the drag event and not on stop. Does anyone know how a function to create this resistance or stretch effect?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光与爱终年不遇 2025-01-08 08:51:42

您可以尝试使用此 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) {
    }
});​

you can try with this http://jsfiddle.net/sAX4W/ with the drag event you can calculate the distance and get a % from the real distance

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) {
    }
});​

edit

you can try this with both axis 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) {
    }
});​
如歌彻婉言 2025-01-08 08:51:42

这是一个快速的 jsfiddle

基本上,它使用简单的公式 1 / (x+1)。这是一条渐近曲线,意味着 y → 0 对于 x → 无穷大(对于 x >= 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 获取代码并将其也放置在这里

Here's a quick jsfiddle

Basically, it uses the simple formula 1 / (x+1). That's an asymptotic curve, meaning that y → 0 for x → infinity (for x >= 0). So y is forever approaching zero, but never gets there.

x in this case is the distance the mouse has been dragged, and y is used to scale the drag vector. So the further the mouse moves, the less the draggable will move, as y gets closer and closer to zero.

So if the mouse is dragged only a little, the draggable pretty much keeps up. But the farther you drag it, the less it will follow.

asymptote

By the way, it looks like the example you linked to simply halves the dragged distance. So if you drag it 100 pixels, it moves 50 pixels. That's a simpler solution, but a different behavior, since it's linear. My solution is makes the draggable move exponentially less the farther you (try to) drag it, so it's a different kind of behavior.


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;
}

Thanks to j08691 for taking the code from jsfiddle and placing it here too

清风无影 2025-01-08 08:51:42
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/

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/

旧城烟雨 2025-01-08 08:51:42

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

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

There are two ways:
You can get the left value of the element:

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

or you can calculate it:

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

drag: function( event, ui ) {
    distance = Math.abs(event.clientX - globalX);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文