I need to have multiple animations cycling, or randomly changing, every time animation occurs on single function.
Currently there's a fade, what I want is to cycle through for example fade, toggle, animate, etc
Here is my code i need it to be used in:
var items = $(".items").on("click", "div", function() {
var not = $.map($(".items div").not(this), function(el) {
return $(el).index(".items div")
});
var next = not[Math.floor(Math.random() * not.length)];
var index = $(this).index(".items div");
var elems = $(">div", items).toArray();
[elems[next], elems[index]] = [elems[index], elems[next]];
$(this).add(items.find("div").eq(next)).fadeTo(600, 0, function() {
items.html(elems).find("div").fadeTo(600, 1)
});
});
I cant find any information about this anywhere but I saw it being used in some scripts, thanks a lot for ideas
Initial version was simpler, but slightly bugged as the effect callbacks for the swap get called twice. New version at the bottom:
JSFiddle: https://jsfiddle.net/TrueBlueAussie/w8cmvu1m/5/
The transitions are queued up in this example using .then()
$(function() {
// Swap the html of two elements
var swap = function($elements) {
var val = $elements.eq(0).html();
$elements.eq(0).html($elements.eq(1).html());
$elements.eq(1).html(val);
};
// Array of effects functions - each takes 2 jQuery elements and swaps the values while not visible
// Each returns a promise that resolves once the animation has completed
var effects = [
// fade in/out
function($elements) {
return $elements.fadeOut(function() {
swap($elements);
}).fadeIn().promise();
},
// Animate
function($elements) {
return $elements.slideUp(function() {
swap($elements);
}).slideDown().promise();
}
];
// Start with a resolved promise
var promise = $.when();
// Delegated handler for click on items
$(document).on("click", ".items div", function() {
// All items except this one
var $item = $(this);
var $notThis = $(".items div").not($item);
// Randomly choose another item
var $other = $notThis.eq(Math.floor(Math.random() * $notThis.length));
// Randomly choose an effect
var effect = Math.floor(Math.random() * effects.length);
promise = promise.then(effects[effect]($item.add($other)));
});
var interval = setInterval(function() {
var $items = $('.items div');
$items.eq(Math.floor(Math.random() * $items.length)).click()
}, 3000);
});
Updated: https://jsfiddle.net/TrueBlueAussie/w8cmvu1m/6/
I corrected the double-callback issue using deferreds and promises, but not happy with the solution:
var effects = [
// fade in/out
function($elements) {
var def = $.Deferred();
$elements.fadeOut(500).promise().always(function() {
swap($elements);
$elements.fadeIn(500).promise().always(function(){
def.resolve();
});
});
return def.promise();
},
// Animate
function($elements) {
var def = $.Deferred();
$elements.slideUp(500).promise().always(function() {
swap($elements);
$elements.slideDown(500).promise().always(function(){
def.resolve();
});
});
return def.promise();
}
];