1

I want to switch between four images in index page. Now what I have is only change of source of image, that causes switch between images with transition. But problem is that when user loads page for the first time, new switched images needs to be load and that makes lets say gap between transitions, because new image isnt visible until load. Is there any way to only switch between already loaded images?

This is what I have now:

import {animated, config, useTransition} from "react-spring";
import Image from "next/image";
import {useEffect, useState} from "react";


const SliderImage = () => {

    const [index, setIndex] = useState(0);

    const images = [
        {id: 0, url: "/images/slide1.jpg", alt: "Chiptuning", priority: true},
        {id: 1, url: "/images/slide4.jpg", alt: "Autočalounictví", priority: false},
        {id: 3, url: "/images/slide2.jpg", alt: "Klimatizace", priority: false},
        {id: 4, url: "/images/slide3.jpg", alt: "Renovace světel", priority: false},
    ]

    const imageTransitions = useTransition(images[index], {
        from: { opacity: 0},
        enter: { opacity: 1},
        leave: { opacity: 0},
        config: config.molasses,
        key: images[index].id,
    });

    useEffect(() => {
        const slideInterval = setInterval(() => {
            setIndex((state) => (state + 1) % 4);
        }, 4000);

        return () => clearInterval(slideInterval);

    }, []);


   return imageTransitions((props, item) => (
        <animated.div style={props}>
            <Image
                src={item.url}
                alt={item.alt}
                layout="fill"
                objectFit="cover"
                priority={item.priority}
            />
        </animated.div>
    ))
}

export default SliderImage;

And what I want to do is have multiple images and only toggle between them.

 <animated.div style={props}>
            <Image
                ...
            />
 </animated.div>

 <animated.div style={props}>
            <Image
               ...
            />
  </animated.div>

 <animated.div style={props}>
            <Image
                ...
            />
 </animated.div>

 <animated.div style={props}>
            <Image
               ..
            />
 </animated.div>

Thank you for your help!

Kretiss
  • 657
  • 4
  • 15

1 Answers1

1

Finally, I found solution. I have loaded all images and now I only changing imageIDs. In images array is compare of ImageID and based on it I change showImage which then in SliderImage component changing opacity in spring.

Here is final code:

sliderImagesContainer component:

import {useEffect, useState} from "react";
import SliderImage from "./sliderImage";


const SliderImagesContainer = () => {

    const [imageID, setImageID] = useState(0)

    const images = [
        {src: "/images/slide1.jpg", alt: "Chiptuning", priority: true, showImage : (imageID === 0)},
        {src: "/images/slide4.jpg", alt: "Autočalounictví", priority: false, showImage : (imageID === 1)},
        {src: "/images/slide2.jpg", alt: "Klimatizace", priority: false, showImage : (imageID === 2)},
        {src: "/images/slide3.jpg", alt: "Renovace světel", priority: false, showImage : (imageID === 3)},
    ]

    useEffect(() => {
        const slideInterval = setInterval(() => {
            setImageID((imageID) => (imageID + 1) % 4);
        }, 4000);

        return () => clearInterval(slideInterval);

    }, []);

    
    return images.map((image, index) => {
        return(
            <SliderImage src={image.src} alt={image.alt} priority={image.priority} showImage={image.showImage} key={index}/>
        )
    })

}

export default SliderImagesContainer;

And then SliderImage component:

import {animated, config, useSpring} from "react-spring";
import Image from "next/image";

const SliderImage = ({src, alt, priority, showImage}) => {

    const spring = useSpring({
        from: {opacity: 0},
        to: {
            opacity: showImage ? 1 : 0,
        },
        config: config.molasses,
    })

    return(
        <animated.div style={spring}>
            <Image
                src={src}
                alt={alt}
                layout="fill"
                objectFit="cover"
                priority={priority}
            />
        </animated.div>
    )
}

export default SliderImage
Kretiss
  • 657
  • 4
  • 15