jqueryanimationdelaydurationjquery-backstretch

backstretch.js duration out of sync with .animate() delay


Preface: I am new to writing my own jQuery code and have had help writing the animateContinously() function below.

I'm using backstretch.js to have a full browser viewport/background slideshow and jQuery animate() function to change the color (with the help of the jquery-color.js plugin) of the text that shows on top of the backstretch controlled images, depending on which backstretch image is showing. It works, but the backstretch() duration and animate() delay are out of sync if I set them to the same number, ie: 5000 (5 seconds). So I tried offsetting them by 1000 (1 second) and the text and backstretch images fade-in/out at the exact same time, as desired...but after 15 or so transitions they fall out of sync again.

Any ideas/help as to why the same duration & delay time amount doesn't work? And/or why the 1 second offset works at first and then falls out of sync? Here is my code:

<script src="jquery.js"></script>
<script src="jquery-color.js"></script>
<script src="backstretch.js"></script>
<script>
  $.backstretch([
  "_img/bg01.jpg",
  "_img/bg02.jpg"
  ], {
  fade: 1000,
  duration: 4000
  });
</script>
<script>
    function animateContinuously($element, attr, values) {
    var i = 0, count = values.length;
    setInterval(function() {
        i = (i + 1) % count;
        var props = {};
        props[attr] = values[i];
        $element.animate(props, 1000);
    }, 5000); // // in sync with backstretch() if 1000 more, but falls out of sync after 15-18 transitions

    animateContinuously($("#color-change1"), 'color', ['#de7056', '#4ec67f']);
    animateContinuously($("#color-change2"), 'svgFill', ['#de7056', '#4ec67f']);
</script>
</body>

Solution

  • Since the cycling of the background images and setInterval() are not tied together, they are just always going to fall out of sync. The solution is to abandon setInterval(), and instead use the events triggered by the Backstretch plugin. You would start your animations when the "backstretch.before" event is triggered.

    $(window).on('backstretch.before', function() {
        // Start animations here.
    });
    

    If the number of images, colors, and other values to be animated are all the same, you could have:

    var TRANSITION_DURATION = 1000,
        PAUSE_DURATION = 4000;
    
    // Note: These arrays should all have the same length.
    var IMAGES = ['_img/bg01.jpg', '_img/bg02.jpg'],
        COLORS = ['#de7056', '#4ec67f'];
    
    var index = 0;
    
    $.backstretch(IMAGES, {
        fade: TRANSITION_DURATION,
        duration: PAUSE_DURATION
    });
    
    $(window).on('backstretch.before', function() {
        index = (index + 1) % IMAGES.length;
        $('#color-change1').animate({ backgroundColor: COLORS[index] }, TRANSITION_DURATION);
        $('#color-change2').animate({ svgFill: COLORS[index] }, TRANSITION_DURATION);
    });
    

    jsfiddle

    If the arrays of values are not all the same length, you could do something like in this jsfiddle.