KDJ
KDJ

Reputation: 307

Modifying to make script crossfade instead of fade out & then fade in

The following script is set to fade out, and then fade in the next banner set. I would like to find out how to modify this to be a crossfade so the next banner set fades in on top of the existing one, and then it disappears. It would just look a lot cleaner.

I've seen a bunch of scripts for crossfade; however, because this script fades "children" elements, not sure how to modify them to make this work.

If there is a better way to do this, please let me know,

$(function () {

    /* SET PARAMETERS */
    var change_img_time     = 9000; 
    var transition_speed    = 1000;

    var simple_slideshow    = $("#graphic_1"),
        listItems           = simple_slideshow.children('.banner'),
        listLen             = listItems.length,
        i                   = 0,

        changeList = function () {

            listItems.eq(i).fadeOut(transition_speed, function () {
                i += 1;
                if (i === listLen) {
                    i = 0;
                }
                listItems.eq(i).fadeIn(transition_speed);



            });

        };

    listItems.not(':first').hide();
    setInterval(changeList, change_img_time);


});

html/php (Just so y'all can see how the data looks)

$rotban1 = $db1->query("SELECT background_image, background_image_alt, foreground_image, foreground_image_alt, text FROM banner") or die ('Unable to execute query. '. mysqli_error($db1con));
$slidecount == 0;
    if ($rotban1->num_rows > 0) {
while ($slide = $rotban1->fetch_assoc()) {

echo '<div class="banner">';
echo '<img class="background_image" alt="'. $slide['background_image_alt'] .'" src="'. $slide['background_image'] .'">';
    echo '<img class="foreground_image" alt="'. $slide['foreground_image_alt'] .'" src="'. $slide['foreground_image'] .'">';
    if (!empty( $slide['text'])) { echo '<h1>'. $text .'</h1>'; }
echo '</div>';
}
    }

Upvotes: 1

Views: 136

Answers (3)

guest271314
guest271314

Reputation: 1

You can use css transition and opacity, position:absolute, setTimeout() and .eq() to "crossfade" elements opacity rendering

function crossFade(n) {
  setTimeout(function() {
    $("div img").eq(n).css("opacity", 0);
    $("div img").eq(n).prev("img").css("opacity", 1);
    setTimeout(function() {
      if (--n > 0) {
        crossFade(n)
      } else {
        setTimeout(function() {
          $("div img").css("opacity", 0).eq(len)
            .css("opacity", 1);
          setTimeout(function() {
            crossFade(len)
          }, 1500)
        }, 1500)
      }
    }, 1500)
  }, 1500)
}

const len = $("div img").length - 1;

crossFade(len);
body {
  width: 100vw;
  overflow: hidden;
}

div {
  position: relative;
  width: 200px;
  height: 200px;
  left: calc(50vw - 100px);
}

div img {
  transition: opacity 3s ease-in-out;
  position: absolute;
}

div img:not(:nth-child(3)) {
  opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div>
  <img src="https://lorempixel.com/200/200/cats" alt="">
  <img src="https://lorempixel.com/200/200/nature" alt="">
  <img src="https://lorempixel.com/200/200/sports" alt="">
</div>

Upvotes: 1

Scott Marcus
Scott Marcus

Reputation: 65845

Instead of calling one effect when the first one finishes, use the .animate() method with the queue option set to false and run them both at the same time.

changeList = function () {

  listItems.eq(i).animate(
    { opacity:0 }, 
    {
      queue: false,
      duration: 3000
  });

  i += 1;
  if (i === listLen) {
    i = 0;
  }

  listItems.eq(i).animate(
    { opacity:1 }, 
    {
      queue: false,
      duration: 3000
  });

};

Here's a working example:

$("#red").animate({
      opacity:0
    }, {
      queue: false,
      duration: 3000
});

$("#blue").animate({
      opacity:1
    }, {
      queue: false,
      duration: 3000
});
div { width:50px; height:50px; position:absolute; top:0; }
#red { background:red; }
#blue { background:blue; opacity:0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="red">

</div>
<div id="blue">

</div>

Upvotes: 2

er-han
er-han

Reputation: 1921

You call fadeIn after fadeOut finishes.

Try calling them both at the same time, to do that don't use callback function:

changeList = function () {
    listItems.eq(i).fadeOut(transition_speed);
    i += 1;
    if (i === listLen) {
        i = 0;
    }
    listItems.eq(i).fadeIn(transition_speed);
};

This way, fadeOut and fadeIn animations start at the same time (ignore miliseconds)

Upvotes: 1

Related Questions