Как имитировать сопротивление с помощью jQueryUI?
Мне нужен способ моделирования сопротивления с помощью плагина jQueryUI draggable (аналогично этот эффект). В нижней части перетаскиваемой документации упоминается:
"Чтобы манипулировать положением перетаскиваемого во время перетаскивания, вы можете либо используйте обертку в качестве перетаскиваемого помощника и поместите обернутый элемент с абсолютным позиционированием, или вы можете исправить внутренние значения следующим образом: $(this).data('draggable'). offset.click.top - = x".
Геометрия, не являющаяся моим сильным костюмом, я искал помощь в том, как наилучшим образом добиться эффекта сопротивления при перетаскивании чего-то. Я думал, что используя этот совет выше, я мог бы изменить расстояние, которое перетаскивает, перемещается с помощью геометрической функции. Я не уверен, что лучший термин - сопротивление или эластичность, но Im ищет ощущение, будто элемент прикреплен к точке резиновой лентой или шнуром банджи, так что чем дальше вы тащите, тем меньше движется объект.
Например, скажем, я хочу перетащить объект на 500 пикселей (в любом направлении). Я бы хотел, чтобы эффект сопротивления увеличивался ближе к 500 пикселям от начальной точки, которую я получаю. Ive огляделся и не видел ничего подобного.
Обновление
Я создал базовый 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);
}
});
Очевидно, я хотел бы изменить расстояние во время события перетаскивания, а не на остановке. Кто-нибудь знает, как создать функцию сопротивления или растяжения?
Ответы
Ответ 1
вы можете попробовать с помощью 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) {
}
});
Ответ 2
Здесь быстрый jsfiddle
В принципе, он использует простую формулу 1 / (x+1)
. Это асимптотическая кривая, означающая y → 0
для x → infinity
(для 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 и его размещения здесь тоже
Ответ 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/
Ответ 4
Существует два способа:
Вы можете получить левое значение элемента:
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);
}