2

I have this line of code, I use it to change the class from class1 until class4 to change the background of my site. I want to add a fadeIn each time the class changes, how can I do it? Thanks

Here is my code :

$(document).ready(function () {
  var counter = 1;
   int = setInterval(function(){
   $("#transition").attr("class", "class" + counter);
   if (counter === 4){
       counter = 1;
   } else {
       counter++;
   }
  }, 3000);
});
Adrian Gonzalez
  • 737
  • 1
  • 7
  • 20
  • You can't really fade in a background-image change with javascript, but you could use CSS animations – adeneo Oct 15 '16 at 19:14
  • 1
    http://stackoverflow.com/questions/1950038/jquery-fire-event-if-css-class-changed It's been asked before. – Lewis Johnson Oct 15 '16 at 19:14
  • 1
    How to fire an event when changing a class isn't really a duplicate of how to fade something in when the style changes, me thinks ? – adeneo Oct 15 '16 at 19:22

4 Answers4

0

Best performant and simplest would be to control this in CSS using transition see here for an example to transition the background.

So to use your code structure: just add transition + different background color to each of the css-classs you assign.

Geert-Jan
  • 18,623
  • 16
  • 75
  • 137
0

You need two layers on the background for the switch:

var backIndex = 1;
setInterval(changeBackground, 3000);

$(document).ready(function(){
   $("#transition1").addClass("class1").css("z-index",1);
   $("#transition2").addClass("class2").css("z-index",0);
});

function changeBackground(){
  $("#transition1").fadeOut({complete: function(){
    $("#transition1")
      .removeClass("class" + (((backIndex + 1) % 4) + 1))
      .addClass("class" + (((backIndex + 2) % 4) + 1))
      .fadeIn({complete: function(){
        backIndex++;
        $("#transition2") 
          .removeClass("class" + (((backIndex + 1) % 4) + 1))
          .addClass("class" + (((backIndex + 2) % 4) + 1 ));     
      }});
  }});
}
.class1 {
  background-image: url("https://placeimg.com/640/480/nature");
}

.class2 {
  background-image: url("https://placeimg.com/640/480/arch");
}

.class3 {
  background-image: url("https://placeimg.com/640/480/animals");
}

.class4 {
  background-image: url("https://placeimg.com/640/480/people");
}

#transition1, #transition2 {
  position: absolute;
  z-index: 0;
  left:0;bottom:0;right:0;top:0;background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="transition1"></div>
<div id="transition2"></div>

Note: Click on "Run Code Snippet" and then "Full Page" ;)

Taha Paksu
  • 15,371
  • 2
  • 44
  • 78
  • Hello, thanks a lot this worked perfect :). Do you know why the first 4 backgrounds change really fast and then they change after the time you pick? – Adrian Gonzalez Dec 28 '16 at 04:35
  • because it starts before the images are loaded, and the image load starts when it is first set as `src` attribute. actually it is working for the same interval for every frame. if you preload the images and start after it, you'll see what I mean. – Taha Paksu Dec 28 '16 at 05:34
  • Hello, Thanks a lot but I dont think this is the problem, i have the images saved lcoally and i open the local html file in my browser and it still changes the first 4 images very fast and then after the time you choosed. – Adrian Gonzalez Dec 29 '16 at 06:44
0

FadeIn is an effect of appearing some element and remember that background is not an element. So you can not use fadeIn for background changes. I think the best choice for you is using jquery switchClass function:

$(document).ready(function () {
    var counter = 4;
    int = setInterval(function(){
    var oldClass = "class" + counter;
    counter = counter == 4 ? 1 : counter + 1;
    var newClass = "class" + counter;
    $("#transition").switchClass(oldClass, newClass, 500/*or any value you want*/);
    }, 3000);
});
Amin
  • 221
  • 3
  • 13
0

You can store the URL's referencing the background images to be set in an array; use $.when(), $.Deferred() to wait until all images are loaded; at load event of img, remove image, append css to style element for each image src to set background-image to loaded image; at .then() chained to $.when() set #transition opacity to 0; at next chained .then() call .animate() to animate #transition opacity to 1; use progress option of .animate() to set #transition parent element className to current className of #transition child element; where parent element css transition is set to 1.5 times the duration of animated element to cross-fade the background-image property of #transition and #transition parent element; use .shift(), .push() to rotate the className indexes corresponding to the .length of total background-images which should be set and unset; recursively call named function at last .then() to repeat process

$(function() {
 
  var [width, height] = [window.innerWidth, window.innerHeight];       
  var [transition, style] = [$("#transition"), $("style")];
  var images = [`url(http://lorempixel.com/${width}/${height}/cats)`
               , `url(http://lorempixel.com/${width}/${height}/nature)`
               , `url(http://lorempixel.com/${width}/${height}/city)`
               , `url(http://lorempixel.com/${width}/${height}/technics)`];
  var indexes = Array.from(images.keys());

  $.when.apply($, $.map(images, function(src, index) {
    return $.Deferred(function(dfd) {
      var img = new Image;
      img.onload = function() {
        $("style")
        .append(`.transition-${index}{background-image:${src}}`);
        dfd.resolve(src);
        $(img).remove();
      };
      img.onerror = dfd.reject;
      img.src = src.replace(/^url\(|\)$/g, "");;
    })
  }))
  .then(function() {
    return transition.addClass(`transition-${indexes[0]}`).css("opacity", 0)
  })
  .then(function animate() {  
    return transition
      .animate({opacity: 1}, {
        duration:3000,
        progress: function(promise, prop, now) {
          if (now <= promise.duration / 2) {
            transition.parent().removeClass()
            .addClass(this.className)
          }
        }
      })
      .promise()
      .then(function() {
          return transition
          .delay(3000)
          .animate({opacity:0}, 3000)
          .promise()
          .then(function() {
            transition
            .removeClass(`transition-${indexes[0]}`);
            indexes.push(indexes.shift());
            return transition.addClass(`transition-${indexes[0]}`);
          })
        }).then(animate)
    })
    .fail(function(err) {
      console.log(err)
    })
})
#transition-wrapper, #transition {
  width: 95vw;
  height: 95vh;
  position:absolute;
  top:0;
}

#transition-wrapper {
 transition: background-image 4.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<style></style>
<div id="transition-wrapper">
  <div id="transition">
  </div>
</div>
guest271314
  • 1
  • 15
  • 104
  • 177