Happy Coder
Happy Coder

Reputation: 4682

Smooth transition while changing background image

I have the following jQuery to change the body background image.

(function($, interval, slides) {

        var gradient = "linear-gradient(0deg,rgba(0,0,255,0.3),rgba(0,0,255,0.3))";
        $('body').css("background", gradient+", url('" + slides[slides.length-1] + "')");

          var i = 0;
          var handle = setInterval(function () {

          var bg =  gradient+", url('" + slides[i] + "')";
          $('body').css('background', bg);

              i++;

              if (i >= slides.length) {
                  i = 0;
              }
          }, interval);

      })(jQuery, 5000, [
          "https://source.unsplash.com/CgOaFB56Vyw/1920x1080",
          "https://source.unsplash.com/18Q4c6EVf_o/1920x1080",
          "https://source.unsplash.com/7uvHtSn5a90/1920x1080"
      ]);

Now the problem I am facing is, the change in background property changes are not smooth. Is there any way that I can use the transition property here to ease the change in the background image and gradient and to make it more smooth?. I have tried using transition: background-image 3s ease but this has no effect. Please find my code in the following fiddle.

https://jsfiddle.net/gw6ndfby/2/

Upvotes: 0

Views: 511

Answers (1)

shrys
shrys

Reputation: 5940

This answer would be relevant in your case, which tells that CSS3 doesn't support transitions for gradients. Also, you would want to apply css to background-image. I tried to encapsulate image loading logic around applying the css to make the transition smooth (no gradient):

(function($, interval, slides) {
  var gradient = "linear-gradient(0deg,rgba(0,0,255,0.3),rgba(0,0,255,0.3))";
  const img = new Image();
  img.onload = function() {
    $('body').css("background-image", "url('" + img.src + "')");
  }
  img.src = slides[slides.length - 1];

  var i = 0;
  var handle = setInterval(function() {
    const img2 = new Image();
    img2.onload = function() {
      var bg = "url('" + img2.src + "')";
      $('body').css('background-image', bg);
      i = (i + 1) % slides.length;
    }
    img2.src = slides[i];
  }, interval);

})(jQuery, 4000, [
  "https://source.unsplash.com/CgOaFB56Vyw/1920x1080",
  "https://source.unsplash.com/18Q4c6EVf_o/1920x1080",
  "https://source.unsplash.com/7uvHtSn5a90/1920x1080"
]);
.transition {
  transition: background-image 2s ease;
  -webkit-transition: background-image 2s ease;
  background-size: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body class="transition">
  Here come the images
</body>

</html>

EDIT: The workaround for the transition would be to apply the gradient to body's pseudo element :before:

.transition:before {
  content: '';
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  position: absolute;
  background: linear-gradient(0deg, rgba(0, 0, 255, 0.3), rgba(0, 0, 255, 0.3));
}

(function($, interval, slides) {
  var gradient = "linear-gradient(0deg,rgba(0,0,255,0.3),rgba(0,0,255,0.3))";
  const img = new Image();
  img.onload = function() {
    $('body').css("background-image", "url('" + img.src + "')");
  }
  img.src = slides[slides.length - 1];

  var i = 0;
  var handle = setInterval(function() {
    const img2 = new Image();
    img2.onload = function() {
      var bg = "url('" + img2.src + "')";
      $('body').css('background-image', bg);
      i = (i + 1) % slides.length;
    }
    img2.src = slides[i];
  }, interval);

})(jQuery, 4000, [
  "https://source.unsplash.com/CgOaFB56Vyw/1920x1080",
  "https://source.unsplash.com/18Q4c6EVf_o/1920x1080",
  "https://source.unsplash.com/7uvHtSn5a90/1920x1080"
]);
.transition:before {
  content: '';
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  position: absolute;
  background: linear-gradient(0deg, rgba(0, 0, 255, 0.3), rgba(0, 0, 255, 0.3));
}

.transition {
  transition: background-image 2s ease;
  -webkit-transition: background-image 2s ease;
  background-size: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body class="transition">
  Here come the images
</body>

</html>

Upvotes: 1

Related Questions