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>
Related
When I'm linking Bootstrap 5 its just fading out the text instead of fading in.
When I remove the link everything just work fine.
const animatedText = document.querySelector(".fancy");
const strText = animatedText.textContent;
const splitText = strText.split("");
animatedText.textContent = "";
for (let i = 0; i < splitText.length; i++) {
animatedText.innerHTML += "<animated>" + splitText[i] + "</animated>";
}
let char = 0;
let timer = setInterval(onTick, 50);
function onTick() {
const animated = animatedText.querySelectorAll('animated')[char];
animated.classList.add('fade');
char++
if (char === splitText.length) {
complete();
return;
}
}
function complete() {
clearInterval(timer);
timer = null;
}
animated {
opacity: 0;
transition: all 0.4s ease;
}
animated.fade {
opacity: 1;
}
<h2 class="fancy">WELCOME TO MY WORLD</h2>
Bootstrap have .fade class in CSS which is responsible for "fade out" alert boxes.
Change your "fade" class to "text-fade" or something else and everything will be okay.
I'm trying to create a number of divs and iterate through them on click.
The iteration only works on every other click.
Strangely, I'm getting no errors.
I tried moving the divs variable declaration outside of the for loop.
for (let i = 0; i <= 5; i++) {
let div = document.body.insertAdjacentHTML('beforeend', `<div class="div">${i}</div>`)
let divs = document.getElementsByClassName('div');
divs[i].style.backgroundColor = randomColor();
divs[i].onclick = () => {
close(divs[i])
open(divs[i + 1])
}
}
function randomColor() {
let e = Math.floor(Math.random() * 16777215).toString(16);
return `#${e}`;
}
function close(t) {
t.style.transform = 'scale(0.5)'
t.style.opacity = '0'
setTimeout(function() {
t.style.display = 'none'
}, 500)
}
function open(t) {
t.style.display = 'block'
setTimeout(function() {
t.style.transform = 'scale(1)'
t.style.opacity = '1'
}, 5)
}
div {
height: 100%;
width: 100%;
position: fixed;
top: 0;
bottom: 0;
right: 0;
transition: 0.5s;
opacity: 0;
transform: scale(0.5);
}
you need to
open(divs[(i + 1) % 6]) so it loop correctly
hide all divs at initial (except one)
there still some minor issue with the initial state (need to add opacity and transform, I leave it for simplicity), I think you should use proper class instead of inline css to make it easier.
for (let i = 0; i <= 5; i++) {
let div = document.body.insertAdjacentHTML('beforeend',
`<div class="div" style="display:${i==0?'block':'none'}">${i}</div>`
)
}
let divs = document.getElementsByClassName('div');
for (let i = 0; i <= 5; i++) {
divs[i].style.backgroundColor = randomColor();
divs[i].onclick = () => {
close(divs[i])
open(divs[(i + 1) % 6])
}
}
function randomColor() {
let e = Math.floor(Math.random() * 16777215).toString(16);
return `#${e}`;
}
function close(t) {
t.style.transform = 'scale(0.5)'
t.style.opacity = '0'
setTimeout(function() {
t.style.display = 'none'
}, 500)
}
function open(t) {
t.style.display = 'block'
setTimeout(function() {
t.style.transform = 'scale(1)'
t.style.opacity = '1'
}, 5)
}
div {
height: 100%;
width: 100%;
position: fixed;
top: 0;
bottom: 0;
right: 0;
transition: 0.5s;
opacity: 0;
transform: scale(0.5);
}
I'm working on canvas here I want to use same canvas multiple times on the same page I tried using the class name getElementsByClassName and using query selector also. but it's not working. Can anyone point me in the right direction what might be the issue here how can I achieve? in both boxes box1, box2 I want to add same canvas.
const noise = () => {
let canvas, ctx;
let wWidth, wHeight;
let noiseData = [];
let frame = 0;
let loopTimeout;
// Create Noise
const createNoise = () => {
const idata = ctx.createImageData(wWidth, wHeight);
const buffer32 = new Uint32Array(idata.data.buffer);
const len = buffer32.length;
for (let i = 0; i < len; i++) {
if (Math.random() < 0.5) {
buffer32[i] = 0xff000000;
}
}
noiseData.push(idata);
};
// Play Noise
const paintNoise = () => {
if (frame === 9) {
frame = 0;
} else {
frame++;
}
ctx.putImageData(noiseData[frame], 0, 0);
};
// Loop
const loop = () => {
paintNoise(frame);
loopTimeout = window.setTimeout(() => {
window.requestAnimationFrame(loop);
}, (1000 / 25));
};
// Setup
const setup = () => {
wWidth = window.innerWidth;
wHeight = window.innerHeight;
canvas.width = wWidth;
canvas.height = wHeight;
for (let i = 0; i < 10; i++) {
createNoise();
}
loop();
};
// Reset
let resizeThrottle;
const reset = () => {
window.addEventListener('resize', () => {
window.clearTimeout(resizeThrottle);
resizeThrottle = window.setTimeout(() => {
window.clearTimeout(loopTimeout);
setup();
}, 200);
}, false);
};
// Init
const init = (() => {
canvas = document.getElementById('noise');
//canvas = document.getElementsByClassName('noise');
ctx = canvas.getContext('2d');
setup();
})();
};
noise();
.noise {
z-index: 100;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: .5;
}
.box1, .box2 {
position: relative;
width: 300px;
height: 300px;
margin: 20px;
background: #eee;
}
<div class="box1">
<canvas id="noise" class="noise"></canvas>
</div>
<div class="box2">
<canvas id="noise" class="noise"></canvas>
</div>
Use getElementsByClassName. You will get an array then. For instance for class box:
canvas = document.getElementsByClassName("box");
for (i = 0; i < canvas.length; i++) { //...do smth here...// }
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>
On the background, I have four different images and I want those img dynamically change for example every two seconds. I manage to change one img, but how do I change all images at once?
Here is my code:
const im1 = document.getElementById("img-1");
const images = ["images/photo1.png","images/photo2.png","images/photo3.png", "images/photo4.png"];
let index = 0;
function changeImage()
{
im1.setAttribute("src", images[index]);
index++;
if(index >= images.length)
{
index=0;
}
}
setInterval(changeImage, 2000);
I know that I could do something like this: document.getElementbyTagName("img'), but what I should do next?
https://jsfiddle.net/ofqkmwsh/
You need only one img
const img = document.getElementById("img");
const images = [
"//placehold.it/100x100/0bf?text=1",
"//placehold.it/100x100/f0b?text=2",
"//placehold.it/100x100/fb0?text=3",
"//placehold.it/100x100/b0f?text=4",
];
let index = 0;
function changeImage() {
index = ++index % images.length; // Incr. and reset index to 0 if exceeds
img.setAttribute("src", images[index]); // set src attribute
}
setInterval(changeImage, 2000);
<img id="img" src="//placehold.it/100x100/0bf?text=1">
You could also exploit Chrome's ability to transition a background-image:
const img = document.getElementById("img");
const images = [
"//placehold.it/800x600/0bf?text=1",
"//placehold.it/800x600/f0b?text=2",
"//placehold.it/800x600/fb0?text=3",
"//placehold.it/800x600/b0f?text=4",
];
const n = images.length;
let c = 0;
images.forEach(src => new Image().src = src); // Preload images
const changeImage = () => img.style.backgroundImage = "url('"+ images[c++ % n] +"')";
changeImage(); // Init!
setInterval(changeImage, 2000);
#img {
height: 50vh;
background: red none 50% 50% / cover no-repeat;
transition: 0.8s;
}
<div id="img"></div>
If you have multiple galleries you could do something like:
const Gallery = (id, time) => {
const gal = document.getElementById(id);
const images = gal.getAttribute("data-images").split(",").map(img => img.trim());
const n = images.length;
let c = 0;
images.forEach(src => new Image().src = src); // Preload images
const changeImage = () => gal.style.backgroundImage = `url(${images[c++ % n]})`;
changeImage(); // Init!
setInterval(changeImage, time);
};
Gallery("Gallery-1", 2000);
Gallery("Gallery-2", 3000);
.Gallery {
float: left;
width: 25%;
height: 100px;
background: transparent none 50% 50% / cover no-repeat;
transition: 0.8s;
}
<div class="Gallery" id="Gallery-1" data-images="
//placehold.it/800x600/0bf?text=1,
//placehold.it/800x600/f0b?text=2,
//placehold.it/800x600/fb0?text=3,
//placehold.it/800x600/b0f?text=4
"></div>
<div class="Gallery" id="Gallery-2" data-images="
//placehold.it/800x600/83a?text=1,
//placehold.it/800x600/a38?text=2,
//placehold.it/800x600/3a8?text=3,
//placehold.it/800x600/38a?text=4
"></div>