Show image using setTimeout and for loop in array

Viewed 775
images: [
    {
        img: 'car_0.png',
        time: 3000,
    },
    {
        img: 'car_1.png',
        time: 500,
    },
    {
        img: 'car_2.png',
        time: 500,
    },
    {
        img: 'car_3.png',
        time: 1000,
    },
],

I need display image in my page. time is the time when the image should be displayed on the page. For example:

The first photo car_0.png is displayed on the page for 3 seconds. After 3 seconds it changes to the second image, which is displayed for 0.5 seconds...

I have writen this method but not working:

if(images !== undefined) {
    for(let i = 0; i < images.length; i++) {
        setTimeout(() => {
            this.images = images[i].img
        }, images[i].time + images[i + 1].time)
    }
}

EDIT:

I change my method to:

if(images !== undefined) {
    let time
    for(let i = 0; i < images.length; i++) {
        if(i > 0) {
            time = time + images[i].time
        }
        else {
            time = images[i].time
        }
        console.log(time)
        setTimeout(() => {
            this.images = images[i].img
        }, time)
    }
}

Now in console.log(time) I have value:

3000
3500
4000
5000

But still not working correctly, the first picture should appear immediately and be displayed for 3 seconds. Now appears after 3 seconds

4 Answers

Add img element in html and change its src attribute using javascript.

To show images in order, you could use a generator function.

  1. Create a generator function that yields an image object after specific amount of time.

  2. Create another function that calls this generator function to get the image object, gets the value of the img property from the returned image object and sets it as value of src attribute on the img element.

    This function also creates a timeout which expires after the time equal to the time property of the current image object. When timeout expires, this function calls itself again to get the next image from the generator function and displays that image.

    These steps are repeated until there are no more images to display.

const images = [
    { img: 'https://picsum.photos/id/0/100', time: 3000 },
    { img: 'https://picsum.photos/id/1/100', time: 500 },
    { img: 'https://picsum.photos/id/10/100', time: 500 },
    { img: 'https://picsum.photos/id/100/100', time: 1000 }
];

const img = document.querySelector('img');

function* getImage() {
  for (let image of images) {
    yield image;
  }
}

const imageGenerator = getImage();

function showNextImage() {
  const image = imageGenerator.next().value;

  if (!image) return;
  
  img.src = image.img;
  
  setTimeout(showNextImage, image.time);
};

showNextImage();
<img src=""/>

Alternatively, Instead of using a generator function to get an image object, you could just use a variable that keeps track of the index of the image that is currently displayed and each image object accessed using this index variable.

const images = [
    { img: 'https://picsum.photos/id/0/100', time: 3000 },
    { img: 'https://picsum.photos/id/1/100', time: 500 },
    { img: 'https://picsum.photos/id/10/100', time: 500 },
    { img: 'https://picsum.photos/id/100/100', time: 1000 }
];

const img = document.querySelector('img');
let index = 0;

function showNextImage() {
  const image = images[index++];

  if (!image) return;
  
  img.src = image.img;
  setTimeout(showNextImage, image.time);
};

showNextImage();
<img src=""/>

Please see below code, it works for me:

var images = [
        {
            img: 'car_0.png',
            time: 3000,
        },
        {
            img: 'car_1.png',
            time: 500,
        },
        {
            img: 'car_2.png',
            time: 500,
        },
        {
            img: 'car_3.png',
            time: 1000,
        },
    ]
    var currentImage = 0;
    function showImages(){
        
        let img = images[currentImage];
        console.log(img.img);
        setTimeout(function () {
            currentImage++;
            if(currentImage<images.length){
              showImages();
            }
        }, img.time);
    };
    showImages();

First:
change first line's : to =,
replace last , with ;,
and remove , from after the last object in the array.

Second, try this code:

function displayImage(images, i=0) {
  if(images.length==0) return;
  console.log(images[i].img); // replace with whatever you want to do
  i++;
  if(i==images.length) i=0;
  setTimeout(displayImage,images[i].time,images,i);
}

call with:

displayImage(images);

or:

displayImage(images, 2); // if you want to start with the 3rd

do something like this using a promise function:

const images = [{
    img: 'https://picsum.photos/id/0/100',
    time: 3000,
  },
  {
    img: 'https://picsum.photos/id/10/100',
    time: 500,
  },
  {
    img: 'https://picsum.photos/id/100/100',
    time: 500,
  },
  {
    img: 'https://picsum.photos/id/1000/100',
    time: 1000,
  },
];

const waitNext = ({
  time
}) => {
  return new Promise(function(resolve) {
    setTimeout(resolve, time);
  });
}



async function displayImages(images) {
  for (const image of images) {
    document.getElementById('img').src = image.img;
    await waitNext(image);
  }
}

displayImages(images)
<img id="img" src="" />

Related