0

My component loads 2 images and then animates opacity between them to fade into the next image. This is all mediated by a setInterval that changes the index for the images every second.

The issue is that just after the first image transitions into the second, the first image briefly shows again. This only happens on the first index. I have tried this on both Chrome and Firefox and the issue is consistent across both.

Here is my code

import { useEffect } from "react";
import { useState } from "react";
import utils from "../hooks/utils";


const ImageSlider = ({ images, speed = 1000 }) => {
  const [current, setCurrent] = useState(0);

  const styles = {
    slider: {
      position: "relative",
      height: "100vh",
      display: "flex",
    },
    image: {
      width: "100vw",
      objectFit: "cover",
      animationName: "out",
      animationTimingFunction: "ease-in-out",
      animationDuration: `${speed}ms`,
      zIndex: "2",
    },
    image2: {
      width: "100vw",
      objectFit: "cover",
      marginLeft: "-100vw",
      zIndex: "1",
    },
  };

  useEffect(() => {
    const timer = setInterval(() => {
      //please remember this in the future
      setCurrent((current + 1) % images.length);
    }, speed);

    return () => clearInterval(timer);
  });

  if (!Array.isArray(images) || images.length == 0) {
    return null;
  }

  return (
    <>
      <div style={styles.slider}>
        {utils.urlArray(images, "", 1000).map((image, index, array) => (
          <>
            {index === current && (
              <>
                <img
                  style={styles.image}
                  src={image}
                  key={`${index}_${current}_0`}
                />
                <img
                  style={styles.image2}
                  src={array[(index + 1) % array.length]}
                  key={`${index}_${current}_1`}
                />
              </>
            )}
          </>
        ))}
      </div>
    </>
  );
};

export default ImageSlider;

This is the first time I have built a component like this so I can't seem to think what I am doing wrong.

Thanks

  • Why do you use `map` to just display 2 images? – Ever Dev Jun 20 '21 at 16:15
  • that is a result of doing no refactoring – maxPugh Jun 20 '21 at 17:23
  • Why not simply do this with CSS? Using JS to crossfade images infinitely seems an overkill as each time the state changes, the component will re-render and possibly flash during repaint. – brc-dd Jun 20 '21 at 18:14
  • How would you implement this solely with CSS? I saw my options as either I load in all images in the array (10+) and cycle through them with CSS or dynamically load them via JS as to not have such a load. – maxPugh Jun 20 '21 at 18:37

0 Answers0