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>
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>
The initial project had an array with file names stored in there and the image slider would display them.
I am trying to create the upload functionality where the user can upload an image and that image would then be pushed to the array.
I've tried utilizing the URL.createObjectURL method on the uploaded file and pushing it to the display but there's an error when the slide arrives at the array index.
The file comes out as 'blob:http etc...' and so i've tried removing 'blob' from the string and still receiving an error.
HTML:
<div id="container">
<button class="button" id="leftButton"><i class="fa fa-arrow-left"></i></button>
<button class="button" id="rightButton"><i class="fa fa-arrow-right"></i></button>
</div>
<div class="upload">
<p><input type='file' name='image' id="input"></p>
</div>
CSS:
#container {
margin: 100px auto;
height: 500px;
width: 900px;
border: 7px solid #3e92cc;
border-radius: 10px;
background: url('images/one.jpg');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
Javascript:
let container = document.getElementById("container");
let rightButton = document.getElementById("rightButton");
let leftButton = document.getElementById("leftButton");
let images = ["one.jpg", "two.jpg", "three.jpg", "four.jpg", "five.jpg"];
let imagesIndex = 0;
const inputElement = document.getElementById("input");
let newURL;
//Add background to slider
function addBackground() {
if (!images[imagesIndex].includes('http')) {
container.style.background = `url('images/${images[imagesIndex]}')`;
} else {
container.style.background = `url('${images[imageIndex]}')`;
}
container.style.backgroundPosition = "center";
container.style.backgroundRepeat = "no-repeat";
container.style.backgroundSize = "cover";
}
// upload files
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
const objectURL = window.URL.createObjectURL(fileList[0]);
//remove 'blob:';
newURL = objectURL.replace('blob:', '');
console.log(newURL);
images.push(newURL);
}
// Event listeners
inputElement.addEventListener("change", handleFiles, false);
rightButton.addEventListener("click", function () {
imagesIndex++;
if (imagesIndex >= images.length) {
imagesIndex = 0;
}
console.log(imagesIndex);
addBackground();
})
leftButton.addEventListener("click", function () {
imagesIndex--;
if (imagesIndex < 0) {
imagesIndex = images.length - 1;
}
console.log(imagesIndex);
addBackground();
})
Don't remove blob: it's required in the URL scheme
// upload files
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
const objectURL = window.URL.createObjectURL(fileList[0]);
//remove 'blob:';
//newURL = objectURL.replace('blob:', '');
console.log(objectURL);
images.push(objectURL);
}
Corrected typo in imagesIndex
//Add background to slider
function addBackground() {
if (!images[imagesIndex].includes('http')) {
container.style.background = `url('images/${images[imagesIndex]}')`;
} else {
container.style.background = `url('${images[imagesIndex]}')`;
}
//.. other code
}
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>
<html>
<section>
<style>
img{
width: 150px;
height:150px;
float:left;
}
</style>
</section>
<script>
var img = undefined,
section = document.querySelector('section'),
images=[
"http://www.psdgraphics.com/file/red-number-0.jpg",
"http://www.psdgraphics.com/file/red-number-1.jpg",
"http://www.psdgraphics.com/file/red-number-2.jpg",
"http://www.psdgraphics.com/file/red-number-3.jpg",
"http://www.psdgraphics.com/file/red-number-4.jpg",
"http://www.psdgraphics.com/file/red-number-5.jpg",
"http://www.psdgraphics.com/file/red-number-6.jpg"
];
function loadImage( i ){
img = document.createElement('img');
section.appendChild(img);
img.dataset['index'] = i;
img.src=images[i];
}
for(var i=0;i<images.length;i++){
loadImage(i)
}
</script>
</html>
This is my code, at the moment I receive all the images at the same time...
I would like to load each image only when the previous one has been load..
Any help will be gratitude
Simply assign a pseudorecursive callback to the onload handler:
function loadImage( i ){
if(i >= images.length) return;
var img = document.createElement('img');
section.appendChild(img);
img.dataset['index'] = i;
img.src=images[i];
img.onload = () => loadImage(i+1);
}
loadImage(0);
Or use some new ES 7 stuff:
(async function(){
for(var i = 0; i < images.length; i++){
var img = document.createElement('img');
section.appendChild(img);
img.dataset['index'] = i;
img.src=images[i];
await new Promise(r => image.onload = r );
}
})()
Probably some setTimeout along with recursion can give a nice effect:
var img = undefined,
section = document.querySelector('section'),
images = [
"http://www.psdgraphics.com/file/red-number-0.jpg",
"http://www.psdgraphics.com/file/red-number-1.jpg",
"http://www.psdgraphics.com/file/red-number-2.jpg",
"http://www.psdgraphics.com/file/red-number-3.jpg",
"http://www.psdgraphics.com/file/red-number-4.jpg",
"http://www.psdgraphics.com/file/red-number-5.jpg",
"http://www.psdgraphics.com/file/red-number-6.jpg"
];
function loadImage(i) {
img = document.createElement('img');
section.appendChild(img);
img.dataset['index'] = i;
img.src = images[i];
}
var index = 0;
function loadNext() {
if(index < images.length) {
loadImage(index);
setTimeout(function(idx){
loadNext();
},200, index++);
}
}
loadNext();
img {
width: 150px;
height: 150px;
float: left;
}
<html>
<section>
</section>
</html>