JQuery 可轻松拖动

发布于 2024-11-16 03:04:21 字数 526 浏览 3 评论 0原文

我想用Jquery的draggable来实现ease效果。但我在这个插件中没有找到这个选项。所以我想知道是否有其他插件有这个选项 - 或者一个简单的解决方案。

我想要达到的效果是这样的: http:// www.fileden.com/files/2009/6/4/2466215/dragease.swf

如您所见,拖动时,图像移动感觉更加平滑,因为缓和。我还想将拖动限制在一个轴上,还需要使其恢复到原来的位置。 JQuery 的可拖动确实有最后两个选项,所以这很好。

示例代码已经为我提供了我想要的(除缓动之外): http://jsfiddle.net/ dandoen/NJwER/1/

如有任何建议,我们将不胜感激。

干杯, 丹东园

I would like to achieve the ease effect with Jquery's draggable. But I did not find the option in this plugin. So I was wondering if there are other plugins that have this option - or an easy solution.

The effect I am trying to achieve is something this: http://www.fileden.com/files/2009/6/4/2466215/dragease.swf

As you can see, upon dragging, the image movement is feeling much smoother because of the easing. I would also like to constraint the dragging to one axis, also need to make it revert back to its place. JQuery's draggable does have this last two options, so thats nice.

The example code already provides me with what I want (except the easing): http://jsfiddle.net/dandoen/NJwER/1/

Any advise would be appreciated.

Cheers,
Dandoen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请别遗忘我 2024-11-23 03:04:21

您可以使用原始的可拖动项,但需要几行额外的代码。我们创建一个不可见的助手,并手动为原始对象设置动画,以使用自定义缓动来跟随它。您可以使用动画持续时间和缓动函数来自定义效果。

如果您要使用任何可拖动对象,当鼠标悬停在它们上方时,它们应该正确激活,而不必等待对象到达那里。

唯一的缺点是,当我们手动更改原始元素的位置时,无法使用 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/

You can use the original draggable, but you will need a few lines of extra code. We create an invisible helper and manually animate the original object to follow it with custom easing. You can play with the animation duration and the easing function to customise the effect.

In case you would use any draggables, they should be properly activating when the mouse hovers over them without having to wait for the object to get there.

The only drawback is that as we're changing the original element's position manually, the revert parameter can't be used, but it can be easily sorted out by saving the starting position and animating the object back when dragging stops.

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');
        }
    });
});

Demo: http://jsfiddle.net/NJwER/4/

Update: Constrained-axis draggable

As requested, here's the modified code from this thread. The original is brianpeiris' brilliant axis-constrained draggables extension.

Changing it was very simple, just added the above bits to the code and made reverting optional. I renamed it to draggableXYE (E for easing that is). It might not be the most elegant solution, it would probably be easy to write it as a small extension to the draggableXY, but it will do the job.

Dragging feels quite interesting when you switch dynamic mode on, it eases movement when the draggable snaps from one axis to the other.

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);
            }
        }
    });
};

Usage:

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

DEMO: http://jsfiddle.net/4C9p2/

兮颜 2024-11-23 03:04:21

我见过很多关于阻力缓和/势头的问题。我终于开始从我的解决方案中制作一个插件。在这里尝试一下:

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

基本使用很简单。

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

它整理了这个问题的一些早期工作。

注释——
CONTAINMENT——.dragMomentum 与“containment”选项配合得很好,当你放手时,用一个漂亮的弹回动作代替正常行为。如果没有容器 div,它会对浏览器窗口执行相同的从边缘弹回操作。

兼容性——适用于 ie9、chrome12、firefox5。过去了,我不知道。

I've seen a fair number of questions about drag easing/momentum. I finally got around to making a plugin from my solution. Try it here:

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

Basic use is straightforward.

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

It tidies up some earlier work from this question.

Notes --
CONTAINMENT -- .dragMomentum works pretty well with the "containment" option, replaces the normal behavior with a nice snap-back action when you let go. And it does the same snap-back-from-edge with the browser window if there's no container div.

COMPATIBILIEY -- It works on ie9, chrome12, firefox5. Past that, I dunno.

(り薆情海 2024-11-23 03:04:21

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

I don't think draggable has an option for that. You may need to roll your own. If you choose to, you may want to do something like this:

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

this is really rough (but was sort of interesting). You would probably want to make the animation duration dynamic based on how far the element was from your cursor and use an easing other than the default.

$(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);
        }
    });
});​
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文