0

这与其说是一个 jQuery 问题,不如说是一个整体概念问题。在我的示例中,我可以使用具有以非线性方式设置的最高值的 div 填充容器。每一个的顶部值是根据一个公式计算的,该公式考虑了它左侧的顶部位置以及容器的高度(小提琴的第 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,因为子 div 已经被添加到具有正确堆叠顺序的父级 - 最左边的子级是容器中的最后一个元素。

计算每个孩子的高度取决于#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 回答