Background Image Transition - javascript

I am trying to get my background "jumbotron" to change images. It works, however, I would like to add a transition to the image background as it is pretty rough. I was hoping to do it in the internal script or javascript however neither appears to be working. Is there any way to achieve this I've been trying to figure it out for a few hours and I can not find any guides online for it that makes sense to me.
var i = 0;
var images = [];
var slideTime = 12000; // 12 seconds
images[0] = 'https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg';
images[1] = 'https://thumbs.dreamstime.com/b/portrait-funny-cat-fly-his-nose-portrait-funny-cat-fly-his-nose-isolated-white-background-125606127.jpg';
images[2] = 'https://mymodernmet.com/wp/wp-content/uploads/2022/11/masayuki-oki-cat-street-photography-19.jpeg';
function changePicture() {
document.getElementById('jumbotron').style.transition = "all 4s";
document.getElementById('jumbotron').style.backgroundImage = "linear-gradient(to right bottom, #0d146f, transparent)," + "url(" + images[i] + ")";
if (i < images.length - 1) {
i++;
} else {
i = 0;
}
setTimeout(changePicture, slideTime);
}
window.onload = changePicture;
#jumbotron {
background-position: center;
background-size: cover;
background-repeat: no-repeat !important;
height: 100vh;
-webkit-transition: background-image 2s ease-in-out;
transition: background-image 2s ease-in-out;
}
.center h3 {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -180%);
}
.center p {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -50%);
}
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<div id="jumbotron" class="text-white text-center" style="">
<div class="center" slot="float: right;">
<h3>Welcome!</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>

I managed to make a smooth transition by giving the jumbotron just the linear gradient background and using an absolute positioned child element with a transition on opacity. The trick is to fade out the background before changing the image and fading back in.
var i = 0;
var images = [];
var slideTime = 12000; // 12 seconds
images[0] = 'https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg';
images[1] = 'https://thumbs.dreamstime.com/b/portrait-funny-cat-fly-his-nose-portrait-funny-cat-fly-his-nose-isolated-white-background-125606127.jpg';
images[2] = 'https://mymodernmet.com/wp/wp-content/uploads/2022/11/masayuki-oki-cat-street-photography-19.jpeg';
const bg = document.querySelector('#jumbotron .bgi')
function changePicture() {
bg.classList.add('fade')
setTimeout(() => {
bg.style.backgroundImage = "linear-gradient(to right bottom, #0d146f, transparent)," + "url(" + images[i] + ")";
bg.classList.remove('fade')
}, 2000)
if (i < images.length - 1) {
i++;
} else {
i = 0;
}
setTimeout(changePicture, slideTime);
}
window.onload = changePicture;
#jumbotron {
position: relative;
height: 100vh;
background-image: linear-gradient(to right bottom, #0d146f, transparent);
}
#jumbotron .bgi {
content: "";
background-position: center;
background-size: cover;
background-repeat: no-repeat !important;
-webkit-transition: all 2s ease-in-out;
transition: all 2s ease-in-out;
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
#jumbtron .bgi.fade {
opacity: 0;
}
.center h3 {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -180%);
}
.center p {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -50%);
}
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<div id="jumbotron" class="text-white text-center" style="">
<div class="bgi"></div>
<div class="center" slot="float: right;">
<h3>Welcome!</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>

I did something similar using pseudo element after (or before). My implementation was in React using styled-components.
I tried to create the same using vanilla js. I hope it helps.
https://codesandbox.io/s/determined-ramanujan-z70egr
Essentially I am adding and removing a css rule (pseudo element before) where I run a transition to background-size.
I'm not using opacity because I thought that what the original question was related to transitioning background images. But I think those solutions look better to me as you don't have to touch the CSS rules.
const images = [];
const slideTime = 2000; // 2 seconds made it short to not wait much for this demo
let i = 0;
images[0] =
"https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg";
images[1] =
"https://thumbs.dreamstime.com/b/portrait-funny-cat-fly-his-nose-portrait-funny-cat-fly-his-nose-isolated-white-background-125606127.jpg";
images[2] =
"https://mymodernmet.com/wp/wp-content/uploads/2022/11/masayuki-oki-cat-street-photography-19.jpeg";
function changePicture() {
document.styleSheets[0].insertRule(
`#jumbotron::before { position: absolute; content: ''; top:0; left:0;width: 100%; height: 100%; background-image: url("${images[i]}"); background-size: cover; transition: all 1s ease; transform-origin: 0% 50%; }`,
document.styleSheets[0].cssRules.length - 1
);
}
function run() {
i++;
if (i === 3) {
i = 0;
}
}
function removeRule() {
setTimeout(() => {
document.styleSheets[0].deleteRule(
document.styleSheets[0].cssRules.length - 1
);
}, slideTime);
}
window.onload = () => {
setInterval(() => {
run();
changePicture();
removeRule();
}, slideTime);
};
#jumbotron {
height: 100vh;
position: relative;
}
#jumbotron::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg");
background-size: cover;
transition: all 1s ease;
transform-origin: 0% 50%;
}
#jumbotron::after {
content: "";
inset: 0;
position: absolute;
background-image: linear-gradient(to right bottom, #0d146f, transparent);
}
.center h3 {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -180%);
}
.center p {
margin: 0;
position: absolute;
top: 40%;
left: 20%;
transform: translate(-50%, -50%);
}
<html lang="en">
<head>
<link rel="stylesheet" href="./styles.css" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
</head>
<body>
<div id="jumbotron" class="text-white text-center">
<div class="center" slot="float: right;">
<h3>Welcome!</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<script src="./script.js"></script>
</body>
</html>
When you run the snippet, at least in my end, the pictures flash the first time they are loaded. This won't occur on codesandbox (see link above)

If you want a transition between two background images, I suggest using ::before and ::after pseudo-elements with background images, and then change the opacity on one of them.
I think it's easier if I showed the changes in steps. This code below have the same behavior as your code, where I only set --background-image.
I should point out that you should never ever use float and position: absolute unless you know what you're doing, because it just messes up the page flow. I updated (removed) the CSS accordingly. Also, Bootstrap is just the worst because you will end up trying to override anything Boostrap tries to implement, just like your CSS code did in your snippet.
var i = 0;
var images = [];
var TWELVE_SECONDS = 12000;
images[0] = 'https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg';
images[1] = 'https://thumbs.dreamstime.com/b/portrait-funny-cat-fly-his-nose-portrait-funny-cat-fly-his-nose-isolated-white-background-125606127.jpg';
images[2] = 'https://mymodernmet.com/wp/wp-content/uploads/2022/11/masayuki-oki-cat-street-photography-19.jpeg';
function changePicture() {
let nextImage = i++ % images.length;
document.getElementById('jumbotron').style.setProperty('--background-image', `url(${images[nextImage]}`);
setTimeout(changePicture, TWELVE_SECONDS);
}
window.onload = changePicture;
#jumbotron {
--foreground-image: '';
--background-image: '';
position: relative;
height: 100vh;
background-image: linear-gradient(to right bottom, #0d146f, transparent);
}
#jumbotron::before,
#jumbotron::after {
content: '';
position: absolute;
inset: 0px; /* top: 0; bottom: 0; left: 0; right: 0; */
background-image: var(--foreground-image);
background-position: center;
background-size: cover;
background-repeat: no-repeat !important;
z-index: -1;
}
#jumbotron::after {
background-image: var(--background-image);
z-index: -2;
}
.center {
display: inline-block;
position: relative;
margin-top: 10%;
margin-left: 20%;
text-align: center;
}
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<div id="jumbotron" class="text-white">
<div class="center" slot="float: right;">
<h3>Welcome!</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
So if I expand on this code above, I will set the old visible image as a foreground image (in ::before), and then set it's opacity to 0 to fade out to the new image set in the background image (in ::after).
I also set the animation speed in code, so it's easier to just change one value rather than having to jump around between CSS and javascript if you want to change certain values.
As a bonus, I added preloading of the next image as well. You don't want to transition into an image that haven't been loaded.
var i = 0;
var images = [];
var preloadedImage = new Image();
var TWELVE_SECONDS = 12000;
var TWO_SECONDS = 2000;
images[0] = 'https://i.pinimg.com/736x/ba/92/7f/ba927ff34cd961ce2c184d47e8ead9f6.jpg';
images[1] = 'https://thumbs.dreamstime.com/b/portrait-funny-cat-fly-his-nose-portrait-funny-cat-fly-his-nose-isolated-white-background-125606127.jpg';
images[2] = 'https://mymodernmet.com/wp/wp-content/uploads/2022/11/masayuki-oki-cat-street-photography-19.jpeg';
function changePicture() {
let jumbotronEl = document.getElementById('jumbotron');
let oldImage = (i-1) % images.length;
let currentImage = i++ % images.length;
let upcomingImage = i % images.length;
if (preloadedImage.src) {
jumbotronEl.style.setProperty('--foreground-image', `url(${images[oldImage]}`);
jumbotronEl.style.setProperty('--background-image', `url(${images[currentImage]}`);
jumbotronEl.style.setProperty('--opacity-animation-duration', TWO_SECONDS + 'ms');
toggleForegroundFade();
setTimeout(toggleForegroundFade, TWO_SECONDS);
} else {
jumbotronEl.style.setProperty('--background-image', `url(${images[currentImage]}`);
}
setTimeout(() => {
preloadedImage.src = images[upcomingImage]
}, TWO_SECONDS);
setTimeout(changePicture, TWELVE_SECONDS);
}
function toggleForegroundFade() {
document.getElementById('jumbotron').classList.toggle('foreground-hidden');
}
window.onload = changePicture;
#jumbotron {
--foreground-image: '';
--background-image: '';
--opacity-animation-duration: '';
position: relative;
height: 100vh;
background-image: linear-gradient(to right bottom, #0d146f, transparent);
}
#jumbotron.foreground-hidden::before {
opacity: 0;
transition: opacity var(--opacity-animation-duration);
}
#jumbotron::before,
#jumbotron::after {
content: '';
position: absolute;
inset: 0px; /* top: 0; bottom: 0; left: 0; right: 0; */
background-image: var(--foreground-image);
background-position: center;
background-size: cover;
background-repeat: no-repeat !important;
z-index: -1;
}
#jumbotron::after {
background-image: var(--background-image);
z-index: -2;
}
.center {
display: inline-block;
position: relative;
margin-top: 10%;
margin-left: 20%;
text-align: center;
}
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<div id="jumbotron" class="text-white foreground-hidden">
<div class="center">
<h3>Welcome!</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>

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>

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

Troubles with changing background image via jQuery while browserSync is not running

I have a slider that works by changing positions of background-images. Also i use the BrowserSync. While BrowserSync runs, slider works good, while not - all animations are commiting, but .slide background image not appears at all. What did i do wrong?
P.S. also i use backgroundPosition script - it allows to set few arguments.
Watch correct: https://gyazo.com/2185ae332bac4b1da1bd4f2fcd9bfe5a
Watch uncorrect: https://gyazo.com/681a28e927ef537f1f4f034faeb56b0d
html:
<!DOCTYPE html>
<html>
<head>
<title>Slider</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="styles/reset.css">
<link rel="stylesheet" type="text/css" href="styles/main.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="js/backgroundPosition.js"></script>
<script src="js/slider.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
</head>
<body>
<div class="slider">
<div class="upside">
<div class="slide">
<div class="wheel"></div>
</div>
</div>
</div>
<div class="next"></div>
</body>
</html>
css:
body{
height: 100%;
width: 100%;
}
.slider, .upside, .slide{
height: 650px;
width: 1200px;
margin: 0 auto;
border-radius: 15px;
}
.slider{
margin: 50px auto;
background: url(../img/bg.jpg) no-repeat center;
overflow: hidden;
}
.upside{
background-image: url(../img/upside.png);
background-repeat: no-repeat;
background-position: 0px -800px;
}
.slide{
background-image: url(../img/sl_1.jpg);
background-repeat: no-repeat;
}
#keyframes rt{
100%{
transform: rotate(360deg);
}
}
.wheel{
height: 640px;
width: 180px;
background-image: url(../img/wheel.png);
background-repeat: no-repeat;
background-position: left center;
position: relative;
margin: 0px 0 0 -180px;
animation: rt 6s linear infinite
}
.next{
height: 120px;
width: 120px;
margin: 0px auto;
font-family: 'Open Sans', sans-serif;
color: white;
font-size: 30px;
text-align: center;
line-height: 120px;
vertical-align: middle;
text-transform: uppercase;
background:url(../img/next.png) no-repeat;
border-radius: 50%;
opacity: .55;
}
js:
$(function(){
var btn = $(".next"),
wheel = $(".wheel"),
upside = $(".upside"),
slide = $(".slide"),
cur_slide = 1;
var nextSlide = function(){
btn.off();
cur_slide++;
if(cur_slide===4){cur_slide=1;}
var i1 = 0;//upside bottom point
var i2 = 650;//slide bottom point
wheel.animate({
margin: "0px 0 0 -105px"
},800,
function(){
slide.animate({
backgroundPosition:("-1200 0")
},1000,
function(){
upside.animate({
backgroundPosition:("0 0")
},1200,
function(){
slide.css('background-image',"url(../img/sl_"+cur_slide+".jpg)");
var up = setInterval(function(){
upside.css("background-position","0 "+i1+"px");
slide.css("background-position","0 "+i2+"px");
if (i2===0) {
clearInterval(up);
upside.css("background-position","0 -800px");
wheel.animate({
margin: "0px 0 0 -180px"
},800,
function(){
btn.click(nextSlide);
})
}
i1--;
i2--;
},2);
})
})
})
}
btn.click(nextSlide);
})
here is the code of backgroundPosition.js (dont know do you need it or not)
(function($) {
$.extend($.fx.step,{
backgroundPosition: function(fx) {
if (fx.pos === 0 && typeof fx.end == 'string') {
var start = $.css(fx.elem,'backgroundPosition');
start = toArray(start);
fx.start = [start[0],start[2]];
var end = toArray(fx.end);
fx.end = [end[0],end[2]];
fx.unit = [end[1],end[3]];
}
var nowPosX = [];
nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
function toArray(strg){
strg = strg.replace(/left|top/g,'0px');
strg = strg.replace(/right|bottom/g,'100%');
strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
}
}
});
})(jQuery);
Well, if someone will get the same problem, i post this solution:
We have to change this:
slide.css('background-image',"url(../img/sl_"+cur_slide+".jpg)");
to this:
slide.css('background-image',"url(img/sl_"+cur_slide+".jpg)");

Create several new Image() objects with dynamic src javascript

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

Cross fade background-image with jQuery

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

Categories