Reputation: 113
I want to fade-in the "image" once it is loaded from an external url, but show a "imgPlaceholder" right from the beginning from local resources.
The HTML looks like this:
<div className="bg-img" style={imgDivStyle}></div>
The CSS looks like this:
const imgDivStyle = {
background: `url('${image}'), url('${imgPlaceholder}')`,
backgroundSize: 'cover',
};
What I want to happen: Show "imgPlaceholder" from beginning and Fade-in "image" once it is loaded.
What is actually happening: "imgPlaceholder" is shown from beginning "image" is showing up instantly once it is loaded.
Is this achievable by pure CSS? Or do I need to load in the image using e.g. jQuery and trigger an animation manually?
Upvotes: 2
Views: 397
Reputation: 58442
You can't check if the image has loaded with css alone so you could do something like the following (comments in code to show what is happening):
$('.inner').each(function() {
var div = $(this),
background = div.data('background'); // get background
$('<img/>').attr('src', background).load(function() { // create an image element with inner background and load it
$(this).remove(); // remove it
// set the inner background image and fade in:
div.css('background-image', 'url(' + background + ')').delay(200).fadeIn(2000); // need a little delay to let the div render it's bg image before the fade starts
});
});
.default,
.inner {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
/* just make sure inner div is same size as outer */
width: 400px;
height: 400px;
}
.default {
background-image: url(https://lorempixel.com/900/900/city/1/); /* default background */
}
.inner {
display:none; /* start of hidden */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="default"><!-- default div with default background image -->
<div class="inner" data-background="https://lorempixel.com/900/900/city/2/"><!-- inner div with background-image set as data attribute -->
</div>
</div>
If you want to create the inner div on the fly, you can do something like this:
$('.background').each(function() {
var div = $(this),
background = div.data('background'), // get background
html = div.html(); // get any contents
$('<img/>').attr('src', background).load(function() { // create an image element with inner background and load it
$(this).remove(); // remove it
div.empty(); // empty current div
// create an inner div:
$('<div/>')
.css({
'background-image': 'url(' + background + ')',
'display': 'none'
}) // add background and hide
.addClass('inner')
.html(html)
.appendTo(div) // append to default div
.delay(175)
.fadeIn(2000); // need a little delay to let the div render it's bg image before the fade starts
});
});
.background,
.inner {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.background {
background-image: url(https://lorempixel.com/900/900/city/1/); /* default background */
/* just make sure inner div is same size as outer */
width: 400px;
height: 400px;
}
.inner {width:100%; height:100%;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="background" data-background="https://lorempixel.com/900/900/city/2/"><!-- default div with default background image, new background image set as data attribute -->
</div>
Upvotes: 2
Reputation: 178
I found a reference that utilizes @keyframes along with some attributes like 'opacity' within an animation frame.
You can try referencing some of the code in the link here -
https://codepen.io/davidhc/pen/nLpJk
@keyframes fade
{
0% {opacity:1}
33.333% { opacity: 0}
66.666% { opacity: 0}
100% { opacity: 1}
}
Upvotes: -1