jquery ui拖动缓动/惯性

使用jquery ui draggable(http://jqueryui.com/demos/draggable/)拖动元素时如何启用缓动或惯性? 我想重新创建类似于maps.google.com的缓动,当您抛出/拖动地图时,它会轻松到位。 理想情况下,我想根据您投掷/拖动元素的力移动元素移动。 你是如何完成这项function的? 也许jquery ui draggable不是必需的,但我希望模仿谷歌地图上的拖动和缓和。

谢谢!

我从这里使用了一些想法,但是将它们与jQuery UI集成在一起。 你必须实现逻辑来处理一个动量动画,它推动元素越界(在它的父容器的边界之外)

结果代码:

$(function() { var $d = $("#draggable"); var x1, x2, y1, y2, t1, t2; // Time var minDistance = 40; // Minimum px distance object must be dragged to enable momentum. var onMouseMove = function(e) { var mouseEvents = $d.data("mouseEvents"); if (e.timeStamp - mouseEvents[mouseEvents.length-1].timeStamp > 40) { mouseEvents.push(e); if (mouseEvents.length > 2) { mouseEvents.shift(); } } } var onMouseUp = function() { $(document).unbind("mousemove mouseup"); } $d.draggable({ start: function(e, ui) { $d.data("mouseEvents", [e]); $(document) .mousemove(onMouseMove) .mouseup(onMouseUp); }, stop: function(e, ui) { $d.stop(); $d.css("text-indent", 100); var lastE = $d.data("mouseEvents").shift(); x1 = lastE.pageX; y1 = lastE.pageY; t1 = lastE.timeStamp; x2 = e.pageX; y2 = e.pageY; t2 = e.timeStamp; // Deltas var dX = x2 - x1, dY = y2 - y1, dMs = Math.max(t2 - t1, 1); // Speeds var speedX = Math.max(Math.min(dX/dMs, 1), -1), speedY = Math.max(Math.min(dY/dMs, 1), -1); // Distance moved (Euclidean distance) var distance = Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)); if (distance > minDistance) { // Momentum var lastStepTime = new Date(); $d.animate({ textIndent: 0 }, { duration: Math.max(Math.abs(speedX), Math.abs(speedY)) * 2000, step: function(currentStep){ speedX *= (currentStep / 100); speedY *= (currentStep / 100); var now = new Date(); var stepDuration = now.getTime() - lastStepTime.getTime(); lastStepTime = now; var position = $d.position(); var newLeft = (position.left + (speedX * stepDuration / 4)), newTop = (position.top + (speedY * stepDuration / 4)); $d.css({ left: newLeft+"px", top: newTop+"px" }); } }); } } }); }); 

试试看

simshaun在这方面的工作非常棒。

我搞砸了他的版本,并使用jquery.easing插件获得了更平滑的动画。
在jsfiddle上尝试一下。

 $(document).ready(function() { $('#dragme').draggable({ start: function(e, ui) { dragMomentum.start(this.id, e.clientX, e.clientY, e.timeStamp); }, stop: function(e, ui) { dragMomentum.end(this.id, e.clientX, e.clientY, e.timeStamp); } }); }); var dragMomentum = new function () { var howMuch = 30; // change this for greater or lesser momentum var minDrift = 6; // minimum drift after a drag move var easeType = 'easeOutBack'; // This easing type requires the plugin: // jquery.easing.1.3.js http://gsgd.co.uk/sandbox/jquery/easing/ var dXa =[0]; var dYa =[0]; var dTa =[0]; this.start = function (elemId, Xa, Ya, Ta) { dXa[elemId] = Xa; dYa[elemId] = Ya; dTa[elemId] = Ta; }; // END dragmomentum.start() this.end = function (elemId, Xb, Yb, Tb) { var Xa = dXa[elemId]; var Ya = dYa[elemId]; var Ta = dTa[elemId]; var Xc = 0; var Yc = 0; var dDist = Math.sqrt(Math.pow(Xa-Xb, 2) + Math.pow(Ya-Yb, 2)); var dTime = Tb - Ta; var dSpeed = dDist / dTime; dSpeed=Math.round(dSpeed*100)/100; var distX = Math.abs(Xa - Xb); var distY = Math.abs(Ya - Yb); var dVelX = (minDrift+(Math.round(distX*dSpeed*howMuch / (distX+distY)))); var dVelY = (minDrift+(Math.round(distY*dSpeed*howMuch / (distX+distY)))); var position = $('#'+elemId).position(); var locX = position.left; var locY = position.top; if ( Xa > Xb ){ // we are moving left Xc = locX - dVelX; } else { // we are moving right Xc = locX + dVelX; } if ( Ya > Yb ){ // we are moving up Yc = (locY - dVelY); } else { // we are moving down Yc = (locY + dVelY); } var newLocX = Xc + 'px'; var newLocY = Yc + 'px'; $('#'+elemId).animate({ left:newLocX, top:newLocY }, 700, easeType ); }; // END dragmomentum.end() }; // END dragMomentum()