0

これは全体的な概念的な質問であるため、jQuery に関する質問ではありません。私の例では、上位の値が非線形に設定された div をコンテナーに取り込むことができます。それぞれの上部の値は、左にあるものの上部の位置とコンテナーの高さを考慮した式に基づいて計算されます (fiddle の 33 行目)。

//this formula sets the top value for each new child added to the container
//height is 100% of its parent which is 20% of the body
//newOne:last is the most recently added child and will have an initial top value of 10%
parseInt($(this).next().css('top'), 10) / $('#queue').height()) * 75  + (parseInt($('.newOne:last').css('top'), 10) * 2) + '%'

私は偶然にこれに出くわすことはあまりなく、「問題なく」動作しているように見えますが、最適化が明らかな場合は指摘してください:)ドラッグ イベント中に子をスムーズに処理します。左オフセットの操作に基づいて上部の値を調整する必要があると考えていますが、何時間もの実験の後、ドラッグを開始したときに元の位置をそのまま維持し、ドラッグ中に値をスムーズに調整し続けるものは見つかりませんでした引っ張る。左にドラッグすると、子は徐々に 10% の最小上限値に近づき (左オフセットが 0 の子は上限値が 10% になります)、右にドラッグすると、その上限値から徐々に元の位置に戻ります。 .

$('#queue').draggable({
    axis: "x",
    scroll: false,
    drag: function(){
        //adjust values of each child
        $('.newOne').each(function(){
            var percentLeft = $(this).offset().left / $('footer').width() * 100
            var thisLeft = parseInt($(this).css('left'), 10) / $(window).width() * 100;
            var thisTop = parseInt($(this).css('top'), 10) / $('#queue').height() * 100;
            if (percentLeft >= 0){
                //top value of each one gradually decreases...
                //as it gets closer to an offset value of 0 and minimum top value of 10%
                //non-linear attempt but not even close
                //$(this).css('top', $(this).css('top', 10 + (thisTop - 10 / thisLeft) + '%'));

                //linear step
                $(this).css({'top': 8 + (percentLeft/2) + '%'});
            }
        });
    }
});

http://jsfiddle.net/5RRCS/17/

PS私はここで多くのことを尋ねていることを知っていますが、うまくいけば誰かが挑戦します:)

更新: exp メソッドに出くわし、次のようなことをしました:

adjustTop = function(offset){
    return 100 * (1.0-Math.min(0.98,(0.83 + ( 0.17/ (Math.exp(0.007*offset))) )) ) + '%';
};
$(this).css('top', adjustTop($(this).offset().left) );
4

1 に答える 1

1

これは、あなたが探していることを行うと私が信じているバージョンです。

私が最初にしたことは、初期化ハンドラーとドラッグ ハンドラーの両方が同じ結果になるように、最上位の計算をリファクタリングすることでした。

ドキュメントへのオフセットに基づいて子 div の位置を計算するのではなく、コンテナーに対する相対位置を使用するようにロジックを変更しました。

また、子 div が正しいスタック順序で親に追加されているため、z-index も削除します。左端の子はコンテナー内の最後の要素です。

各子の高さの計算は、#queueの現在の位置が原点の左か右かによって異なります。

また、現在の要素の開始オフセットの計算を簡素化するために、反復ロジックも同じように動作するように変更します。

$($('.newOne').get().reverse()).each(function (index) {
    $(this).css({
        'background': 'rgba(255,255,255,.80)',
        'top': calcTop($(this), index)
    });
});

子要素を配置するためのコード:

function calcTop($ele, index) {
    var elePositionLeft   = $ele.position().left;
    var queuePositionLeft = $('#queue').position().left;
    var footerWidth       = $('footer').width();
    var queueHeight       = $('#queue').height();
    var distanceToTravel  = queuePositionLeft < 0 ? elePositionLeft : footerWidth - elePositionLeft;
    var percentTraveled   = Math.abs(queuePositionLeft) / distanceToTravel;
    var thisPercentLeft   = (elePositionLeft + queuePositionLeft) / footerWidth;
    var queuePercentLeft  = queuePositionLeft / footerWidth;
    var newTop;

    var myStartOffset = (index + 1) * startOffset;
    var topTravel = queuePositionLeft < 0 ? -myStartOffset + startOffset : (queueHeight - startOffset);

    var linear = false;
    if (linear) {
        newTop = myStartOffset + (topTravel * percentTraveled);
        newTop = newTop > startOffset ? Math.round(newTop) : startOffset;
        return newTop;
    } else {
        if (queuePositionLeft >= 0) {
            newTop = myStartOffset + (topTravel * thisPercentLeft * percentTraveled);
            newTop = newTop > startOffset ? Math.round(newTop) : startOffset;
        } else {
            newTop = myStartOffset + (topTravel * (1+thisPercentLeft) * percentTraveled);
            newTop = newTop < startOffset ? startOffset : Math.round(newTop);
        }
        return newTop;
    }
}

リセット関数にも小さなバグがありました - childCount をゼロに戻していませんでした:

$('#reset').click(function () {
    $('#queue').empty().css('left', 0);
    childCount = 0;
});

デモフィドル

于 2013-09-08T22:08:15.193 に答える