Search code examples
javascriptreactjsimagesource

How to change image src on scroll in reactjs


I want to change the source of image onscroll in reactjs. Like if scrollY is greater than 100 change the image source and if it is greater than 200 change it another source. i tried to do it but could not. any ideas?

    import React, { useEffect, useState, useRef } from 'react';
import './Video.css';
import { useInView } from 'react-intersection-observer';

function Video() {

    const videoSrc1 = "https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/6341303c29c5340961dc9ae6_Mco-1-transcode.mp4";

    const videoSrc2 = "https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/63413ff244f1dc616b7148a0_Mco-transcode.mp4";
        const videoSrc3 = "https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/63455a67996ba248148c4e31_add-options%20(3)-transcode.mp4";
    
    const img1 = 'https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/63455a67996ba248148c4e31_add-options%20(3)-poster-00001.jpg';
    const img2 = 'https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/63413ff244f1dc616b7148a0_Mco-poster-00001.jpg';
    const img3 = 'https://global-uploads.webflow.com/62efc7cb58ad153bfb146988/63455a67996ba248148c4e31_add-options%20(3)-poster-00001.jpg';


    const [scrollPosition, setScrollPosition] = useState(0);
    const handleScroll = () => {
        const position = window.pageYOffset;
        setScrollPosition(position);
    };

    useEffect(() => {
        window.addEventListener('scroll', handleScroll, { passive: true })

        return () => {
            window.removeEventListener('scroll', handleScroll);
        };
    }, []);


    {
        if (scrollPosition>=316){
            // this.src={videoSrc2}
        }
    }
   console.log("position;", scrollPosition)


    return (
        <div className='container'>

            <video loop autoPlay muted className='video'>
                <source src={videoSrc1} type="video/webm" />
            </video>

           
   

        </div>
    )
   
}

export default Video

Solution

  • You can do a combination of Vanilla JS methods and React methods to achieve this.

    Your best best bet is to use the useEffect hook and add an event listener to the Window DOM object based on where on the page the scroll is position.

    • First you need a function that executes every time the DOM re-renders (scrolling does this)

    start by using the useEffect hook

    useEffect(() => {}, [])
    
    • Next you want a function that executes specifically when you scroll the page

    you can add an event handler to the window DOM element

    window.addEventListener('scroll',() => {})
    
    • Then you want to track the where you are on the page (how far up or how far down)

    You can use the window's scrollTop property to return how far up or down you are on the page relative to the top of the page

    document.documentElement.scrollTop 
    
    • Now comes the logic part, you said you want to change the image's src based on how far up or down you've scrolled on the page

    This is where, useState, boolean flags and the ternary operator come into play

    • You can write a useState hook to store the Y position of the scroll, and the useEffect and scroll event listener will keep updating it to the current position
    const [scrollPosition, getScrollPositon] = useState(document.documentElement.scrollTop)
    
    
    • finally nest the hook function into the window 'scroll' function and nest that in the useEffect hook
    const [scrollPosition, getScrollPositon] = useState(document.documentElement.scrollTop)
    
    useEffect(() => {
      window.addEventListener('scroll',() => {
        getScrollPositon(document.documentElement.scrollTop);
      })
    }, [])
    
    

    AND finally write the logic in your .jsx code to say 'when we are x number of pixel below the top of the screen...change the image source'

    
    const App = () => {
    
      return (
        <div className='app'>
          <img src={scrollPosition < 1000 ? 'http://imagelinkA.com' : 'http://imagelinkB.com'}>
        </div>
      ); 
    
    }
    
    

    Now you put it all together...

    // App.js/jsx
    
    import { useState, useEffect } from 'react';
    
    const App = () => {
    
      // initial scroll positon on page load
      const [scrollPosition, getScrollPositon] = useState(document.documentElement.scrollTop)
    
      // hook and event handlers to keep track of and update scroll
      useEffect(() => {
        window.addEventListener('scroll',() => {
        getScrollPositon(document.documentElement.scrollTop);
        })
      }, [])
    
      // your .jsx code with appropriate boolean flags and use of the ternary operator
      return (
        <div className='app'>
          <img src={scrollPosition < 1000 ? 'http://imagelinkA.com' : 'http://imagelinkB.com'}>
        </div>
      ); 
    
    }
    
    

    Hope I was able to help!