I have created a jQuery based slideshow that lives within a DIV on my webpage. The only problem is the images have no transition effect between each other, just one to the next without the first one slowly fading out and the next fading on.
I would like to crossfade these images. What am I missing in my JS?
var urls = ['https://example.com/front.png',
'https://example.com/interior-scaled.jpeg'];
var count = 1;
$('.hero').css('background-image', 'url("' + urls[0] + '")');
setInterval(function() {
$('.hero').css('background-image', 'url("' + urls[count] + '")');
count == urls.length-1 ? count = 0 : count++;
}, 6000);
});
LINK TO FIDDLE
If you are not opposed to using a jQuery slideshow library then may I suggest using Ken Wheelers Slick carousel jQuery lib.
slick.min.css minified size 1.4 KB
slick-theme.min.css minified size 3.07 KB (only use if you want slicks base theme styles)
slick.min.js minified size 51.9 KB
In your first comment you mentioned...
even if images slide like a carousel would be sufficient.
Well Slick makes easy work of both, plus loads of other cool options, event callbacks and responsive breakpoint settings. It might speed up creating sliding/fading carousels for your project utilising jQuery which you are already using.
I've include 2 hero slideshows in example below, both in fade: false mode.
#Hero_1 slideshow runs before images may have or have not loaded.
#Hero_2 uses $(window).on('load') to make sure your images have loaded before slideshow runs
// our hero examples as constant variables
const hero_1 = $('#hero_1');
const hero_2 = $('#hero_2');
// our slide image urls in constant variable array
const slides = [
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-patient-exam-room.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-interior-scaled.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-front.png'
];
// for each of the slide images as key > url
$.each(slides, function(key, url) {
// append slide to hero carousel div
$('.carousel', '.hero').append('<div class="slide" style="background-image:url(\'' + url + '\');"></div>');
});
// the below slick js should not run until the above each function has finished appending images in slides array
// slick hero carousel on init
$('.carousel', hero_1).on('init', function(slick) {
// add show class to hero div to animate height when slick init
$(hero_1).addClass('show');
// slick carousel options
}).slick({
slidesToShow: 1,
slidesToScroll: 1,
dots: false,
arrows: false,
fade: true,
adaptiveHeight: false,
autoplay: true,
infinite: true,
pauseOnFocus: false,
pauseOnHover: false,
autoplaySpeed: 4000,
speed: 1000,
draggable: false
});
// use this if you want all background images to load first
// tho may be slow to run depending on how many images and the image size you are loading
$(window).on('load', function() {
// slick on init
$('.carousel', hero_2).on('init', function(slick) {
// add show class to hero div to expand height
$(hero_2).addClass('show');
// slick options
}).slick({
slidesToShow: 1,
slidesToScroll: 1,
dots: false,
arrows: false,
fade: true,
adaptiveHeight: false,
autoplay: true,
infinite: true,
pauseOnFocus: false,
pauseOnHover: false,
autoplaySpeed: 4000,
speed: 1000,
draggable: false
});
});
.hero {
position: relative;
overflow: hidden;
background: rgba(0, 0, 0, .75);
min-height: 0;
height: 0;
transition: all 0.5s ease;
margin: 0 0 .5rem 0;
}
.hero.show {
min-height: 150px;
height: 150px;
/*
height:45%;
height:45vh;
min-height:400px;
*/
}
.hero .carousel {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.5s ease;
}
.hero .carousel.slick-initialized {
opacity: 1;
}
.hero .carousel .slick-list,
.hero .carousel .slick-track {
height: 100% !important;
}
.hero .carousel .slide {
background-color: none;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
height: 100%;
}
.hero .overlay {
color: #fff;
position: relative;
text-align: center;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-shadow: 1px 1px 2px rgba(0, 0, 0, .75);
}
/* for demo styling purposes */
BODY {
font-family: helvetica;
}
H1 {
font-size: 2rem;
font-weight: 600;
margin: 0 0 .5rem 0;
}
P {
margin: 0 0 .5rem 0;
}
.lead {
font-size: 1.4rem;
margin: 0 0 .5rem 0;
}
.row {
margin: 0 -4px 0 -4px;
}
.col {
float: left;
width: calc(50% - 8px);
padding: 0 4px 0 4px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet" />
<div class="row">
<div class="col">
<p>
<code><strong>#hero_1</strong><br/></code>
<code><small>Slick inits after each function is complete.</small></code>
</p>
<div id="hero_1" class="hero">
<div class="carousel"></div>
<div class="overlay">
<h1>Hero 1</h1>
<p class="lead">
Tooth Hurty
</p>
</div>
</div>
</div>
<div class="col">
<p>
<code><strong>#hero_2</strong></code><br/>
<code><small>Waits for all imgs to load before init slick.</small></code>
</p>
<div id="hero_2" class="hero">
<div class="carousel"></div>
<div class="overlay">
<h1>Hero 2</h1>
<p class="lead">
Tooth Hurty
</p>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
Here is the same code above but in fade: false mode...
#Hero_1 slideshow runs before images may have or have not loaded.
#Hero_2 uses $(window).on('load') to make sure your images have loaded before slideshow runs
// our hero examples as constant variables
const hero_1 = $('#hero_1');
const hero_2 = $('#hero_2');
// our slide image urls in constant variable array
const slides = [
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-patient-exam-room.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-interior-scaled.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-front.png'
];
// for each of the slide images as key > url
$.each(slides, function(key, url) {
// append slide to hero carousel div
$('.carousel', '.hero').append('<div class="slide" style="background-image:url(\'' + url + '\');"></div>');
});
// the below slick js should not run until the above each function has finished appending images in slides array
// slick hero carousel on init
$('.carousel', hero_1).on('init', function(slick) {
// add show class to hero div to animate height when slick init
$(hero_1).addClass('show');
// slick carousel options
}).slick({
slidesToShow: 1,
slidesToScroll: 1,
dots: false,
arrows: false,
fade: false,
adaptiveHeight: false,
autoplay: true,
infinite: true,
pauseOnFocus: false,
pauseOnHover: false,
autoplaySpeed: 4000,
speed: 1000,
draggable: false
});
// use this if you want all background images to load first
// tho may be slow to run depending on how many images and the image size you are loading
$(window).on('load', function() {
// slick on init
$('.carousel', hero_2).on('init', function(slick) {
// add show class to hero div to expand height
$(hero_2).addClass('show');
// slick options
}).slick({
slidesToShow: 1,
slidesToScroll: 1,
dots: false,
arrows: false,
fade: false,
adaptiveHeight: false,
autoplay: true,
infinite: true,
pauseOnFocus: false,
pauseOnHover: false,
autoplaySpeed: 4000,
speed: 1000,
draggable: false
});
});
.hero {
position: relative;
overflow: hidden;
background: rgba(0, 0, 0, .75);
min-height: 0;
height: 0;
transition: all 0.5s ease;
margin: 0 0 .5rem 0;
}
.hero.show {
min-height: 150px;
height: 150px;
/*
height:45%;
height:45vh;
min-height:400px;
*/
}
.hero .carousel {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.5s ease;
}
.hero .carousel.slick-initialized {
opacity: 1;
}
.hero .carousel .slick-list,
.hero .carousel .slick-track {
height: 100% !important;
}
.hero .carousel .slide {
background-color: none;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
height: 100%;
}
.hero .overlay {
color: #fff;
position: relative;
text-align: center;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-shadow: 1px 1px 2px rgba(0, 0, 0, .75);
}
/* for demo styling purposes */
BODY {
font-family: helvetica;
}
H1 {
font-size: 2rem;
font-weight: 600;
margin: 0 0 .5rem 0;
}
P {
margin: 0 0 .5rem 0;
}
.lead {
font-size: 1.4rem;
margin: 0 0 .5rem 0;
}
.row {
margin: 0 -4px 0 -4px;
}
.col {
float: left;
width: calc(50% - 8px);
padding: 0 4px 0 4px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet" />
<div class="row">
<div class="col">
<p>
<code><strong>#hero_1</strong><br/></code>
<code><small>Slick inits after each function is complete.</small></code>
</p>
<div id="hero_1" class="hero">
<div class="carousel"></div>
<div class="overlay">
<h1>Hero 1</h1>
<p class="lead">
Tooth Hurty
</p>
</div>
</div>
</div>
<div class="col">
<p>
<code><strong>#hero_2</strong></code><br/>
<code><small>Waits for all imgs to load before init slick.</small></code>
</p>
<div id="hero_2" class="hero">
<div class="carousel"></div>
<div class="overlay">
<h1>Hero 2</h1>
<p class="lead">
Tooth Hurty
</p>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
You can use transition: background-image. It might not be supported in all browsers, but most modern browsers should be fine.
Add
-webkit-transition: background-image 0.5s ease-in-out;
transition: background-image 0.5s ease-in-out;
to the css of the div which has the background image.
Here's a forked fiddle with a working example: https://jsfiddle.net/bmh2qu0e/1/
You can use transition on opacity and toggle opacity on background change, something like:
$(document).ready(function() {
var urls = ['https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-patient-exam-room.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-interior-scaled.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-front.png'
];
var count = 1;
var $hero = $('.hero');
$hero.css('background-image', 'url("' + urls[0] + '")');
setInterval(function() {
setTimeout(function() {
$hero.toggleClass('transparent');
setTimeout(function() {
$hero.css('background-image', 'url("' + urls[count] + '")');
count == urls.length - 1 ? count = 0 : count++;
$hero.toggleClass('transparent');
}, 300);
}, 300);
}, 6000);
});
.transparent {
opacity: 0;
}
.hero {
height: 45%;
height: 45vh;
min-height: 400px;
background-color: none;
text-align: center;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
-webkit-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hero"></div>
If you want to take a step further, you can make it more generic with class:
class ImageSlider {
imagePos = 0;
intevalHandle = null;
intervalMS = 6000;
constructor(elem, images, startImmediately) {
this.images = images || [];
this.elem = $(elem);
if (startImmediately) {
this.startSlider();
}
}
startSlider() {
if (this.startTimer()) {
this.imagePos = 0;
this.onTimerInterval();
}
};
pauseSlider() {
this.clearTimer();
}
resumeSlider() {
this.startTimer();
}
stopSlider() {
this.clearTimer();
this.imagePos = 0;
};
startTimer() {
if (this.intervalHandle != null) {
return false;
}
this.intervalHandle = setInterval(() => this.onTimerInterval(), this.intervalMS);
return true;
};
clearTimer() {
if (this.intervalHandle) {
this.clearInterval(this.intervalHandle);
this.intervalHandle = null;
}
}
onTimerInterval() {
if (this.images.length <= 0) {
return;
}
setTimeout(() => {
this.elem.toggleClass('transparent');
setTimeout(() => {
if (this.imagePos >= this.images.length) {
this.imagePos = 0;
}
this.elem.css('background-image', 'url("' + this.images[this.imagePos] + '")');
this.imagePos++;
this.elem.toggleClass('transparent');
}, 300);
}, 300);
}
}
$(document).ready(function() {
var urls = ['https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-patient-exam-room.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-interior-scaled.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-front.png'
];
var slider1 = new ImageSlider('#ss1', urls, true);
var slider2 = new ImageSlider('#ss2', [...urls].reverse(), true);
});
.transparent {
opacity: 0;
}
.hero {
height: 45%;
height: 45vh;
min-height: 400px;
background-color: none;
text-align: center;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
-webkit-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ss1" class="hero"></div>
<div id="ss2" class="hero"></div>
You can't cross-fade a single background image using CSS.
A possible solution is to have two containers inside the hero <div> you have there.
E.g:
<div class="hero">
<div class="img-container" id="first"></div>
<div class="img-container" id="second"></div>
</div>
For your desired effect of the crossfade you will need these images to cover the desired area on top of the hero <div>.
This can be done by these CSS rules:
.img-container {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
background-color: transparent;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Now we need to have the images load in and cross-fade over one another.
$(document).ready(function() {
var urls = [
'imgURL1',
'imgURL2',
'imgURL3'
];
// Preload the images
var tempImg = []
for (var i = 0; i < urls.length; i++) {
(new Image()).src = urls[i]
}
// The currently shown image's index
var currentShown = 0;
// Get the containers
var first = $("#first");
var second = $("#second");
// This shows whether the second object is on top or not
var secondOnTop = true;
// Set the first container's value so that there is something on the screen and load the second image on top.
first.css('background-image', 'url("' + urls[urls.length - 1] + '")');
second.css({
backgroundImage: 'url("' + urls[0] + '")',
opacity: 1
});
// Change the image every X seconds
setInterval(function() {
var animationSpeed = 1000; // In milliseconds
// Increment currently shown image index
currentShown === urls.length - 1 ? currentShown = 0 : currentShown++;
// Determine which object has visual priority
var primaryObj = first;
var auxObj = second;
if (secondOnTop) {
primaryObj = second;
auxObj = first;
}
secondOnTop = !secondOnTop;
// Show aux obj background
auxObj.css({backgroundImage: 'url("' + urls[currentShown] + '")'});
auxObj.animate({
opacity: 1
}, animationSpeed);
// Change shown object's background and set to 0
primaryObj.animate({
opacity: 0,
}, animationSpeed, function() {
// Change the primary's background to the next in queue
var nextImg = currentShown === urls.length - 1 ? 0 : currentShown + 1;
primaryObj.css('background-image', 'url("' + urls[nextImg] + '")');
});
}, 6000);
});
I have created a fork of your fiddle available here: https://jsfiddle.net/YeloPartyHat/uLfr389g/88/
Here is a solution: (I had to replace shortened url with full url otherwise SO wouldn't let me save the answer)
$(document).ready(function(){
var urls = ['https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-patient-exam-room.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-interior-scaled.jpeg',
'https://concorddentalde.com/wp-content/uploads/2020/10/concord-dental-front.png'];
var totalLayers = 2;
var layerIndex = 0;
var count = 0;
$('.layer-' + layerIndex)
.removeClass('layer')
.css('background-image', 'url("' + urls[count] + '")');
console.log({first: layerIndex, second: (layerIndex + 1) % totalLayers, count})
setInterval(function() {
var outLayer = layerIndex
var inLayer = ++layerIndex % totalLayers
layerIndex = inLayer
count = ++count % urls.length;
console.log({first: outLayer, second: inLayer, count})
$('.layer-' + outLayer)
.addClass('animateXFadeOut');
$('.layer-' + inLayer)
.removeClass('layer')
.css('background-image', 'url("' + urls[count] + '")')
.addClass('animateXFadeIn');
setTimeout(function() {
$('.layer-' + outLayer).css({backgroundImage: 'none', opacity: 1});
$('.layers').removeClass('animateXFadeIn animateXFadeOut');
}, 1000);
}, 6000);
});
.hero {
/* height: 45%;
height: 45vh;
min-height: 400px;
*/
background-color: none;
text-align: center;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
}
#keyframes xfadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes xfadeout {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.animateXFadeIn {
animation-name: xfadein;
animation-duration: 1s;
}
.animateXFadeOut {
animation-name: xfadeout;
animation-duration: 1s;
}
.layer-0, .layer-1 {
display: block;
position: absolute;
height: 45%;
height: 45vh;
min-height: 400px;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hero">
<div class="layers layer-0"></div>
<div class="layers layer-1"></div>
</div>
you can use one little class and one line of jquery to do that
$(document).ready(function(){
var urls = ['image_one_url',
'image_two_url',
'image_three_url'];
var count = 1;
$('.hero').css('background-image', 'url("' + urls[0] + '")');
$('.hero').addClass('animatedinout');
setInterval(function() {
$('.hero').css('background-image', 'url("' + urls[count] + '")');
count == urls.length-1 ? count = 0 : count++;
}, 6000);
});
.animatedinout{
animation: fadeinout;
animation-duration: 6000ms;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
#keyframes fadeinout{
0%{
opacity: 0;
}
10%{
opacity: 1;
}
90%{
opacity: 1;
}
100%{
opacity: 0;
}
}
i just add a css class called animatedinout that use an animation forever for every 6000 mili seconds and add
$('.hero').addClass('animatedinout');
right before your setInterval.
I thank everyone for their hard work. The solution I found (because I was on a tight deadline) is actually pretty simple and combines JS and CSS to make for a "true" crossfade transition.
HTML:
<div id="background-images">
<div class="bgImages active" id="bgImg1"></div>
<div class="bgImages" id="bgImg2"><br></div>
<div class="bgImages" id="bgImg3"><br><br></div>
<div class="bgImages" id="bgImg4"><br></div>
<div class="bgImages" id="bgImg5"><br><br></div>
</div>
jQuery:
function cycleImages() {
var $active = $("#background-images .active");
var $next = $active.next().length > 0
? $active.next()
: $("#background-images div:first");
$next.css("z-index", 2); // move the next img up the stack
$active.fadeOut(1500, function() {
//fade out the top image
$active.css("z-index", 1).show().removeClass("active"); //reset z-index and unhide the image
$next.css("z-index", 3).addClass("active"); //make the next image the top one
});
}
$(document).ready(function() {
$("#cycler img").show();
// run every 6 seconds
setInterval(cycleImages, 6000);
});
CSS:
#background-images {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 670px;
z-index: -5;
}
#bgImg1, #bgImg2, #bgImg3, #bgImg4, #bgImg5 {
width: 100%;
height: 100%;
position: fixed;
background-position-x: center;
background-position-y: center;
background-size: cover;
background-repeat: no-repeat;
}
#bgImg1 { background-image: url("https://image1.jpg"); }
#bgImg2 { background-image: url("https://image2.png"); z-index: 2; }
#bgImg3 { background-image: url("https://image3.jpeg"); }
#bgImg4 { background-image: url("https://image4.jpg"); }
#bgImg5 { background-image: url("https://image5.jpeg"); }
It was a clever way of using z-index combined with active status to get the images to actually crossfade with no white "blink".
Found it on a CodePen here.
I am making a loading animation and now I am having a loading animation circle type below :
var waitingMask = {
show: function() {
var body = $('body');
var static_pos;
var spinner = body.children('.spinner');
if (spinner.length && !spinner.hasClass('spinner-remove')) return null;
!spinner.length && (spinner = $('<div class="spinner' + (static_pos ? '' : ' spinner-absolute') + '"/>').appendTo(body));
animateSpinner(spinner, 'add');
body.addClass("spinner-fade");
},
hide: function() {
var body = $('body');
var complete;
var spinner = body.children('.spinner');
spinner.length && animateSpinner(spinner, 'remove', complete);
body.removeClass("spinner-fade");
}
}
function animateSpinner(el, animation, complete) {
if (el.data('animating')) {
el.removeClass(el.data('animating')).data('animating', null);
el.data('animationTimeout') && clearTimeout(el.data('animationTimeout'));
}
el.addClass('spinner-' + animation).data('animating', 'spinner-' + animation);
el.data('animationTimeout', setTimeout(function() {
animation == 'remove' && el.remove();
complete && complete();
}, parseFloat(el.css('animation-duration')) * 1000));
}
function showLoading() {
return waitingMask.show();
}
function hideLoading() {
return waitingMask.hide();
}
/* The spinner */
#keyframes spinner {
to {
transform: rotate(360deg);
}
}
.spinner,
.spinner:before {
width: 80px;
height: 80px;
box-sizing: border-box;
}
.spinner:before {
content: '';
display: block;
border-radius: 50%;
border: 2px solid #ccc;
border-top-color: #333;
animation: spinner .6s linear infinite;
}
.spinner-absolute {
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
}
/* Animations */
.spinner-add,
.spinner-remove {
animation-fill-mode: both;
animation-duration: .4s;
}
.spinner-add {
animation-name: spinner-add;
}
#keyframes spinner-add {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.spinner-remove {
animation-name: spinner-remove;
}
#keyframes spinner-remove {
to {
transform: scale(0);
}
}
.spinner-fade {
content: '';
display: block;
/* position: fixed; */
top: 0;
/* bottom: 0; */
left: 0;
/* right: 0; */
width: 100%;
height: 100%;
background-color: transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>
ABC
</h1>
<button onclick="showLoading()">Add Spinner</button>
<button onclick="hideLoading()">Remove Spinner</button>
jsfiddle
But I want to improve my to circle loading to floating bar loading like below:
Anyone can give me a solution for my problem?
Thanks.
I'm appending a large image when it's done loading and fading it in which all works well. My problem is when there is more than one image. Then it's only the last small image that get replaced (with the first image). I can't seem to figure out how to separate them. The src URLs are retrieved trough a data-attribute. Codepen with two images. (with one image it works as intended).
window.onload = function() {
var ImageBlur = function (element) {
var self = this;
this.element = element;
this.$element = $(element);
};
var placeholder = $('.js-image-blur', this.$element);
var small = $('.js-small-image', placeholder);
// Load large image
var imgLarge = new Image();
imgLarge.src = placeholder.data('largeimage');
imgLarge.className = "is-large-image";
imgLarge.onload = function () {
$(imgLarge).addClass('is-loaded');
// Remove small image
setTimeout(function(){
$(small).remove();
}, 1200);
};
$(imgLarge).each(function() {
placeholder.append(this);
});
return ImageBlur;
};
I would rewrite the code like that:
$(function() {
$(".js-image-blur").each(function() {
var $this = $(this);
var $smallImage = $(".js-small-image", $this);
var $largeImage = $("<img>").attr({
src: $this.data("largeimage"),
class: "is-large-image"
}).load(function() {
$(this).addClass("is-loaded");
setTimeout(function() {
$smallImage.remove();
}, 1200);
});
$this.append($largeImage);
});
});
.image-blur {
background-color: transparent;
background-size: cover;
background-repeat: no-repeat;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
}
.image-blur img {
position: absolute;
top: 50%;
left: 50%;
min-height: 100%;
width: auto;
min-width: 100%;
transition: opacity 1s linear;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.image-blur img.small-image {
-webkit-filter: blur(20px);
filter: blur(20px);
position: absolute;
}
.image-blur img.is-large-image {
opacity: 0;
}
.image-blur img.is-loaded {
opacity: 1;
}
body {
margin: 3em 0;
background: silver;
}
.container {
position: relative;
margin: 3em auto;
min-width: 320px;
min-height: 560px;
border-top: 3px solid black;
border-bottom: 3px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">
<div class="image-blur js-image-blur" data-component="image-blur" data-largeimage="https://s3-us-west-2.amazonaws.com/s.cdpn.io/67710/1600-full.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/67710/1600-small.jpg" alt="" class="small-image js-small-image" />
</div>
</section>
<section class="container">
<div class="image-blur js-image-blur" data-component="image-blur" data-largeimage="https://s3-us-west-2.amazonaws.com/s.cdpn.io/67710/1600-2-full.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/67710/1600-2-small.jpg" alt="" class="small-image js-small-image" />
</div>
</section>
See updated Codepen.
If you want to load images silently and fade them in, a simple solution would be:
<img class="load-fade" src="url" />
And in your JavaScript:
$('.load-fade').hide().load(function() {
$(this).fadeIn(1000);
});
I wanted to create a card with text which will flip and show a backside with some other text, whenever you click on the "card" (div). I checked for any mistakes and stuff but somehow its not working on chrome.
HTML:
<div class="card effect__EFFECT">
<div class="card__front">
<span class="card__text">front</span>
</div>
<div class="card__back">
<span class="card__text">back</span>
</div>
</div>
CSS:
.card {
position: relative;
float: left;
padding-bottom: 25%;
width: 25%;
text-align: center;
}
.card__front,
.card__back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.card__front,
.card__back {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: -webkit-transform 0.3s;
transition: transform 0.3s;
}
.card__front {
background-color: #ff5078;
}
.card__back {
background-color: #1e1e1e;
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.card.effect__click.flipped .card__front {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.card.effect__click.flipped .card__back {
-webkit-transform: rotateY(0);
transform: rotateY(0);
}
Javascript:
(function() {
var cards = document.querySelectorAll(".card.effect__click");
for ( var i = 0, len = cards.length; i < len; i++ ) {
var card = cards[i];
clickListener( card );
}
function clickListener(card) {
card.addEventListener( "click", function() {
var c = this.classList;
c.contains("flipped") === true ? c.remove("flipped") : c.add("flipped");
});
}
})();
Here is a working fiddle http://jsfiddle.net/hzsbzxw6/ it seems that this should all work, it could be the way you're embedding the script.
<script type = "text/javascript">
Try fixing that, or ultimately not embedding it inline.
so I have some images and I would like to show them as a slideshow in the background. However, I want the image to cross-fade between the current image and the next image. So far, I have only been able to switch between the images:
$(document).ready(function () {
var images = ["landing_background_1.jpg", "landing_background_2.jpg", "landing_background_3.jpg", "landing_background_4.jpg"];
var currentImage = 0;
function changeBackgroundImage() {
$("html").fadeIn().css({
"background-image": "url('img/backgrounds/" + images[++currentImage] + "')",
});
if (currentImage >= images.length - 1) {
//set it back to the begining
currentImage -= images.length;
}
}
setInterval(changeBackgroundImage, 1500);
});
Any help would be much appreciated! :)
What you have to do is layer two element on top of each other. Then have one fadeout and the other fadein.
Here is how I would go about doing it ...
css ...
#background-images {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
#bImg1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 3;
background: url(starting-img1.jpg) no-repeat;
background-size: contain;
}
#bImg2 {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
background: url(starting-img2.jpg) no-repeat;
background-size: contain;
}
.container {
width: 960px;
height: 900px;
background: rgba(255,255,255,.7);
margin: auto;
position: relative;
z-index: 10;
}
The html ...
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<html>
<body>
<div id="background-images">
<div id="bImg1"></div>
<div id="bImg2"></div>
</div>
<div class="container">
Content Here
</div>
</body>
</html>
The script ...
var imageSet1 = ["image1.jpg", "image2.jpg", "image3.jpg"];
var currentImageSet1 = 0;
var imageSet2 = ["image4.jpg", "image5.jpg", "image6.jpg"];
var currentImageSet2 = 0;
function changeBackgroundImages() {
img1Fade();
setTimeout(img2Fade, 2000);
}
function img1Fade(){
$('#bImg1').fadeOut('slow', function(){$('#bImg1').css({background: 'url(' + imageSet1[++currentImageSet1] + ')'})});
$('#bImg2').fadeIn('slow');
if (currentImageSet1 >= imageSet1.length - 1) {
currentImageSet1 -= imageSet1.length;
};
}
function img2Fade(){
$('#bImg2').fadeOut('slow', function(){$('#bImg2').css({background: 'url(' + imageSet2[++currentImageSet2] + ')'})});
$('#bImg1').fadeIn('slow');
if (currentImageSet2 >= imageSet2.length - 1) {
currentImageSet2 -= imageSet2.length;
};
}
$(document).ready(function(){
setInterval(changeBackgroundImages, 5000);
});
You will need to mess with the timing to get it to look good. Make sure to set your urls to the images in the image array or when the sting in the css is built.
I've spent a lot of time to find the most clean and easy way.
This finally works:
var i=0;
var imghead=[
"url(http://yoururl.com/picture0.jpg)",
"url(http://yoururl.com/picture1.jpg)"
];//add as many images as you like
function slideimg() {
setTimeout(function () {
jQuery('#element').css('background-image', imghead[i]);
i++;
if(i==imghead.length) i=0;
slideimg();
}, 6000);
}
slideimg();
#element{
height: 100%;
overflow: hidden;
opacity: 1.0;
-webkit-transition: background-image 1.5s linear;
-moz-transition: background-image 1.5s linear;
-o-transition: background-image 1.5s linear;
-ms-transition: background-image 1.5s linear;
transition: background-image 1.5s linear;
}
Easier:
var current = 1;
function anim() {
if(current == 4) {current = 1; }
$('#bImg'+ current).fadeOut(3000);
++current;
$('#bImg'+ current).fadeIn(3000);
setTimeout(anim, 8000);
}
anim();
html:
<div class="inside" >
<div id="bImg2"></div>
<div id="bImg3"></div>
</div>
css:
.inside {
background:url(top_01.jpg) no-repeat center top ;
}
#bImg2 {
position: absolute;
top: 0px;
width: 100%;
background:url(top_02.jpg) no-repeat center top ;
display: none;
}
#bImg3 {
position: absolute;
top: 0px;
width: 100%;
background:url(top_03.jpg) no-repeat center top ;
display: none;
}