I have got a problem with the background fading script. The function causes high CPU usage (30-40%, tested on Intel i7-4810MQ). The problem is present only on Chrome and Opera. With Firefox everything work fine. It's quite a big problem for me, because when my website is open the laptop starts heating and the fan is getting louder.
Here is the jsfiddle code: http://jsfiddle.net/jwdu8mkq/4/
JS:
$(document).ready(function() {
var background = {};
background.num = 3;
background.min = 1;
background.max = 6;
background.firstShow = true;
background.swap = function() {
var swapFirst = false;
var swapSecond = false;
if($('.background.img1').attr('image-number') == this.num) {
$('.background.img1').fadeOut(2000);
swapSecond = true;
} else if($('.background.img2').attr('image-number') == this.num) {
$('.background.img2').fadeOut(2000);
swapFirst = true;
} else {
swapFirst = true;
}
this.num++;
if(this.num < this.min) {
this.num = this.min;
} else if(this.num > this.max) {
this.num = this.min;
}
if(swapFirst) {
$('.background.img1').css('background-image', 'url(\'http://lokeshdhakar.com/projects/lightbox2/images/image-' + this.num + '.jpg\')');
$('.background.img1').attr('image-number', this.num);
$('.background.img1').fadeIn(this.firstShow ? 0 : 2000);
this.firstShow = false;
} else if(swapSecond) {
$('.background.img2').css('background-image', 'url(\'http://lokeshdhakar.com/projects/lightbox2/images/image-' + this.num + '.jpg\')');
$('.background.img2').attr('image-number', this.num);
$('.background.img2').fadeIn(this.firstShow ? 0 : 2000);
this.firstShow = false;
}
}
setInterval(function() { background.swap() }, 6000);
background.swap();
});
CSS:
.background {
filter: blur(10px);
-webkit-filter: blur(10px);
-moz-filter: blur(10px);
-o-filter: blur(10px);
-ms-filter: blur(10px);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: -1000;
display: none;
}
HTML:
<div class="background img1"></div>
<div class="background img2"></div>
Is there any chance to optimize this code? Or maybe can I replace it with something similar that has the same effect?
Sorry if the question is obvious, I'm definitely not a good web designer.
You might try using CSS transitions to do most of the lifting for you. If you define 6 classes each with a background then you can swap the classes and simplify things quite a lot.
This strategy allows you to swap classes rather than divs with a cross fade. The fade effect provided by a CSS transition.
For full effect you need to view a cycle so that the images are cached. For your proper implementation, you will want to pre-load the images.
$(document).ready(function() {
var background = {};
background.num = 3;
background.max = 6;
background.container = $(".background");
background.swap = function() {
this.container.removeClass("background_" + this.num);
this.num = (this.num % this.max) + 1;
this.container.addClass("background_" + this.num);
}
setInterval(function() { background.swap() }, 6000);
background.swap();
});
.background {
height: 600px;
width: 600px;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
-webkit-filter: blur(10px);
-moz-filter: blur(10px);
-o-filter: blur(10px);
-ms-filter: blur(10px);
filter: blur(10px);
transition: all 0.5s ease-in-out;
}
.background_1 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-1.jpg) }
.background_2 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-2.jpg) }
.background_3 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-3.jpg) }
.background_4 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-4.jpg) }
.background_5 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-5.jpg) }
.background_6 { background-image: url(http://lokeshdhakar.com/projects/lightbox2/images/image-6.jpg) }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="background background_3"></div>
This is the CPU use I see on my system in chrome. Your code for the left half and mine for the right.
Well, a different approach might be to use a canvas then. This is a bit more complicated but conceptually mirrors your initial attempt. We will load up an array of images then cycle them by calling crossfadeTo(). There is a bunch of stuff you can do to improve on this, but it might get you going again. As an example, the first image crossfading to itself is a little wonky.
function loadImages(imageURLs, images) {
imageURLs.forEach(function(item){
var img = new Image();
img.onload = function(){ images.push(img); };
img.src = item;
});
}
var crossfadeTo = (function(myCanvas){
var ctx = myCanvas.getContext('2d');
var last = myCanvas.cloneNode(true).getContext('2d');
var next = myCanvas.cloneNode(true).getContext('2d');
var currentImage;
var nextImage;
var currentAlpha = 1;
var crossfadeTo = function(toImage){
currentAlpha = 1;
nextImage = toImage;
if (!currentImage) { currentImage = nextImage; }
crossfade();
}
var crossfade = function() {
last.clearRect(0, 0, myCanvas.width, myCanvas.height);
last.globalAlpha = currentAlpha;
last.drawImage(currentImage, 0, 0, currentImage.width, currentImage.height, 0, 0, myCanvas.width, myCanvas.height);
next.clearRect(0, 0, myCanvas.width, myCanvas.height);
next.globalAlpha = 1 - currentAlpha;
next.drawImage(nextImage, 0, 0, nextImage.width, nextImage.height, 0, 0, myCanvas.width, myCanvas.height);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
ctx.drawImage(last.canvas, 0, 0);
ctx.drawImage(next.canvas, 0, 0);
currentAlpha -= 0.01;
if (currentAlpha <= 0) {
currentImage = nextImage;
} else {
requestAnimationFrame(crossfade);
}
};
return crossfadeTo;
})(document.getElementById("main"), images);
var imageURLs = [
"http://lokeshdhakar.com/projects/lightbox2/images/image-1.jpg",
"http://lokeshdhakar.com/projects/lightbox2/images/image-2.jpg",
"http://lokeshdhakar.com/projects/lightbox2/images/image-3.jpg",
"http://lokeshdhakar.com/projects/lightbox2/images/image-4.jpg",
"http://lokeshdhakar.com/projects/lightbox2/images/image-5.jpg",
"http://lokeshdhakar.com/projects/lightbox2/images/image-6.jpg",
];
var images = [];
loadImages(imageURLs, images);
var currentImageIndex = 0;
setInterval(function(){
if (images.length === 0 ){ console.log("not enough images yet..."); return; }
crossfadeTo(images[currentImageIndex % images.length]);
currentImageIndex = (currentImageIndex + 1) % images.length;
}, 6000);
<canvas id="main" width="400" height="400"></canvas>
This solution uses almost no CPU under FF, Chrome and Edge.