I would like to change a background image with JavaScript.
JS:
<head>
<script type="text/javascript">
// Ta funkcja odpowiedzialna jest odpowiedzialna za zmiane obrazow w tle
$(window).load(function(){
var i = 0;
var images = ['images/1.jpg','images/2.jpg','images/3.jpg','images/4.jpg','images/5.jpg'];
var image = $('#slideit');
image.css('background-image', 'url(images/1.jpg)');
image.css('background-size', 'cover');
setInterval(function(){
image.css('background-image', 'url(' + images [i++] +')');
// image.fadeOut(1500, function (){
// image.fadeIn(1000);
// })
if(i == images.length) i = 0;
}, 6000);
});
</script>
</head>
HTML:
<body id="slideit" style="width:100%;height:100%;">
The problem is in making the images change smoothly. The commented out code makes everything in the website fade in and fade out except the background. Why is this happening? This code works but does not change the image smoothly. How can I fade the images in and out?
Unfortunately CSS does not support the animation (via transition) of background images. Why? Actually, I'm not sure why. But it's enough to know they don't. Javascript works directly by extending CSS functionality. In short, what you want to do can't be done with Javascript without writing a very convoluted piece of code designed at hacking its functionality.
There is an easy work around using jQuery, however, which will actually make your source less complex too. Make the body relative, add each individual background image to the bottom of your source (to make them load after everything else) inside a named wrapper. Let's go with #backgrounds.
<style>
body{
height:100%;
position:relative
}
#backgrounds img{
position:absolute;
z-index:1; // this is important
top:0;
left:0;
width:100%;
height:100%;
opacity:0;
display:none;
}
#wrapper{
position:relative;
z-index:3; // again, this is important
}
</style>
We set the z-index of the wrapper to be higher than that of the images so that our content is in front of them, thus giving the illusion the images are background images. Change position:absolute to position:fixed if you want a background-attachment:fixed effect. I'm assuming you want their widths and heights to be that of the viewport; change them to whatever if not. We set the images to display:none to stop them all loading when the page loads. Yuck!
<div id="wrapper">
all of your page are belong to us...
</div>
<div id="backgrounds">
<img src="background/one.jpg" alt="">
<img src="background/two.jpg" alt="">
<img src="background/three.jpg" alt="">
</div>
And then simply cycle through each image using a counter based on the number of images (so you can easily cut and paste more images in later without any effort):
$(function(){
var total = $('#backgrounds img').length;
var counter = 1;
function cycle(){
// Makes old backgrounds appear beneath new ones
$('#backgrounds img').css('z-index','1')
// Set it to display and opacity 0 so we get the effect
$('#backgrounds img:nth-child('+counter+')').css({'opacity':'0','display':'block','z-index':'2'})
// Fade the background in
$('#backgrounds img:nth-child('+counter+')').animate({'opacity':'1'},1500)
// increase the counter
counter++
// make sure we're working within the quantity of images we have
if( counter > total ){ counter = 1 }
}
cycle();
setInterval(function(){cycle()},6000);
})
Try
$(function() {
$.fx.interval = 3000;
(function cycleBgImage(elem, bgimg) {
elem.css("backgroundImage", bgimg).delay(3000, "fx")
.fadeTo(3000, 1, "linear", function() {
$(this).fadeTo(3000, 0, "linear", function() {
var img = $(this).css("backgroundImage").split(",")
, bgimg = img.concat(img[0]).splice(1).join(",");
cycleBgImage(elem, bgimg);
});
});
}($("#slideit")));
});
#slideit {
width: 100%;
height: 100%;
display: block;
opacity: 0.0;
background-color: #000;
background-image: url("http://lorempixel.com/400/400/cats/?1")
, url("http://lorempixel.com/400/400/animals/?2")
, url("http://lorempixel.com/400/400/nature/?3")
, url("http://lorempixel.com/400/400/technics/?4")
, url("http://lorempixel.com/400/400/city/?5");
background-size: cover, 0px, 0px, 0px;
-webkit-transition: background-image 3000ms linear;
-moz-transition: background-image 3000ms linear;
-ms-transition: background-image 3000ms linear;
-o-transition: background-image 3000ms linear;
transition: background-image 3000ms linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body id="slideit"></body>
Related
Im trying to work out script that will change background images every 3 sec using fadeIn, fadeOut, addClass and removeClass.
Is there a better way to do it using setInterval?
$("document").ready(function () {
$("#bg").delay(3000);
$("#bg").fadeOut(300);
$("#bg").removeClass('bg1');
$("#bg").addClass('bg2');
$("#bg").fadeIn(300);
$("#bg").delay(3000);
$("#bg").fadeOut(300);
$("#bg").removeClass('bg2');
$("#bg").addClass('bg1');
$("#bg").fadeIn(300);
});
btw. its not working properly.
HTML:
<div id="bg" class="ShowBG bg1"></div>
CSS:
#bg{
position:absolute;
width:100%;
height:70%;
background-size:cover;
background-position:center;
display:none;
}
.bg1{background-image:url("/img/index/bg1.png");}
.bg2{background-image:url("/img/index/bg2.png");}
Your method should work just fine but it's not the best way to write it: what if your graphic designer suddenly decides to add another background image in the cycle? Your code could become pretty long pretty fast. Here's how I would do it:
var backgroundClasses = ['bg1', 'bg2']; // Store all the background classes defined in your css in an array
var $element = $('.container'); // cache the element we're going to work with
var counter = 0; // this variable will keep increasing to alter classes
setInterval(function() { // an interval
counter++; // increase the counter
$element.fadeOut(500, function() { // fade out the element
$element.removeClass(backgroundClasses.join(' ')). // remove all the classes defined in the array
addClass(backgroundClasses[counter % backgroundClasses.length]). // add a class from the classes array
fadeIn(500); // show the element
});
}, 3000)
.container {
width: 100vw;
height: 100vh;
}
.bg1 {
background-color: red;
}
.bg2 {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container bg1"></div>
The hardest part of the code is this:
$element.addClass(backgroundClasses[counter % backgroundClasses.length])
It basically adds one of the classes stored in the backgroundClasses array. Using the modulo operator (%) on the counter will basically start over every time it has reached the end of the array, counting 0, 1, 0, 1, 0, 1 if you're array is only 2 elements long. If it's 3 elements long it counts 0, 1, 2, 0, 1, 2, ... and so on. Hope that makes sense.
Use callback of fadeOut() method (see complete parameter here) to perform class change when the animation is done. Otherwise the class will swap while the animation is still going.
There is no better way than using setInterval() if you want to do it automatically and continuously.
Here is working example:
$("document").ready(function () {
var bg = $("#bg");
setInterval(function() {
// We fadeOut() the image, and when animation completes we change the class and fadeIn() right after that.
bg.fadeOut(300, function() {
bg.toggleClass('bg1 bg2');
bg.fadeIn(300);
});
}, 1500);
});
#bg {
position:absolute;
width:100%;
height:70%;
background-size:cover;
background-position:center;
}
.bg1 {
background-image: url("https://www.w3schools.com/css/img_fjords.jpg");
}
.bg2 {
background-image: url("https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg" class="ShowBG bg1"></div>
Edit
Just noticed OP wants fading so I added a simple CSS transition and opacity properties to both classes and #bg.
Use toggleClass(). Not sure why you used display:none so I removed it. Also I added the dimensions to html and body so your div has something to relate it's percentage lengths with.
Demo
setInterval(function() {
$('#bg').toggleClass('bg1 bg2');
}, 3000);
html,
body {
height: 100%;
width: 100%
}
#bg {
position: absolute;
width: 100%;
height: 70%;
background-size: cover;
background-position: center;
opacity:1;
transition:all 1s;
}
.bg1 {
background-image: url("http://placehold.it/500x250/00f/eee?text=BG1");
opacity:1;
transition:all 1s;
}
.bg2 {
background-image: url("http://placehold.it/500x250/f00/fff?text=BG2");
opacity:1;
transition:all 1s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg" class="ShowBG bg1"></div>
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?
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>
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}
}
Hi there I need to an interactive element using a large image. This image sized 1000x1000 pixel with simple imagery will contain several questions with yes or no. What I want to do is place this image within a small div (say 500x300) with hidden overflow and add hotspots on the image for the yes/no option. What I want is when the user clicks yes, then the hotspot link pans to specific x/y coordinates of the same large image. Viewer will only see within the 500x300 window. So on and so forth. Is this possible? It seems so simple yet only option I can find is the pan by mouse option or iframe option with complicated divs and anchors. I'm not an expert in java/jquery but would love to find a script that is adaptable. Please help!
This sounded fun so I made a custom solution real quick. Demo here: jsBin
It's heavily reliant on the proper CSS, so check that in the bin, but here's the JS part:
var choice = document.querySelectorAll('.choice'),
image = document.getElementById('image')
for ( var i=0; i<choice.length; i++) {
choice[i].addEventListener('click', function (event) {
var x = this.dataset['x'],
y = this.dataset['y'];
image.style.top = '-'+y+'px';
image.style.left = '-'+x+'px';
})
}
Use css transitions for animation. Set up the positions you want the buttons to move the image around to in the image using a series of javascript objects. Then, set up your anchors, text, etc using absolute positioning on top of the image inside of a div container. Finally, add a click action in jQuery to assign your different positions to the top and left css of that container.
The end result, then, will be that you click an anchor, the left and top positions are assigned to the container via css in jQuery, and the transitions will slide the image around with the anchors.
I set up a fiddle here.
Here's the html from the fiddle:
<div id="window">
<div id="container">
<img src="http://upload.wikimedia.org/wikipedia/en/1/1f/Kill_The_Lights_1000x1000.jpg" id="image">
<ul>
<li><a id="city" href="#">City</a></li>
<li><a id="bottom" href="#">Bottom</a></li>
</ul>
</div>
</div>
And the CSS:
#window {
width:500px;
height:300px;
overflow:hidden;
position:relative;
}
#window a {
position: absolute;
z-index: 2;
display: block;
padding: 10px;
background: rgba(255,255,255,.5);
}
#city {
top: 20px;
left: 20px;
}
#bottom {
top: 220px;
left: 220px;
}
#container {
-webkit-transition:left 2s, top 2s, -webkit-transform 2s;
transition:left 2s, top 2s, transform 2s;
position: absolute;
z-index: 1;
top: 0px;
left: 0px;
}
Here's some javascript to give an example of setting up the positions as objects.
var city = {
top: -200,
left: -200
};
var bottom = {
top: -700,
left: -100
}
$('a').click(function() {
var t = this.id;
var c = $('#container');
if (typeof eval(t) !== 'undefined') {
c.css({
'top': eval(t).top,
'left': eval(t).left
});
}
});
I've just made a Fiddle with a demo image from where you could proceed.
HTML:
<div class="imgHolder">
<div class="hotspot one">Click</div>
<img src="image.jpg" />
</div>
CSS:
.imgHolder {
overflow:hidden;
width:300px;
height:300px;
position:relative;
}
.hotspot.one {
position:absolute;
top:10px;
padding:2px;
background-color:#fff;
left:10px;
}
.hotspot:hover {
cursor:pointer;
}
img {
position:relative;
z-index:-1;
}
jQuery:
$(".hotspot").on("click", function () {
$("img").animate({
"right": "+=100px"
});
});
For reference: http://api.jquery.com/animate/
You could e.g. fade hotspots in and out on specific positions and use animate() to move to the next hotspot.
I am trying to fade in a new background of a header when the user scrolls down. I would like it to fade in smoothly on top of the original background.
Instead what is happening, is that it is removing the original background and then fading in the new one. This makes the transition look ugly when the user scrolls down...
HTML
<div id="navbar" class="navbar">
</div>
CSS
#navbar {
transition: background 0.5s ease-in 0s;
}
.navbar {
background: url("images/nav-bg.png") repeat scroll 0 0 rgba(0, 0, 0, 0);
height: 75px;
margin: 0 auto;
max-width: 1600px;
width: 100%;
position: relative;
z-index: 1;
}
.navbar.fade-blue {
background:#566c75;
}
JS
jQuery(document).ready( function() {
jQuery(window).scroll(function() {
if ( jQuery(window).scrollTop() > 20) {
jQuery(".navbar").addClass("fade-blue");
}
else {
jQuery(".navbar").removeClass("fade-blue");
}
});
});
EDIT: I changed the .fade-blue class as I had two background rules there, I am attempting to fade a background image into a colour.
If you want to fadeIn/fadeOut your background imgae (A) with another one (B), you need to put both in a separate div, and apply to those the opacity transition.
If you need only to fadeOut your backgorund image, you can only put it on separate element inside parent container, and apply to that the opacity transition.
Here an example
How to fade in background image by CSS3 Animation
I'm new to javascript and jquery, so please forgive my ignorance. I created a webpage where you rollover a text link and an image in another div changes. I used the method from here: http://jsfiddle.net/fWpJz/1/ to create my page and it works well.
Here is the code I'm using:
$(document).ready(function () {
$('.productmenu a').hover(function () {
$('#prodimage img').attr('src', $(this).data('image-src'));
$('.image-src').stop().animate({.attr}, slow);
});
});
I'd like to slow down the transition from one image to another on mouse over, so that the image doesn't flip as abruptly.
I used this tutorial (http://bavotasan.com/2009/creating-a-jquery-mouseover-fade-effect/) to create an effect that I like, but don't know how to combine it with the image changes based on a link hover. Here is the code from the jsfiddle.net:
$(document).ready(function () {
$('.menu a').hover(function () {
$('#container img').attr('src', $(this).data('image-src'));
});
});
Can anyone point me to the correct piece of code and how I can add it into my javascript? I've never used jquery before, so I don't know how to add an animate function.
Thank you!!
What if I told you you didn't have to use jQuery.animate at all to achieve the effect you want? Use CSS3 transitions! Here's a forked version of your fiddle showing how to accomplish what you're looking to do (I think) (I've put the html/css/js at the bottom of this post as well).
When the DOM content has loaded, the alignItems function makes sure that all images stay in the same place on the page. The script keeps track of the current image being displayed. Every time a different link is moused over, the image being displayed gets updated, such that the old current image gets its opacity set to 0 and the new current image gets its opacity set to 1. Then CSS transitions can be used to animate the opacity, which blows away $.fn.animate, but will only work on modern browsers (see caniuse...motherf***ing IE -_- ). Code below:
html
<div class="menu">
link 1
link 2
link 3
link 4
link 5
</div>
<div id="container">
<img id="1" src="http://farm7.staticflickr.com/6092/6330704947_dd7e1b453c_t.jpg" />
<img id="2" src="http://farm1.staticflickr.com/13/15463218_8651d51b21_t.jpg"/>
<img id="3" src="http://farm3.staticflickr.com/2570/4220856234_029e5b8348_t.jpg" />
<img id="4" src="http://farm4.staticflickr.com/3036/2975303180_86c4858b2b_t.jpg" />
<img id="5" src="http://farm7.staticflickr.com/6216/6240217938_aeed84634a_t.jpg" />
</div>
css
.menu a {
padding: 2px 4px;
color: #555;
text-decoration: none;
}
.menu a:hover {
color: #ddd;
background: #333;
}
#container {
margin-top: 10px;
}
#container img {
margin: 4px;
padding: 4px;
border: 1px dashed #aaa;
opacity: 0;
-webkit-transition: opacity 500ms ease-in;
-moz-transition: opacity 500ms ease-in;
transition: opacity 500ms ease-in;
}
javascript
$(document).ready(function () {
alignImages();
var currentImgId = 0;
$('.menu a').hover(function () {
var oldImgId = currentImgId;
currentImgId = this.dataset.imageId;
$(document.getElementById(oldImgId)).css('opacity', 0);
$(document.getElementById(currentImgId)).css('opacity', 1.0);
});
});
function alignImages() {
var $images = $('#container img');
var position = $images.eq(0).position();
$images.each(function() {
this.style.position = 'absolute';
this.left = position.left;
this.top = position.top;
});
}
Below is one of the implementations by using setTimeout
var count = 0;
$(document).ready(function () {
$('.menu a').hover(function () {
var self = this;
var innerCount = ++count;
setTimeout(function(){
if(innerCount == count) //If mouse move out within 1 second, will not show new image
{
$('#container img').attr('src', $(self).data('image-src'));
}
}, 1000); //1 second delay
});
});
Try this:
your HTML should be like this:
<div id="container" style="display:none;">
<img src="">
</div>
and in your script :
$('.menu a').hover(function () {
$('#container').hide();
$('#container').fadeIn().animate({ opacity: 1, top: "-10px" }, 'slow');
$('#container img').attr('src', $(this).data('image-src'));
});
Effect should be nice in transition See: JSFiddle