Cross fade background-image with jQuery - javascript

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;
}

Related

How to create an image that repeats for a js fade in and out background slideshow?

I am currently building a website and I want a aesthetically pleasing landing page with a background fade in and out slideshow comprised of pictures that repeat y and x. I have the fading slideshow working perfectly and all I need is to repeat the image across the screen. Adding background: repeat to the CSS does not work. Below is may code:
HTML:
<div class="mybody" id="slider">
<div>
<h2>Dog Adoption</h2>
<p>Find the perfect match for your new four legged companion</p>
</div>
</div>
JavaScript:
var curIndex = 0,
imgDuration = 3000,
slider = document.getElementById("slider"),
slides = slider.childNodes; //get a hook on all child elements, this is live so anything we add will get listed
imgArray = [
'../../static/main/images/slideshow/dog2.jpg',
'../../static/main/images/slideshow/dog3.jpg',
'../../static/main/images/slideshow/dog4.jpg',
'../../static/main/images/slideshow/dog1.jpg',
];
//
// Dynamically add each image frame into the dom;
//
function buildSlideShow(arr) {
for (i = 0; i < arr.length; i++) {
var img = document.createElement('img');
img.src = arr[i];
slider.appendChild(img);
}
// note the slides reference will now contain the images so we can access them
}
//
// Our slideshow function, we can call this and it flips the image instantly, once it is
called it will roll
// our images at given interval [imgDuration];
//
function slideShow() {
function fadeIn(e) {
e.className = "fadeIn";
};
function fadeOut(e) {
e.className = "";
};
fadeOut(slides[curIndex]);
curIndex++;
if (curIndex === slides.length) {
curIndex = 0;
}
fadeIn(slides[curIndex]);
setTimeout(function () {
slideShow();
}, imgDuration);
};
buildSlideShow(imgArray);
slideShow();
CSS:
.mybody{
width: 100%;
min-height: 100vh;
max-height: fit-content;
top: 0px;
left: 0px;
padding: 0px;
/*background: url(../images/slideshow/dog1.jpg);*/
display: flex;
justify-content: center;
align-items: center;
text-align: center;
margin: 0px;
position: relative;
background-repeat: repeat;
}
.mybody img {
transition: opacity 1.5s;
position: absolute;
left: 0;
top: 0;
opacity:0;
background-repeat: repeat;
}
.mybody img.fadeIn {
opacity:1;
}
When I just set the background image as a fixed image (no JS) I get the desired result:
However when I comment out the backgorund image (as in above code) and just have the JS slideshow as the background, this is the result:
I essentially just need this image from the second picture to repeat as in the first picture and cannot figure out how to make this happen although I am sure there is a simple fix/solution. If anyone could be of help it would be much appreciated. Thanks in advance!
You can't repeat an image without duplicating it. But you can repeat background so, you can make the slide using divs with background. Note the usage of css classes instead of jquery fade.
slide = 1;
setInterval(function() {
$(".slide").removeClass("active");
$(".div" + slide).addClass("active");
slide++
if (slide == 4) {
slide = 1;
}
}, 1000)
body {
height: 100vh;
width: 100%;
position: relative;
padding: 0;
margin: 0;
text-align: center;
padding: 30px;
}
.slide {
background-repeat: repeat;
background-size: 100px;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
opacity: 0;
transition: 1000ms all;
}
.slide.active {
opacity: 1;
}
.div1 {
background: url('https://picsum.photos/id/101/200');
}
.div2 {
background: url('https://picsum.photos/id/102/200');
}
.div3 {
background: url('https://picsum.photos/id/103/200');
}
.text {
position: relative;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<body>
<div class="slide div1">
</div>
<div class="slide div2">
</div>
<div class="slide div3">
</div>
<div class="text">
<h1>dog trainer</h1>
<p>best in the world</p>
</div>
</body>

Javascript nth-of-type and data-attribute (change background images on hover links)

Somehow I can't get the following script to run.
The idea is to swap background images of a div, once the links with its corresponding data attributes are hovered. To be clear, both the links and the background images are listed separately.
Can someone help me with the solution??
Ps: Codepen example over here: https://codepen.io/eric-schakel/pen/qBXvgoM
!(function (t) {
class Bo {
constructor(t) {
const e = $$$(".capabilities__list a"),
i = $$(".capabilities__list");
e.forEach((t) => {
t.addEventListener("mouseover", function () {
const e = t.getAttribute("data-capability");
$$(".background__images img:nth-of-type(" + e + ")").classList.add("active");
}),
t.addEventListener("mouseout", function () {
const e = t.getAttribute("data-capability"),
i = $$(".background__images img:nth-of-type(" + e + ")");
i && i.classList.remove("active");
}),
t.addEventListener("click", function () {
window.capability = this.getAttribute("data-capability");
}),
i.addEventListener("mouseover", function () {
$$("#home__capabilities img.fill-background").classList.add("hidden");
}),
i.addEventListener("mouseout", function () {
const t = $$("#home__capabilities img.fill-background");
t && t.classList.remove("hidden");
});
});
}
}
});
#home__capabilities {
width: 100vw;
height: 60vh;
display: flex;
align-items: center;
}
img.fill-background {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
img.fill-background.hidden {
opacity: 0;
}
.capabilities__list {
font-size: 50px;
z-index: 10;
}
.capabilities__list a:hover {
opacity: .5;
}
.background__images {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
z-index: 1;
}
.background__images img {
width: 100%;
height: 100%;
max-width: 100%;
object-fit: cover;
opacity: 0;
position: absolute;
top: 50%;
transform: translateY(-50%) translateZ(0) scale(1.01);
transform-origin: left center;
transition: opacity .2s ease-in-out,transform .4s ease;
}
.background__images img.active {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="home__capabilities">
<img class="fill-background" src="https://images.unsplash.com/photo-1428606381429-22224991fb0c">
<div class="capabilities__list">
Link 01
Link 02
Link 03
Link 04
</div>
<div class="background__images">
<img src="https://images.unsplash.com/photo-1427830574887-32e5702033b0">
<img src="https://images.unsplash.com/photo-1427830180740-12146c79a1a3">
<img src="https://images.unsplash.com/photo-1415226181422-279a51ca056e">
<img src="https://images.unsplash.com/photo-1450885413713-176921f199b2">
</div>
</section>
Here
I changed a few things I would love to delegate more, but that would change your code too much.
Syntax error - script should end on }) and not ])
Instantiation of class was missing
Variable names and constants were not understandable
Missing helper functions for querySelector and querySelectorAll
!(function() {
class Bo {
constructor() {
const $$ = selector => document.querySelector(selector),
$$$ = selector => document.querySelectorAll(selector),
links = $$$(".capabilities__list a"),
list = $$(".capabilities__list");
links.forEach(link => {
link.addEventListener("mouseover", function() {
const capability = link.getAttribute("data-capability");
$$(".background__images img:nth-of-type(" + capability + ")").classList.add("active");
}),
link.addEventListener("mouseout", function() {
const capability = link.getAttribute("data-capability"),
image = $$(".background__images img:nth-of-type(" + capability + ")");
image && image.classList.remove("active");
}),
link.addEventListener("click", function() {
window.capability = this.getAttribute("data-capability");
}),
list.addEventListener("mouseover", function() {
$$("#home__capabilities img.fill-background").classList.add("hidden");
}),
list.addEventListener("mouseout", function() {
const image = $$("#home__capabilities img.fill-background");
image && image.classList.remove("hidden");
});
});
}
}
const list = new Bo()
})();
#home__capabilities {
width: 100vw;
height: 60vh;
display: flex;
align-items: center;
}
img.fill-background {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
img.fill-background.hidden {
opacity: 0;
}
.capabilities__list {
font-size: 50px;
z-index: 10;
}
.capabilities__list a:hover {
opacity: .5;
}
.background__images {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
z-index: 1;
}
.background__images img {
width: 100%;
height: 100%;
max-width: 100%;
object-fit: cover;
opacity: 0;
position: absolute;
top: 50%;
transform: translateY(-50%) translateZ(0) scale(1.01);
transform-origin: left center;
transition: opacity .2s ease-in-out, transform .4s ease;
}
.background__images img.active {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="home__capabilities">
<img class="fill-background" src="https://images.unsplash.com/photo-1428606381429-22224991fb0c">
<div class="capabilities__list">
Link 01
Link 02
Link 03
Link 04
</div>
<div class="background__images">
<img src="https://images.unsplash.com/photo-1427830574887-32e5702033b0">
<img src="https://images.unsplash.com/photo-1427830180740-12146c79a1a3">
<img src="https://images.unsplash.com/photo-1415226181422-279a51ca056e">
<img src="https://images.unsplash.com/photo-1450885413713-176921f199b2">
</div>
</section>

I doing setTimeout loaing symbol in javascript?

Javascript setTimeout working well. but opacity starting in 1 to 0.5. How to fixed opacity 0.50 in setTimeout mode?
jQuery(document).ready(function() {
document.getElementById('load').style.visibility = "visible";
document.getElementById('load').style.width = '100' + '%';
document.getElementById('load').style.height = '100' + '%';
document.getElementById('load').style.position = 'initial';
document.getElementById('load').style.backgroundImage = "url('image/load.gif')";
jQuery('#load').fadeOut(3000);
});
#load {
background-repeat: no-repeat;
background-position: center;
opacity: 0.50 !important;
z-index: 999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id='load'>
</div>
</body>
Check out the below. Try using animate
var x = document.getElementById('load');
$(x).animate({opacity:0.5},3000);
Hope this helps..!
Instead you can do it like following way:
HTML, CSS and JS
jQuery(document).ready(function() {
setTimeout(function() {
jQuery('#load').removeClass('active');
}, 1000)
});
#load {
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
transition: 0.5s;
text-align: center;
display: none;
}
#load.active {
display: block;
transition: 0.5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='load' class="active">
<img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">
</div>
Here is jsfiddle link

progress bar is not working

i am trying to made progress bar but its can working plz solve it .
i am using if else for increasing the width but it's not working
var x = document.getElementById("p_bar");
for(var i = 0; i < 100; i++) {
var wid;
wid=1;
if(wid == 800)
break;
else
wid+=8;
x.style.width=wid+"px";
}
document.body.style.background = "#"+((1<<24)*Math.random()|0).toString(16);
#cont {
width: 800px;
height: 30px;
background-color: cornsilk;
position: relative;
}
#p_bar {
width: 8px;
height: 30px;
background-color: red;
position: absolute;
}
<div id="cont">
<div id="p_bar"></div>
</div>
<p id="write"></p>
var x=document.getElementById("p_bar");
var wid = 1;
var it = setInterval(function(){
if(wid <= 800){
wid+=8;
x.style.width=wid+"px";
}else{
clearInterval(it);
}
}, 1000);
document.body.style.background = "#"+((1<<24)*Math.random()|0).toString(16);
#cont{
width: 800px;
height: 30px;
background-color: cornsilk;
position: relative;
}
#p_bar{
width: 8px;
height: 30px;
background-color: red;
position: absolute;
}
<div id="cont">
<div id="p_bar"></div></div>
<p id="write"></p>
If you want to see moving progress bar, You should use setInterval().
If you use just for, you can't see any animation.
Because, computer's calculating is so fast, so you can see only the result of for
I wrote it again using functions, try this shubham:
var x = document.getElementById('p_bar');
var container = document.getElementById('cont');
var write = document.getElementById('write');
var containerWidth = container.offsetWidth;
var currentWidth = x.offsetWidth;
var compeleteProgress = function (step, every) {
currentWidth = Math.min(currentWidth + step, containerWidth);
write.innerHTML = Math.floor((currentWidth / containerWidth) * 100) + '%' // Priniting percentage
x.style.width = currentWidth + 'px'
if (currentWidth < containerWidth) setTimeout(function () {
compeleteProgress(step, every)
}, every)
}
compeleteProgress(8, 300) // When you call this function, everything starts
document.body.style.background = "#"+((1<<24)*Math.random()|0).toString(16);
#cont{
width: 800px;
height: 30px;
background-color: cornsilk;
position: relative;
}
#p_bar{
width: 8px;
height: 30px;
background-color: red;
position: absolute;
}
<div id="cont">
<div id="p_bar"></div>
</div>
<p id="write"></p>
I am not sure what behavior you really expects. The Bar size is usually changed according to any application events (in my example by timeouts). I hope this helps:
document.body.style.background = "#"+((1<<24)*Math.random()|0).toString(16);
var setBarWidthInPercent = function(barId, value){
var bar=document.getElementById(barId);
bar.style.width = value+"%";
}
setTimeout(function(){
setBarWidthInPercent("p_bar",10)
},500)
setTimeout(function(){
setBarWidthInPercent("p_bar",50)
},1500)
setTimeout(function(){
setBarWidthInPercent("p_bar",100)
},3000)
#cont{
width: 800px;
height: 30px;
background-color: cornsilk;
position: relative;
}
#p_bar{
width: 8px;
height: 30px;
background-color: red;
position: absolute;
-webkit-transition: width 1s ease-in-out;
-moz-transition: width 1s ease-in-out;
-o-transition: width 1s ease-in-out;
transition: width 1s ease-in-out;
}
<div id="cont">
<div id="p_bar"></div></div>
<p id="write"></p>

document.querySelectorAll does not work

I've just started to study javascript, and checked the example from the website https://cssanimation.rocks/clocks/. But, unfortunatelly, one part in js script does not work. The code is like this:
/*
* Starts any clocks using the user's local time
* From: cssanimation.rocks/clocks
*/
(function() {
// Initialise the locale-enabled clocks
//initInternationalClocks();
// Initialise any local time clocks
initLocalClocks();
// Start the seconds container moving
//moveSecondHands();
// Set the intial minute hand container transition, and then each subsequent step
//setUpMinuteHands();
})();
function initLocalClocks() {
//get the local time using javascript
var date = new Date();
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hours = date.getHours();
var hands = [
{
hand: "hours",
angle: (hours * 30) + (minutes/2)
},
{
hand: "minutes",
angle: (minutes * 6)
},
{
hand: "seconds",
angle: (seconds * 6)
},
];
for (var j = 0; j < hands.length; j++){
var elements = document.querySelectorAll('.' + hands[j].hand);
// window.alert(elements.length);
for (var k = 0; k < elements.length; k++)
{
// window.alert(elements[k]);
elements[k].style.webkitTransform = 'rotateZ(' + hands[j].angle + 'deg)';
elements[k].style.transform = 'rotateZ(' + hands[j].angle + 'deg)';
if (hands[j].hand === 'minutes'){
elements[k].parentNode.setAttribute('data-second-angle', hands[j+1].angle)
}
}
}
}
// Set a timeout for the first minute hand movement (less than 1 minute), then rotate it every minute after that
function setUpMinuteHands() {
// Find out how far into the minute we are
var containers = document.querySelectorAll('.minutes-container');
var secondAngle = containers[0].getAttribute("data-second-angle");
if (secondAngle > 0) {
// Set a timeout until the end of the current minute, to move the hand
var delay = (((360 - secondAngle) / 6) + 0.1) * 1000;
setTimeout(function() {
moveMinuteHands(containers);
}, delay);
}
}
.footer{
color: black;
font-style: italic;
position: fixed; bottom: 0; left:0; right: 0; height: 30px;
float: left;
clear: both;
}
.clock {
border-radius: 50%;
background: #fff url(./images/ios_clock.svg) no-repeat center;
background-size: 88%;
height: 20em;
padding-bottom: 0%;
position: relative;
width: 20em;
}
.clock::after{
background: #000;
border-radius: 50%;
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 5%;
height: 5%;
z-index: 10;
}
.minutes-container, .hours-container, .seconds-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.hours {
background: #000;
height: 20%;
left: 48.75%;
position: absolute;
top: 30%;
transform-origin: 50% 100%;
width: 2.5%;
}
.minutes {
background: #000;
height: 40%;
left: 49%;
position: absolute;
top: 10%;
transform-origin: 50% 100%;
width: 2%;
}
.seconds {
background: #000;
height: 45%;
left: 49.5%;
position: absolute;
top: 14%;
transform-origin: 50% 100%;
width: 1%;
z-index: 8;
}
#keyframes rotate {
100% {
transform: rotateZ(360deg);
}
}
.hours-container{
animation: rotate 43200s infinite linear;
}
.minutes-container{
animation: rotate 3600s infinite linear;
}
.seconds-container {
animation: rotate 60s infinite linear;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="script.js" ></script>
</head>
<body>
<article class="clock">
<div class="hours-container">
<div class="hours"></div>
</div>
<div class="minutes-container">
<div class="minutes"></div>
</div>
<div class="seconds-container">
<div class="seconds"></div>
</div>
</article>
</body>
<footer>
<div class="footer">All materials are taken from the website cssanimation.rocks
</div>
</footer>
</html>
And when I open page, javascript is executed, but array "elements" from the line:
var elements = document.querySelectorAll('.' + hands[j].hand)
is empty. I've checked via alert windows, and really, querySelectorAll does not return objects, but name of css class seems to be correct... I've tried the same in console (like: document.querySelectorAll('.hands'), and it returns the needed div...
Could you, please, help me - what can be wrong with it?...
P.S. When I've pasted snippet to this post, the js script seems working... Now I'm completely lost - is it something with my browser settings, or something?
Thank you very much in advance for any suggestion/help!

Categories