JQuery可拖拽插件的简单使用方法

13
我希望使用Jquery的可拖动插件实现缓动效果,但是在该插件中没有找到这个选项。所以我想知道是否有其他插件具备此选项或者有简单的解决方案。
我尝试要达到的效果如下:http://www.fileden.com/files/2009/6/4/2466215/dragease.swf 如您所见,在拖动时,由于缓动效果,图像移动感觉更加平滑。我还想限制拖动到一个轴上,并使其恢复到原来的位置。JQuery的可拖动插件确实具有这最后两个选项,这很好。
示例代码已经为我提供了我想要的东西(除了缓动效果):http://jsfiddle.net/dandoen/NJwER/1/ 任何建议将不胜感激。
谢谢, Dandoen
3个回答

23

您可以使用原始的可拖动对象,但需要添加几行额外的代码。我们创建一个不可见的辅助对象,并手动使用自定义缓动函数使原始对象跟随它进行动画处理。您可以根据需要调整动画持续时间和缓动函数以定制效果。

如果您使用任何可拖动对象,则应在鼠标悬停在其上时正确激活它们,而无需等待对象到达。

唯一的缺点是,由于我们手动更改了原始元素的位置,因此无法使用还原参数,但可以通过保存起始位置并在拖动停止时将对象动画回来轻松解决。

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/

更新:约束轴可拖动

根据要求,这是来自this thread的修改后的代码。原始版本是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/


1
非常感谢!不过有一个小问题,您知道我如何实现brianpeiris的代码[链接](https://dev59.com/4nI_5IYBdhLWcg3wAd82),以便允许用户水平和垂直拖动,但一次只能在一个轴上移动。 - dandoen
@dandoen:我加入了修改过的brianpeiris扩展,包含缓动和可选的回归功能。享受吧。 - DarthJDG
太棒了!!谢谢伙计,真希望我能给你更多的赞哈哈。 - dandoen
很棒的东西。我该如何修改 draggableXYE 以仅限制在 x 轴上拖动? - sooper
@sooper 你可以将 deltaXdeltaY 设置为零,以强制仅使用单个轴,你可以添加一个选项或删除一些代码来实现。 - DarthJDG
显示剩余2条评论

7

我认为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);
        }
    });
});​

我不会基于距离来计算时间,特别是如果你使用了其中一个easeOut函数。 - nkorth

7

我看到了很多关于拖动缓动/动量的问题。最终,我从我的解决方案中制作了一个插件。在这里试试:

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

基本使用非常简单。

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

它可以整理一些早期工作,来自这个问题

注意事项-- 容器 -- .dragMomentum 在“containment”选项上运行得非常好,用一个漂亮的弹回操作替换了正常的行为,当你松开时。如果没有容器 div,它也会在浏览器窗口边缘处进行相同的弹回操作。

兼容性 -- 它可以在ie9、chrome12、firefox5上运行。过了这个版本,我就不知道了。


看起来很不错。考虑使用MIT或类似的许可证进行授权如何? - Stas Bichenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接