更改 jQuery 队列中动画的缓动函数

Change easing functions on animations in jQuery queue

我有一个链接到滚动位置的动画。每当用户向上或向下滚动时,都会为该位置触发动画以在视图中移动元素 window。如果用户滚动得更远,这些动画需要排队,以便元素沿着路径平滑移动。

var target = getAnimation();
var props = {
    left: [target.x, target.easing],
    top: target.y
};

$("#ball").animate(props, 400, "easeInOutQuad");

问题是当多个动画排队时,球会以糟糕的方式减速和加速。我想做的是这样的:

var target = getAnimation();
var props = {
    left: [target.x, target.easing],
    top: target.y
};

var ball = $("#ball"), queue = ball.queue();

if(ball.queue().length) {
    for(var i = 1, len = queue.length; i < len; i++) {
        //modify all the other queued animations to use linear easing
    }
    ball.animate(props, 400, "easeOutQuad");
}
else {
    ball.animate(props, 400, "easeInQuad");
}

从 easeIn 函数开始,在中间使用 linear,在最后使用 easeOut,我得到了一个更流畅的动画。无论如何我可以访问和修改队列中的动画吗?

编辑:

这是一个 fiddle 来演示我正在努力实现的目标:https://jsfiddle.net/reesewill/mtepvguw/

在 fiddle 中,我使用的是线性缓动,但我真的希望整体效果更像 easeInOutQuad。但是,因为我允许排队,所以我不能只应用缓动函数而不弄乱整个效果(将线性更改为 easeInOutQuad 并快速单击队列几次以查看)。因此,我需要类似上面的内容来创建 easeInOutQuad 的一般印象。

我试过了,你可以通过创建新的(重新排序的)队列来做到这一点

下载源码http://api.jquery.com/queue/
示例:设置队列数组删除队列。

并将开始事件替换为我的,成功了。

但是队列中的函数存储在函数数组中。您需要知道要更改的原始动画队列的顺序:( 或者您可以创建新的优化队列。

$( "#start" ).click(function() {
  $( "div" )
    .show( "slow" )
    .animate({ left: "+=50" }, 5000 )
    .animate({ top: "+=50" }, 5000 )
    .queue(function() {
      $( this ).addClass( "newcolor" ).dequeue();
    })
    .animate({ left: '-=50' }, 1500 )
    .queue(function() {
      $( this ).removeClass( "newcolor" ).dequeue();
    })
    .slideUp();


    // get current queue
    var currQueue = $( "div" ).queue( "fx");

    // create new queue and change order or add/remove animations
    var newQueue = [];
      newQueue.push(currQueue[1]);
      newQueue.push(currQueue[3]); // changed
      newQueue.push(currQueue[2]); // changed
      newQueue.push(currQueue[5]);

    // set new queue to element
    $("div").queue("fx", newQueue);

    console.log($("div").queue("fx"));
}); 

jquery documentation

中找到更多信息

.queue( [queueName ], newQueue )
描述:操纵要执行的函数队列,对每个匹配的元素执行一次。

重要的是第二个参数newQueue

希望对你有帮助

备注 , $(selector).queue() returns a reference to the animation queue, an Array. This reference can be modified with standard array methods. See also .dequeue() .

尝试利用

Array.prototype.splice()

Summary

The splice() method changes the content of an array by removing existing elements and/or adding new elements.

Syntax

array.splice(start, deleteCount[, item1[, item2[, ...]]]) Parameters

start

Index at which to start changing the array. If greater than the length of the array, actual starting index will be set to the length of the array. If negative, will begin that many elements from the end.

deleteCount

An integer indicating the number of old array elements to remove. If deleteCount is 0, no elements are removed. In this case, you should specify at least one new element. If deleteCount is greater than the number of elements left in the array starting at start, then all of the elements through the end of the array will be deleted.

itemN

The element to add to the array. If you don't specify any elements, splice() will only remove elements from the array.

Returns

An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.

另见 Array.prototype.concat()


var elem = $("body")
, msg = function() {
    return "<br />" 
           + "queue length:" 
           + $(this).queue("abc").length
  };

elem.queue("abc", [
  function(next) {
    $(this).append(msg.call(this));
    next()
  },
  function(next) {
    $(this).append(msg.call(this));
    next()
  },
  function(next) {
    $(this).append(msg.call(this));
    next()
  }
]);

elem.append(msg.call(elem));

// do stuff, 
// replace `function` within `abc` queue,
// change `easing` options within replacement function 
elem.queue("abc").splice(1, 1, function(next) {
  $(this).append("<br />" 
                 + "`function` at index `1` within `abc` queue " 
                 + "replaced with new `function`" 
                 + msg.call(this));
  next()
});

elem.append("<br />" 
            + "after `.splice()` , before `.concat()`" 
            + msg.call(elem));
// do stuff,
// `concat` functions onto `abc` queue`
var arr = elem.queue("abc").concat(
  function(next) {
    $(this).append(msg.call(this));
    next()
  }, function(next) {
    $(this).append(msg.call(this));
    next()
  }, function() {
    $(this).append(msg.call(this) 
                   + "<br />" 
                   + "done");
  }
);

elem.queue("abc", arr);

elem.append("<br />" 
            + "after `.concat()`"
            + msg.call(elem));

elem.dequeue("abc");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>