I have an animation linked to scroll position. Whenever the the user scrolls up or down, an animation is triggered for that position to move an element within the view window. If the user scrolls farther, these animations need to queue so that the element moves smoothly along the path.
var target = getAnimation();
var props = {
left: [target.x, target.easing],
top: target.y
};
$("#ball").animate(props, 400, "easeInOutQuad");
The problem with this is that when multiple animations get queued, the ball slows and speeds up in a bad way. What I'd like to do is something like this:
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");
}
By starting with an easeIn function, using linear in the middle, and easeOut at the end, I get a much smoother animation. Is there anyway I can access and modify the animations in the queue?
Edit:
Here is a fiddle to demonstrate what I'm trying to achieve: https://jsfiddle.net/reesewill/mtepvguw/
In the fiddle, I am using linear easing, but I'd really like the general affect to be more like easeInOutQuad. However, because I allow queueing, I can't just apply that easing function without it messing up the whole effect (change the linear to easeInOutQuad and click queue a few times quickly to see). Thus, I need something like the above to create the general impression of easeInOutQuad.
Note
, $(selector)
.queue() returns a reference to the animation queue, an Array. This reference can be modified with standard array methods. See also .dequeue() .
Try utilizing
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.
See also 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>
i tried, you can do it with create new (re-ordered) queue
download source http://api.jquery.com/queue/
Example: Set a queue array to delete the queue.
and replace start event with my, its worked.
But functions in queue are stored in array of functions. You need to know order of original queue of animations which you want to changed :( Or you can create new optimalized 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"));
});
more info found in jquery documentation
.queue( [queueName ], newQueue )
Description: Manipulate the queue of functions to be executed, once for each matched element.
important is second parameter newQueue
i hope it helps