операция перетаскивания в JavaScript - PullRequest
3 голосов
/ 20 августа 2011

Я знаю, как реализовать эффект перетаскивания в JavaScript, но я обнаружил, что на некоторых сайтах скорость операции перетаскивания приведет к другому результату.

Возьмем, к примеру, карту Google,вид карты можно перетаскивать, когда вы медленно перетаскиваете карту, карта будет перемещаться с помощью мыши, однако, если вы перетащите карту очень быстро, а затем отпустите кнопку мыши, карта продолжит движение (ограниченное расстояние), кажется, что онаимеет буферное расстояние.

Интересно, как это сделать?

Ответы [ 2 ]

4 голосов
/ 20 августа 2011

К сожалению, для этого нет эффекта ванили.

Вам придется подсчитывать различные параметры, такие как расстояние, направление и время, необходимое для завершения перетаскивания.

Затем в зависимости отВ результате вы можете вычислить кривую Безье и расширить анимацию, чтобы она выглядела плавно и плавно.

Вот пример ... http://jsfiddle.net/an44z/

Это работает, если возможно не так хорошо (написан на скорую руку для старого проекта, но он может дать вам хорошее представление о том, что происходит - должно происходить).

РЕДАКТИРОВАТЬ: В качестве альтернативы вы можете изучить этот пример mooTools, поскольку это в значительной степени именно то, что выпосле.http://mootools.net/demos/?demo=Drag.Scroll

2 голосов
/ 20 августа 2011

Звучит так, будто вы ищете какую-то "скорость сопротивления".Сегодня утром я потратил некоторое время на то, чтобы собрать для вас этот пример «мышь-в-бросок» , поэтому я надеюсь, что это поможет (мне тоже было интересно сделать это).* Принцип * тот же, что вы хотите сделать, и это то, с чем вы можете получить массу удовольствия.

Используемый основной удар 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");
}

Этот примерэто всего лишь верхушка айсберга, поэтому я говорю, что вы можете поработать со сценарием, чтобы узнать, как он работает, поскольку вы, вероятно, найдете новые классные способы сделать что-то. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...