Background image swap animation

Background image swap animation



I have a grid and each div has a background image. I am trying to create a fade out/in image swapping effect. Currently I'm getting two random divs and inserting one background-image URL into the other. Problem is, after a while all the images wind up the same. I think I need to reset the background URL to the original value (image) each time, but I'm not sure how to do that.



So the order would be:
original image fades out,
new image fades in,
new image fades out,
original image fades in



Any help greatly appreciated!



Currently I have this fiddle:



JS:


var $squares = $('.box');

function imgFade() ")/g, '');
var square2Url = square2.css('background-image').replace(/(url(

imgFade();



HTML:


<div class="grid-container">

<div class="box" style="background-image: url('https://www.catster.com/wp-content/uploads/2017/11/A-Siamese-cat.jpg')"></div>

<div class="box" style="background-image: url('https://r.hswstatic.com/w_907/gif/tesla-cat.jpg')"></div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/s_f/o_1/cx_462/cy_245/cw_1349/ch_1349/w_720/APL/uploads/2015/06/caturday-shutterstock_149320799.jpg')"></div>

<div class="box" style="background-image: url('https://www.shelterluv.com/sites/default/files/animal_pics/464/2016/11/25/22/20161125220040.png')"></div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/w_830/s_f/o_1/cx_0/cy_66/cw_288/ch_162/APL/uploads/2014/10/cat_5-1.jpg')"></div>

<div class="box" style="background-image: url('https://cdn.theatlantic.com/assets/media/img/mt/2017/06/shutterstock_319985324/lead_720_405.jpg?mod=1533691890')"></div>

</div>



CSS:


body margin:0
.grid-container width:100%;

.box
width:20vw;
height:33.33vh;
float:left;
border:1px solid white;
background-size: cover;
background-position:center;




1 Answer
1



Since you are changing the background-image url in a random element, each time you are going to potentially lose a url if the other url is a copy of one of the others.



You could parse all the urls and keep them in an array and grab the urls randomly from that array instead of the elements themselves since you will be changing the elements.


var $squares = $('.box');
//create an array from all the backgroundImage values
var urls = $squares.map(function()
return this.style.backgroundImage;
);



Then in imgFade


var square1 = $squares.eq([Math.floor(Math.random()*$squares.length)])
//get random urls from the array instead of the elements
var square1Url = urls[Math.floor(Math.random()*$squares.length)];
var square2Url = urls[Math.floor(Math.random()*$squares.length)];



Demo




var $squares = $('.box');
var urls = $squares.map(function()
return this.style.backgroundImage;
);

function imgFade()

var square1 = $squares.eq([Math.floor(Math.random() * $squares.length)])

var square1Url = urls[Math.floor(Math.random() * $squares.length)];
var square2Url = urls[Math.floor(Math.random() * $squares.length)];

$(square1).fadeOut(1500, function()
$(this).css("background-image", square2Url);
$(this).fadeIn(1500);
);

timeoutId = setTimeout(imgFade, 1500);


imgFade();


body
margin: 0


.grid-container
width: 100%;


.box
width: 20vw;
height: 33.33vh;
float: left;
border: 1px solid white;
background-size: cover;
background-position: center;


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid-container">

<div class="box" style="background-image: url('https://www.catster.com/wp-content/uploads/2017/11/A-Siamese-cat.jpg')">

</div>

<div class="box" style="background-image: url('https://r.hswstatic.com/w_907/gif/tesla-cat.jpg')">
</div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/s_f/o_1/cx_462/cy_245/cw_1349/ch_1349/w_720/APL/uploads/2015/06/caturday-shutterstock_149320799.jpg')">
</div>

<div class="box" style="background-image: url('https://www.shelterluv.com/sites/default/files/animal_pics/464/2016/11/25/22/20161125220040.png')">
</div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/w_830/s_f/o_1/cx_0/cy_66/cw_288/ch_162/APL/uploads/2014/10/cat_5-1.jpg')">
</div>

<div class="box" style="background-image: url('https://cdn.theatlantic.com/assets/media/img/mt/2017/06/shutterstock_319985324/lead_720_405.jpg?mod=1533691890')">
</div>

</div>



Side note you dont need to do the url() replace since you are just adding it back in when setting the new background.



Also you will end up with multiple duplicates since it is random. But you won't end up just having a single url being used. If you don't want multiple duplicates, eg more than 2 duplicates at a time, you would need to write a check to see if that url has been used more than once and if so get a different one until you get one that hasn't been.



If you want no duplicates at all you would have to swap 2 backgrounds at once instead of just one at a time. This would be a bit easier code wise but does require changing two at a time.



In this one you would do as you were but add in the change to the second element as well


var square1 = $squares.eq([Math.floor(Math.random()*$squares.length)])
//modified to not select square1
var square2 = var square2 = $squares.not(square1).eq([Math.floor(Math.random() * $squares.length-1)])

var square1Url = square1.css('background-image').replace(/(url(|)|")/g, '');
var square2Url = square2.css('background-image').replace(/(url(|)|")/g, '');

$(square1).fadeOut(1500, function()
$(this).css("background-image", "url(" + square2Url + ")");
$(this).fadeIn(1500);
);
$(square2).fadeOut(1500, function()
$(this).css("background-image", "url(" + square1Url + ")");
$(this).fadeIn(1500);
);



You would also need to increase the timeout to 3000 so that you don't accidently trigger a new transition while one is already taking place.




var $squares = $('.box');
var urls = $squares.map(function()
return this.style.backgroundImage;
);

function imgFade()

var square1 = $squares.eq([Math.floor(Math.random() * $squares.length)])
//modified to make sure we dont accidently
//select square1
var square2 = $squares.not(square1).eq([Math.floor(Math.random() * $squares.length-1)])
var square1Url = square1.css('background-image');
var square2Url = square2.css('background-image');

$(square1).fadeOut(1500, function()
$(this).css("background-image", square2Url);
$(this).fadeIn(1500);
);
$(square2).fadeOut(1500, function()
$(this).css("background-image", square1Url)
$(this).fadeIn(1500);
);
//change timing so it doesnt get called
//in the middle of a transition
timeoutId = setTimeout(imgFade, 3000);


imgFade();


body
margin: 0


.grid-container
width: 100%;


.box
width: 20vw;
height: 33.33vh;
float: left;
border: 1px solid white;
background-size: cover;
background-position: center;


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid-container">

<div class="box" style="background-image: url('https://www.catster.com/wp-content/uploads/2017/11/A-Siamese-cat.jpg')">

</div>

<div class="box" style="background-image: url('https://r.hswstatic.com/w_907/gif/tesla-cat.jpg')">
</div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/s_f/o_1/cx_462/cy_245/cw_1349/ch_1349/w_720/APL/uploads/2015/06/caturday-shutterstock_149320799.jpg')">
</div>

<div class="box" style="background-image: url('https://www.shelterluv.com/sites/default/files/animal_pics/464/2016/11/25/22/20161125220040.png')">
</div>

<div class="box" style="background-image: url('https://r.ddmcdn.com/w_830/s_f/o_1/cx_0/cy_66/cw_288/ch_162/APL/uploads/2014/10/cat_5-1.jpg')">
</div>

<div class="box" style="background-image: url('https://cdn.theatlantic.com/assets/media/img/mt/2017/06/shutterstock_319985324/lead_720_405.jpg?mod=1533691890')">
</div>

</div>






Thanks for this. Having multiple duplicates is part of the problem, I thought that by returning the image to its original url then I shouldn't have more than 2 duplicates at any given time. I'm a little confused though how I would do the check to see if the url has been used more than once?

– patrice
Sep 17 '18 at 2:53






@patrice see edited answer. Added a way of doing it without duplicates but would need doing two images at once instead of 1.

– Patrick Evans
Sep 17 '18 at 3:11







That's great! Actually having 2 at a time fade out is even better. Thank you

– patrice
Sep 17 '18 at 3:19




Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)