3

I am trying to rotate CSS backgrounds by calling setTimeout on functions, however the code doesn't work as expected. There is only one transition, and then it skips to the last image right away.

JsFiddle

var func = function () { 

    setTimeout( function(){
      $('#rotator').css("background-image", "url(http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/diamond_upholstery.png)"); 
    },2000);

    setTimeout( function(){
      $('#rotator').css("background-image", "url(http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/subtle_stripes.png)"); 
    },2000);

    setTimeout( function(){
      $('#rotator').css("background-image", "url(http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/struckaxiom.png)"); 
    },2000);

    setTimeout( function(){
      $('#rotator').css("background-image", "urlhttp://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/dark_stripes.png)"); 
    },2000);

    setTimeout(func, 0);

}
setTimeout(func, 0);

Thanks

4 Answers 4

2

You can use setInterval instead of setTimeout:

var i = 0;
var rotator = document.querySelector('#rotator');
var path = 'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/';

var backgrounds = [
'diamond_upholstery',
'subtle_stripes',
'struckaxiom',
'dark_stripes'
];

function func(i) {
setInterval(function(){
if (i === (backgrounds.length-1)) {i = 0;} else {i++;}
rotator.style.backgroundImage = 'url(' + path + backgrounds[i] + '.png)';}, 2000);
}

window.onload = func(i);
#rotator {
width: 160px;
height: 160px;
background-image:url('http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/diamond_upholstery.png');
}
<div id="rotator">
</div>

Sign up to request clarification or add additional context in comments.

Comments

2

You can do without a lot of the setTimeouts, try something like this:

var func = function () {
    var images = [
        'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/diamond_upholstery.png',
        'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/subtle_stripes.png',
        'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/struckaxiom.png',
        'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/dark_stripes.png'
    ]; 
    var state = $('#rotator').data('background-image-state');
    var newState = state % images.length;
    $('#rotator').data('background-image-state', newState);
    $('#rotator').css("background-image", "url("+images[newState]+")");

    setTimeout(func, 2000);

}
$('#rotator').data('background-image-state', 0);
setTimeout(func, 0);

Comments

1

Change the duration of your timeouts to be different, right now they all end at the same time (2000ms). If you want each to be 2000ms a part, make them 2000, 4000, 6000, 8000.

5 Comments

But doesn't 2000ms mean that it executes 2sec after the last statement has finished? I tried your solution, and it created some unintended consequences as time went on: jsfiddle.net/e2fr5o0q/1
Hmm, so what is causing the issue in the effect becoming unstable over time? jsfiddle.net/e2fr5o0q/2
@pufAmuf because timeouts lose sync: ejohn.org/blog/how-javascript-timers-work This would fix it but... jsfiddle.net/e2fr5o0q/3 Better would be to set an infinite animation in CSS
I just answered why the initial delay didn't work. According to your fiddle, now the first images have a delay. The real problem is you are setting timeouts with no delay which is the cause for the strobing.
Ahh okay, I will keep that in mind next time. Thank you!
1

You should use callback functions. Following is the Fiddle depicting the same.

Code

function updateImage(url, callback) {
    var _url = 'http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/';
    _url += url;
    $('#rotator').css("background-image", "url(" + _url + ")");
    setTimeout(function () {
        callback();
    }, 2000);
}

var func = function () {
    updateImage("diamond_upholstery.png",
    function () {
        updateImage("subtle_stripes.png",
        function () {
            updateImage("struckaxiom.png",
            function () {
            	updateImage("dark_stripes.png",
                           function(){})
            });
        })
    });
}
setTimeout(func, 2000);
#rotator {
    width: 200px;
    height: 200px;
    display: block;
    background-image: url(http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/diagmonds.png);
    transition: background 0.5s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rotator"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.