JQuery легко перетаскивается - PullRequest
13 голосов
/ 19 июня 2011

Я бы хотел добиться эффекта легкости с помощью перетаскиваемого Jquery. Но я не нашел вариант в этом плагине. Поэтому мне было интересно, есть ли другие плагины, которые имеют эту опцию - или простое решение.

Эффект, которого я пытаюсь достичь, это что-то такое: http://www.fileden.com/files/2009/6/4/2466215/dragease.swf

Как вы можете видеть, при перетаскивании движение изображения становится намного более плавным из-за ослабления. Я также хотел бы ограничить перетаскивание на одну ось, также необходимо, чтобы оно вернулось на свое место. Draggable в JQuery имеет последние два варианта, и это хорошо.

Пример кода уже дает мне то, что я хочу (кроме смягчения): http://jsfiddle.net/dandoen/NJwER/1/

Буду признателен за любой совет.

Cheers, Dandoen

Ответы [ 3 ]

23 голосов
/ 20 июня 2011

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

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

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

HTML:

<div id="draggable" class="ui-widget-content">
    <p>Revert the original</p>
</div>

CSS:

#draggable {
    position: relative;
    width: 100px;
    height: 100px;
    padding: 0.5em;
    float: left;
    margin: 0 10px 10px 0;
    background-color: red;
    border: 2px solid gray;
}

Javascript:

$(function() {
    $("#draggable").draggable({
        // Can't use revert, as we animate the original object
        //revert: true,

        axis: "y",
        helper: function(){
            // Create an invisible div as the helper. It will move and
            // follow the cursor as usual.
            return $('<div></div>').css('opacity',0);
        },
        create: function(){
            // When the draggable is created, save its starting
            // position into a data attribute, so we know where we
            // need to revert to.
            var $this = $(this);
            $this.data('starttop',$this.position().top);
        },
        stop: function(){
            // When dragging stops, revert the draggable to its
            // original starting position.
            var $this = $(this);
            $this.stop().animate({
                top: $this.data('starttop')
            },1000,'easeOutCirc');
        },
        drag: function(event, ui){
            // During dragging, animate the original object to
            // follow the invisible helper with custom easing.
            $(this).stop().animate({
                top: ui.helper.position().top
            },1000,'easeOutCirc');
        }
    });
});

Демо: http://jsfiddle.net/NJwER/4/

Обновление: перетаскиваемая ось с ограничением

По запросу, вот модифицированный код из этой темы . Оригинал brianpeiris ' блестящее расширение с ограничениями по оси.

Изменить это было очень просто, просто добавили вышеуказанные биты в код и сделали возврат не обязательным. Я переименовал его в draggableXYE (E для облегчения, то есть). Возможно, это не самое элегантное решение, возможно, было бы легко написать его как небольшое расширение для draggableXY, но оно выполнит свою работу.

Перетаскивание кажется довольно интересным, когда вы включаете динамический режим, оно облегчает движение, когда перетаскиваемый объект щелкает от одной оси к другой.

Javascript:

$.fn.draggableXYE = function(options) {
    var defaultOptions = {
        distance: 5,
        dynamic: false
    };
    options = $.extend(defaultOptions, options);

    // ADDED: Store startPosition for reverting
    var startPosition = this.position();

    // ADDED: Function to apply easing to passed element
    function AnimateElement(element, newpos) {
        $(element).stop().animate({
            top: newpos.top,
            left: newpos.left
        }, 1000, 'easeOutCirc');
    }

    this.draggable({
        distance: options.distance,
        // ADDED: Helper function to create invisible helper
        helper: function(){
            return $('<div></div>').css('opacity',0);
        },
        start: function(event, ui) {
            ui.helper.data('draggableXY.originalPosition', ui.position || {
                top: 0,
                left: 0
            });
            ui.helper.data('draggableXY.newDrag', true);
        },
        drag: function(event, ui) {
            var originalPosition = ui.helper.data('draggableXY.originalPosition');
            var deltaX = Math.abs(originalPosition.left - ui.position.left);
            var deltaY = Math.abs(originalPosition.top - ui.position.top);

            var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag');
            ui.helper.data('draggableXY.newDrag', false);

            var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax');
            ui.helper.data('draggableXY.xMax', xMax);

            var newPosition = ui.position;
            if (xMax) {
                newPosition.top = originalPosition.top;
            }
            if (!xMax) {
                newPosition.left = originalPosition.left;
            }

            // ADDED: Animate original object with easing to new position
            AnimateElement(this, newPosition);

            return newPosition;
        },
        // ADDED: Stop event to support reverting
        stop: function() {
            if (options.revert) {
                AnimateElement(this, startPosition);
            }
        }
    });
};

Использование:

$('.drag').draggableXYE({
    revert: true,
    dynamic: true
});

ДЕМО: http://jsfiddle.net/4C9p2/

7 голосов
/ 22 июля 2011

Я видел немало вопросов об ослаблении сопротивления / импульсах.Наконец-то я нашел способ создать плагин из своего решения.Попробуйте здесь:

http://jsfiddle.net/mattsahr/bKs7w/

Основное использование не вызывает затруднений.


    $('.dragme').draggable().dragMomentum();

Это приводит в порядок некоторые более ранние работы из этого вопроса .

Примечания - СОДЕРЖАНИЕ - .dragMomentum довольно хорошо работает с опцией «сдерживание», заменяет нормальное поведение приятным действием возврата при отпускании.И он делает ту же привязку назад с края окна браузера, если нет контейнера div.

СОВМЕСТИМОСТЬ - Работает на ie9, chrome12, firefox5.Прошлое, я не знаю.

7 голосов
/ 19 июня 2011

Я не думаю, что у draggable есть возможность для этого. Возможно, вам придется свернуть свой собственный. Если вы решите, вы можете сделать что-то вроде этого:

http://jsfiddle.net/NJwER/2/

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

$(function() {
    var dragging = false;
    var dragger, offsetX, offsetY;

    $("#draggable").mousedown(function(e) {
        dragging = true;
        dragger = this;
        offsetX=e.offsetX;
        offsetY=e.offsetY;
    });

    $("body").mouseup(function(e) {
        dragging = false;
    }).mousemove(function(e) {
        if (dragging) {
            $(dragger).stop().animate({left:e.pageX-offsetX, top:e.pageY-offsetY},300);
            console.log(e.pageX+" "+e.pageY);
        }
    });
});​
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...