skip to Main Content

I have a row of thumbnails that are supposed to play a video when I hover over them, and stop when I mouse out of the thumbnail. As of right now, only the last thumbnail plays it’s video when I hover, all the other ones are frozen. But if I hover over one of the frozen videos, then back to the working video, the working video will have moved forward as if I was hovering over it the whole time.

This is my component

import React from 'react'
import { projectlist } from '../../projectlist'
import { useRef } from 'react'
import './Projects.css'

export default function Projects() {
  const playerRef = useRef<any>()

  function onMouseOver(){
    console.log('playerRef',playerRef)
    playerRef.current.play();
  }

  function onMouseOut(){
    playerRef.current.pause();
  }

  return (
    <div className='projects-container'>

      {projectlist.map((video)=>{
        return(
          <div className='project-image' key={video.video_id} onMouseOver={onMouseOver} onMouseOut={onMouseOut}>
            <video ref={playerRef} muted loop>
              <source src={video.test} type='video/mp4' />
            </video>
            <img src={video.image}/>
          </div>
        )
      })}

    </div>
  )
}

Here is the CSS incase it is relevant

.project-image{
    position: relative;

    img{
        position: relative;
        width: 100%;
        height: 100%;
        z-index: 1;
    }
    
    video{
        position: absolute;
        opacity: 0;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        z-index: 0;
    }

    &:hover{
        video{
            z-index: 2;
            opacity: 1;
        }
    }
}

I used this video as a reference: https://www.youtube.com/watch?v=UIX0DSaNOjI&ab_channel=ColbyFayock around the 15:30 mark is where I followed the useRef guide.

2

Answers


  1. It is simple. You have only one ref and multiple videos. How can the system or anyone identify which video the ref is for. Also, all your videos have only one listener for mouseOut and mouseOver each.

    You need a list of refs, one for each video. Or you need a ref, which can hold multiple values.

    Now, you also have to modify your functions to ensure that there is an identifier for each video.

    export default function Projects() {
      const playerRef = useRef<any>(new Array(projectlist.length).fill(false));
    
      function onMouseOver(index){
        console.log('playerRef',playerRef)
        playerRef.current[index].play();
      }
    
      function onMouseOut(){
        playerRef.current[index].pause(index);
      }
    
      return (
        <div className='projects-container'>
    
          {projectlist.map((video,index)=>{
            return(
              <div className='project-image' key={video.video_id} onMouseOver={() => { onMouseOver(index) }} onMouseOut={() => { onMouseOut(index) }}>
                <video ref={playerRef} muted loop>
                  <source src={video.test} type='video/mp4' />
                </video>
                <img src={video.image}/>
              </div>
            )
          })}
    
        </div>
      )
    }
    

    You can also follow the video and create a ref and method for each video seperately.

    Login or Signup to reply.
  2. I give you an example for your reference:

    let pause = (e) => {
      let video = e.target;
      video.pause();
    }
    let start = (e) => {
      let video = e.target;
      video.play();
    }
    <div>
      <video muted loop onMouseOver={start} onMouseOut={pause}>
              <source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"/>
          </video>
    </div>
    <div>
      <video muted loop onMouseOver={start} onMouseOut={pause}>
        <source src="https://www.w3schools.com/tags/movie.mp4"/>
      </video>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search