2011-08-20 101 views
3

我知道如何在JavaScript中实现拖放效果,但是我发现在某些站点中,拖放操作的速度会导致不同的结果。javascript中的拖放操作

以Google地图为例,地图视图是可拖动的,当您缓慢拖动地图时,地图会随着鼠标移动,但是如果您非常快地拖动地图然后放下鼠标,地图会保留移动(有限的距离),似乎它有一个缓冲距离。

我想知道如何做到这一点?

回答

4

不幸的是,没有香草效应。

您将不得不计算各种参数,例如完成拖拽所需的距离,方向和时间。

然后根据结果,您可以计算贝塞尔曲线并扩展动画,使其看起来无缝平滑。

下面是一个例子... http://jsfiddle.net/an44z/

它的工作原理,如果也许不是那么好(匆匆写了一个老项目,但它可能给你什么正在发生的事情是一个好主意 - 应该发生)。

编辑:或者,你可以研究这个mooTools的例子,因为它几乎正是你所追求的。 http://mootools.net/demos/?demo=Drag.Scroll

2

听起来就像你在寻找某种“拖动速度”。我今天早上花了一些时间给你,所以我希望它有帮助(我也有一些乐趣)。 *原则*对于你想要做的事情是一样的,并且你可以有很多乐趣。

的Javascript布伦特使用:

// this is the easing I used in my "throwing" animation 
// I use this to average out some of the arrays (distance & angle) 
$.easing.easeOutCirc = function (x, t, b, c, d) { 
    return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 
} 

// stores the last drag spot, useful for calculating distances between points 
var drag_last_spot; 
// stores distances for use with calculating animation distance 
var drag_distances; 
// stores rads for use with calculating throw angle 
var drag_rads; 
// keeps the offset of the initial click to know where the mouse "went down" on the box 
var drag_offset; 
// keeps track of the "current target" since mouseUp and MouseMove are document level 
var drag_target; 
// keeps track of how long you held your mouse down on the box (to determine animation length) 
var drag_time; 

// taken via Google from http://jsfromhell.com/array/average 
average = function(a){ 
    var r = {mean: 0, variance: 0, deviation: 0}, t = a.length; 
    for(var m, s = 0, l = t; l--; s += a[l]); 
    for(m = r.mean = s/t, l = t, s = 0; l--; s += Math.pow(a[l] - m, 2)); 
    return r.deviation = Math.sqrt(r.variance = s/t), r; 
} 
function onMouseDown(event) { 
    // offset and last_spot are the same for the first move iteration 
    drag_time = (new Date).getTime(); 
    drag_offset = drag_last_spot = { 
     x: event.offsetX, 
     y: event.offsetY 
    }; 

    // initialize or reset the distances and angle arrays 
    drag_distances = []; 
    drag_rads = []; 

    // because there are multiple boxes, we need to keep track of the target since our events are document level 
    drag_target = $(this); 

    $(document).bind("mousemove", onMouseMove); 
    $(document).bind("mouseup", onMouseUp); 
} 

function onMouseMove(event) { 
    // use pathagorean theorem for distance between two points (yay geometry!) 
    var dist = Math.sqrt(Math.pow(drag_last_spot.x - event.clientX, 2) + Math.pow(drag_last_spot.y - event.clientY, 2)); 

    // push all the distances to this array for later use 
    drag_distances.push(dist); 

    // push all radians to this array for later use 
    var cur_rad = Math.atan2(event.clientY - drag_last_spot.y, event.clientX - drag_last_spot.x); 
    drag_rads.push(cur_rad); 

    // we need to know the last drag spot so we can calc the distance of the points during the next onMouseMove 
    drag_last_spot = { 
     x: event.clientX, 
     y: event.clientY 
    }; 

    drag_target.css({left:event.clientX - drag_offset.x, top:event.clientY - drag_offset.y}); 
} 

function onMouseUp(event) { 
    /* FYI wherever you see .slice(-N) you can change N to any number. I recommend a small number as a short drag will only have 5 or 10 items. A big number will average more of your "throw", but a small number is seemingly safer.*/ 

    // this is the total duration of how long you dragged for 
    var duration = ((new Date).getTime() - drag_time); 

    // this is the distance of your drag (I times by three for a better animated effect) 
    var dist = average(drag_distances.slice(-3)).mean * 3; 

    // these help determine the direction of your throw (figures out the angle) 
    var rad = average(drag_rads.slice(-3)).mean - Math.PI/2; 
    var to_left = event.clientX + Math.sin(rad) * -dist - drag_offset.x; 
    var to_top = event.clientY + Math.cos(rad) * dist - drag_offset.y; 

    // now to animation your throw! 
    drag_target.animate({left:to_left, top:to_top}, duration * 2, "easeOutCirc"); 

    $(document).unbind("mousemove"); 
    $(document).unbind("mouseup"); 
} 

这个例子是冰山的一角,所以我说勾搭脚本,以了解它是如何工作的,你很可能会拿出新的很酷的方式,做事。 祝你好运!