13

Jquery のドラッグ可能で容易な効果を達成したいと思います。しかし、このプラグインにはオプションが見つかりませんでした。したがって、このオプションを備えた他のプラグイン、または簡単な解決策があるかどうか疑問に思っていました。

私が達成しようとしている効果はこれです:http://www.fileden.com/files/2009/6/4/2466215/dragease.swf

ご覧のとおり、ドラッグすると、イージングのおかげで画像の動きが非常にスムーズに感じられます。また、ドラッグを1つの軸に制限したいと思います。また、元の場所に戻す必要があります。JQuery のドラッグ可能なものには、この最後の 2 つのオプションがあるので、それは素晴らしいことです。

サンプルコードは、私が望むものをすでに提供しています (イージングを除く): http://jsfiddle.net/dandoen/NJwER/1/

アドバイスをいただければ幸いです。

乾杯、ダンドーエン

4

3 に答える 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/

更新: 拘束軸のドラッグ可能

リクエストに応じて、このスレッドから変更されたコードを次に示します。オリジナルは、brianpeiris による見事な軸制限付きのドラッグ可能拡張です。

変更は非常に簡単で、上記のビットをコードに追加し、元に戻すことをオプションにしました。draggableXYE名前を(イージングの E)に変更しました。これは最も洗練された解決策ではないかもしれません。 への小さな拡張としてそれを書くのはおそらく簡単でしょうが、それでdraggableXYうまくいきます。

動的モードをオンにすると、ドラッグが非常に面白く感じられます。ドラッグ可能な軸が 1 つの軸から別の軸にスナップすると、動きが楽になります。

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/

于 2011-06-20T00:13:06.607 に答える
7

ドラッグ イージング/モメンタムに関するかなりの数の質問を見てきました。私は最終的に自分のソリューションからプラグインを作成することに取り掛かりました。ここで試してください:

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

基本的な使い方は簡単です。

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

この質問から以前の作業を整理します。

注 -- 封じ込め -- .dragMomentum は、「封じ込め」オプションと非常にうまく連携します。通常の動作を、手放したときのスナップバック アクションに置き換えます。また、コンテナー div がない場合は、ブラウザー ウィンドウで同じスナップバック フロム エッジを実行します。

互換性 -- ie9、chrome12、firefox5 で動作します。それを過ぎると、わかりません。

于 2011-07-21T22:44:43.530 に答える
7

ドラッグ可能にそのためのオプションがあるとは思いません。自分で巻く必要があるかもしれません。選択した場合は、次のようなことを行うことができます。

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);
        }
    });
});​
于 2011-06-18T21:58:40.900 に答える