I have three images which my two div's switch between. However, the animation appears too rough. How do I apply a fade right before the switch?
<div class="my-images">
<div id="image-1"></div>
<div id="image-2"></div>
</div>
<script>
function displayNextImage() {
x = (x === images.length - 1) ? 0 : x + 1;
document.getElementById("image-1").style.backgroundImage = images[x];
document.getElementById("image-2").style.backgroundImage = images[x];
}
function startTimer() {
setInterval(displayNextImage, 10000);
}
var images = [],
x = 0;
images[0] = "url('images/snow.jpeg')";
images[1] = "url('images/nike.jpeg')";
images[2] = "url('images/motor.jpeg')";
</script>
This loops continuously so I do not want it just fading in on the first load.
Without JQuery you'll have cross-browser compatibility issue.
So i suggest you to use JQuery to achieve this.
<div class="my-images">
<div class="my-image" id="image-1"></div>
<div class="my-image" id="image-2"></div>
</div>
<script>
function displayNextImage() {
$("#image-" + x).css('backgroundImage', images[x]).show('slow');
x++;
}
var images = [],
x = 0;
images[0] = "url('images/snow.jpeg')";
images[1] = "url('images/nike.jpeg')";
images[2] = "url('images/motor.jpeg')";
</script>
And you have to add this to css:
.my-image{
display:none;
}
In case you not use display: block to you element:
Your CSS will be:
.my-image{
display:whatYouWant;
}
Then need add the document ready() function and change show() to fadeIn():
$(document).ready(function(){
$(".my-image").hide();
});
function displayNextImage() {
$("#image-" + x).css('backgroundImage', images[x]).fadeIn('slow');
x++;
}
This will work because fadeIn() set to display the previous value.
If you want div visible before image adding, remove $(document).ready() call and edit displayNextImage():
function displayNextImage() {
$("#image-" + x).hide().css('backgroundImage', images[x]).fadeIn('slow');
x++;
}
You can do it with CSS animation, for each cycle:
1) swap the image sources like you are already doing
2) reset the fade in animation, more info here
3) increment your index
const imgs = [
'https://source.unsplash.com/iMdsjoiftZo/100x100',
'https://source.unsplash.com/ifhgv-c6QiY/100x100',
'https://source.unsplash.com/w5e288LU8SU/100x100'
];
let index = 0;
const oldImage1 = document.getElementById('oldImage1');
const newImage1 = document.getElementById('newImage1');
const oldImage2 = document.getElementById('oldImage2');
const newImage2 = document.getElementById('newImage2');
window.setInterval(() => {
// put new image in old image
oldImage1.src = newImage1.src;
oldImage2.src = newImage2.src;
// Set new image
newImage1.src = imgs[index];
newImage2.src = imgs[index];
// reset animation
newImage1.style.animation = 'none';
newImage1.offsetHeight; /* trigger reflow */
newImage1.style.animation = null;
newImage2.style.animation = 'none';
newImage2.offsetHeight; /* trigger reflow */
newImage2.style.animation = null;
// increment x
index = index + 1 >= imgs.length ? 0 : index + 1;
}, 1500);
.parent {
position: relative;
top: 0;
left: 0;
float: left;
}
.oldImage1 {
position: relative;
top: 0;
left: 0;
}
.newImage1 {
position: absolute;
top: 0;
left: 0;
}
.oldImage2 {
position: relative;
top: 0;
left: 100;
}
.newImage2 {
position: absolute;
top: 0;
left: 100;
}
.fade-in {
animation: fadein 1s;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
<div class="parent">
<img id="oldImage1" class="oldImage1" src="https://source.unsplash.com/ifhgv-c6QiY/100x100" />
<img id="newImage1" class="newImage1 fade-in" src="https://source.unsplash.com/w5e288LU8SU/100x100" />
</div>
<div class="parent">
<img id="oldImage2" class="oldImage2" src="https://source.unsplash.com/ifhgv-c6QiY/100x100" />
<img id="newImage2" class="newImage2 fade-in" src="https://source.unsplash.com/w5e288LU8SU/100x100" />
</div>
Related
The pictures change themselves every 3 seconds.
I would like to add simple animation to the photo during the change.
Preferably in vaniilla js.
let index = 1;
const changeImg = () => {
index++;
img.setAttribute('src', `img/img${index}.png`);
if (index === 3) {
index = 0;
}
};
setInterval(changeImg, 3000);
If you use something like animate.css, or create your own animation class you could do it like this:
(Im assuming you're getting the image by a query selector/getElementById)
let index = 1;
const changeImg = () => {
index++;
img.classList.add('animate__animated');
img.classList.add('animate__bounce');
setTimeout(() => {
img.setAttribute('src', `img/img${index}.png`);
img.classList.remove('animate__animated');
img.classList.remove('animate__bounce');
}, 300); // This delay is assuming the animation duration is 300ms, you need to change this to the length of the animation
if (index === 3) {
index = 0;
}
};
setInterval(changeImg, 3000);
As you suggested an example in vanilla JavaScript (no libraries), here you go.
(function slideShow() {
let imgs = [
"https://picsum.photos/id/237/200/300",
"https://picsum.photos/id/238/200/300",
"https://picsum.photos/id/239/200/300"
];
let index = 0;
const frontImg = document.getElementById("slideshow__img--front");
const backImg = document.getElementById("slideshow__img--back");
frontImg.src = imgs[index];
const changeSlideShowImg = () => {
const currImgSrc = imgs[index];
index++;
if (index >= imgs.length) index = 0;
const newImgSrc = imgs[index];
backImg.src = newImgSrc;
frontImg.classList.add("slideshow__img--fadeout");
setTimeout(() => {
frontImg.src = newImgSrc;
frontImg.classList.remove("slideshow__img--fadeout");
}, 500);
};
setInterval(changeSlideShowImg, 3000);
})()
.slideshow {
width: 200px;
height: 300px;
position: relative;
}
.slideshow__img {
position: absolute;
left: 0;
top: 0;
opacity: 1;
}
#slideshow__img--front {
z-index: 2;
}
.slideshow__img.slideshow__img--fadeout {
transition: opacity 0.5s ease-in;
opacity: 0;
}
<div class="slideshow">
<img id="slideshow__img--front" class="slideshow__img" />
<img id="slideshow__img--back" class="slideshow__img" />
</div>
I have a series of images I want to transition from 0 opacity to 1 opacity when they come into the view port. I have the viewport check part done and the adding classes, however I would like them to be on an interval, so once the first 3 images come into the view port they appear 1, 2, 3 every .5seconds or so. Instead of all 3 at the same time.
here's a JS fiddle of how it works currently
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
reveal[i].classList.add("fade");
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
https://jsfiddle.net/u04sy7jb/
I've modified your code to add a transition-delay of an additional .5 seconds for each element after the first one, in each "group" that is revealed as you scroll. I left comments in the JavaScript so you can understand the changes.
Let me know if you have any questions!
Live demo:
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
// start a new count each time user scrolls
count = 0;
for (var i = 0; i < reveal.length; i++) {
// also check here if the element has already been faded in
if (checkVisible(reveal[i]) && !reveal[i].classList.contains("fade")) {
// add .5 seconds to the transition for each
// additional element currently being revealed
reveal[i].style.transitionDelay = count * 500 + "ms";
reveal[i].classList.add("fade");
// increment count
count++;
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
.container {
width: 100%;
height: 1200px;
background-color: orange;
}
.reveal {
display: inline-block;
width: 32%;
margin: 0 auto;
height: 400px;
background-color: pink;
border: 1px solid black;
opacity: 0;
}
.fade {
opacity: 1;
transition: 1s;
}
<div class="container">
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
</div>
You could be able to stick your reveal[i].classList.add("fade"); inside of a setTimeout that executes as a function of your ith element so they show up how you're describing. Here is an example of adding short function to add the class and using it in a setTimeout to make this happen, although you could change it up to meet any additional needs.
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
addMyFadeClass(reveal[i], i)
}
}
}
};
function addMyFadeClass(element, i) {
setTimeout(function() {
element.classList.add("fade");
}, i * 500)
}
You can also use :nth-child CSS selectors without the need to change the JS:
.reveal:nth-child(3n+1).fade {
opacity: 1;
transition: 1s;
}
.reveal:nth-child(3n+2).fade {
opacity: 1;
transition: 1.5s;
}
.reveal:nth-child(3n).fade {
opacity: 1;
transition: 2s;
}
JSFiddle: https://jsfiddle.net/u04sy7jb/8/
I have the following hacked code to fadein text and fadeout an image on hover. I want to repeat this affect on a second image/div but I can't get it to work. i tried copying all the scripting and changing the variable names (i.e. img2 instead of img1 etc.) and I tried adding multiple handlers to the existing code but it doesn't work. Only one image will fade while the other one does not. Please help. If it is not abdunantly clear, I am a Jquery wannabe who has some HTMl skills and a rudimentary understanding of programming. Thanks
<style type="text/css">
#imgContainer {
position: relative;
}
#img1 {
opacity: 100;
filter:alpha(opacity=100);
position: relative;
top: 0px;
left: 0px;
}
#imgContainer div {
position: absolute;
top: 20px;
left: 60px;`enter code here`
}
</style>
<script type="text/javascript">
var speed = 0.8;
var fadeTimerImg, fadeTimerTxt;
function fade(obj,dir){
if(fadeTimerImg){clearInterval(fadeTimerImg);}
if(fadeTimerTxt){clearInterval(fadeTimerTxt);}
fadeTimerImg = setInterval(function(){setOpacity(obj,dir)},100);
fadeTimerTxt = setInterval(function(){setOpacity(oTxtContainer,-dir)},100);
}
function setOpacity(obj,dir) {
obj.curOpac = obj.curOpac + (speed * dir);
if(obj.curOpac < 0){obj.curOpac = 0;}
if(obj.curOpac > 10){obj.curOpac = 10;}
if(typeof(obj.style.opacity) == 'string'){
obj.style.opacity = obj.curOpac/10;
} else {
obj.style.filter = 'alpha(opacity=' + obj.curOpac*10 + ')';
}
}
window.onload=function(){
var oImg1 = document.getElementById('img1');
oImg1.curOpac = 10; //10 = opaque
oTxtContainer = document.getElementById('txtContainer');
oTxtContainer.curOpac = 0; //0 = transparent
oImg1.onmouseover = function(){fade(this,-1);}
oImg1.onmouseout = function(){fade(this,1);}
}
</script>
<div id="imgContainer">
<div id="txtContainer">
s`enter code here`ome text<br />
more text <br />
some more text
</div>
<img id="img1" src="FRY751_A.jpg">
</div>
Add the same class to each image, and do this, for example:
window.onload=function(){
var $images = $('.my-image-class');
$images.each(function() {
$(this).curOpac = 10; //10 = opaque
$(this).onmouseover = function(){fade(this,-1);}
$(this).onmouseout = function(){fade(this,1);}
});
}
I'm using the following code to run a slider. The function runs well.
How do I make a simple fadein effect with js. No jQuery.
Also setInterval waits 5 seconds before displaying the first image. How do I start with an image and then continue with the 5 second interval?
var i = 0;
var hello = function(){
if(i<image.length)
{document.getElementById('fullscreenImage').src = image[i];
i+=1;
}
else i = 0;
}
setInterval(hello,5000);
#fullscreenImage {
z-index: -999;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-size: cover;
}
<img id="fullscreenImage"></img>
You can do this by progressively adjusting the opacity style property of an image. Here's a simple example: declare some HTML structure, then wire the sliding behavior, using the makeSlider() function, passing an array containing the target images, as well as fading parameters.
HTML file example (whatever.html) :
<head>
<style type="text/css">
img {
position: absolute;
top: 0;
left: 0;
width: 300px;
visibility: hidden;
}
img:first-child {
visibility: visible;
}
</style>
<script type="text/javascript" src="slider.js"></script>
</head>
<body>
<img src="1.jpg" alt="Alt 1" />
<img src="2.jpg" alt="Alt 2" />
<script type="text/javascript">
var fadeInterval = 3000;
var fadeStep = 20;
setTimeout(function() {
makeSlider([document.images[0], document.images[1]], fadeInterval, fadeStep);
}, fadeInterval);
</script>
</body>
Javascript file (slider.js):
function makeSlider(pictures, fadeInterval, fadeStep) {
var currentIndex = 0;
function show() {
var nextIndex = (currentIndex + 1) % pictures.length;
var current = pictures[currentIndex];
var next = pictures[nextIndex];
fade(current, 1, -0.1, function() {
current.style.visibility = "hidden";
next.style.visibility = "visible";
fade(next, 0, +0.1, function() {
currentIndex = nextIndex;
setTimeout(function() { show(); }, fadeInterval);
});
});
}
function fade(element, origin, step, continuation) {
element.style.opacity = origin;
setTimeout(function () {
var nextOrigin = Math.round((origin + step) * 10) / 10;
if (nextOrigin >= 0 && nextOrigin <= 1) {
fade(element, nextOrigin, step, continuation);
} else {
continuation();
}
}, fadeStep);
}
show();
}
HTH.
http://jsfiddle.net/MAaVV/
Above is the JSFiddle for my code. It's some CSS to make an image full screen, and then a simple src change for the image. I want to change image backgrounds every 5 seconds. It's below as well:
<STYLE type=text/css>
#bg {
position: fixed;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
}
#bg img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
min-width: 50%;
min-height: 50%;
}
</style>
<script type="text/javascript">
for(var x = 0; x < 2; x++)
{
setTimeout(function()
{
var imgs = ["http://www.hdwallpapers.in/walls/aprilia_rsv4_motorcycles-wide.jpg","http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg","clf.jpg"];
document.getElementById("img").src = imgs[x];
},5000);
}
</script>
<div id="bg">
<img id="img" src="http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg?w=919&h=613" alt="" />
</div>
Anyone know why it isn't working?
Bonus points for building in a redirect (to another website) after the last image of the slideshow is shown for 5 seconds.
Try this:
var imgs = ["http://www.hdwallpapers.in/walls/aprilia_rsv4_motorcycles-wide.jpg", "http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg"];
var i=0;
setInterval(function () {
document.getElementById("img").src = imgs[i];
if(i==1)
{
//alert('test');
$("#img").click(function(){
alert('on');
location.href='http://www.google.com';
});
}
if(i++>=1) i=0;
}, 5000);
Fiddle: http://jsfiddle.net/MAaVV/6/
Your code fails for two reasons:
You set all three (or two in th case of the jsFiddle) timeouts to run at the same time. Your code sets all three to run 5 seconds after the call, but all the calls are made at the same time, so they'll all run 5 seconds later.
You use the x variable in your timeout function, but it is not defined in the scope for that function. So, in all cases, the image is getting 'undefined' as the src.
To fix this, I'd use something like this:
<script type="text/javascript">
var imageIndex = 0;
var imgs = ["http://www.hdwallpapers.in/walls/aprilia_rsv4_motorcycles-wide.jpg","http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg","clf.jpg"];
setInterval(function(){
document.getElementById("img").src = imgs[imageIndex++];
if(imageIndex >= imgs.length) imageIndex = 0;
},5000);
</script>
http://jsfiddle.net/MAaVV/5/
EDIT: To make the function do something after all the slides have shown, you might try something like this:
<script type="text/javascript">
var imageIndex = 0;
var imgs = ["http://www.hdwallpapers.in/walls/aprilia_rsv4_motorcycles-wide.jpg","http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg","clf.jpg"];
var interval = setInterval(function(){
document.getElementById("img").src = imgs[imageIndex++];
if(imageIndex >= imgs.length){
clearInterval(interval);
setTimeout(function(){
// do whatever you want here, after a 5 second pause
},5000);
},5000);
</script>
var imgs = ["http://www.hdwallpapers.in/walls/aprilia_rsv4_motorcycles-wide.jpg", "http://chivethethrottle.files.wordpress.com/2012/12/user-girl-motorcycle-920-3.jpg"];
var currentImage = 1;
$(document).ready(function(){
setInterval(function(){
if (currentImage >= imgs.length)
{
currentImage = 0;
window.location.href = 'http://www.google.com';
}
else
{
currentImage++;
}
$("#bg #img").attr("src", imgs[currentImage]);
}, 5000);
});
http://jsfiddle.net/MAaVV/2/