Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in videoCarousel #6

Open
ayush09316 opened this issue Mar 19, 2024 · 0 comments
Open

Error in videoCarousel #6

ayush09316 opened this issue Mar 19, 2024 · 0 comments

Comments

@ayush09316
Copy link

i am making this in nextjs and typescript and got this error
Screenshot 2024-03-19 223610
my code is:
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import { ScrollTrigger } from "gsap/all";
gsap.registerPlugin(ScrollTrigger);
import { SyntheticEvent, useEffect, useRef, useState } from "react";
import { hightlightsSlides } from "@/constant";
import Image from "next/image";

const VideoCarousel = () => {
const videoRef = useRef<HTMLVideoElement[]>([]);
const videoSpanRef = useRef<HTMLSpanElement[]>([]);
const videoDivRef = useRef<HTMLSpanElement[]>([]);

const [video, setVideo] = useState({
isEnd: false,
startPlay: false,
videoId: 0,
isLastVideo: false,
isPlaying: false,
});

const [loadedData, setLoadedData] = useState<SyntheticEvent[]>([]);
const { isEnd, isLastVideo, startPlay, videoId, isPlaying } = video;

useGSAP(() => {
// slider animation to move the video out of the screen and bring the next video in
gsap.to("#slider", {
transform: translateX(${-100 * videoId}%),
duration: 2,
ease: "power2.inOut", // show visualizer https://gsap.com/docs/v3/Eases
});

// video animation to play the video when it is in the view
gsap.to("#video", {
  scrollTrigger: {
    trigger: "#video",
    toggleActions: "restart none none none",
  },
  onComplete: () => {
    setVideo((pre) => ({
      ...pre,
      startPlay: true,
      isPlaying: true,
    }));
  },
});

}, [isEnd, videoId]);

useEffect(() => {
let currentProgress = 0;
let span = videoSpanRef.current;

if (span[videoId]) {
  // animation to move the indicator
  let anim = gsap.to(span[videoId], {
    onUpdate: () => {
      // get the progress of the video
      const progress = Math.ceil(anim.progress() * 100);

      if (progress != currentProgress) {
        currentProgress = progress;

        // set the width of the progress bar
        gsap.to(videoDivRef.current[videoId], {
          width:
            window.innerWidth < 760
              ? "10vw" // mobile
              : window.innerWidth < 1200
              ? "10vw" // tablet
              : "4vw", // laptop
        });
        
        
        // set the background color of the progress bar
        gsap.to(span[videoId], {
          width: `${currentProgress}%`,
          backgroundColor: "white",
        });
      }
    },

    // when the video is ended, replace the progress bar with the indicator and change the background color
    onComplete: () => {
      if (isPlaying) {
        gsap.to(videoDivRef.current[videoId], {
          width: "12px",
        });
        gsap.to(span[videoId], {
          backgroundColor: "#afafaf",
        });
      }
    },
  });

  if (videoId == 0) {
    anim.restart();
  }

  // update the progress bar
  const animUpdate = () => {
    anim.progress(
      videoRef.current[videoId].currentTime /
        hightlightsSlides[videoId].videoDuration
    );
  };

  if (isPlaying) {
    // ticker to update the progress bar
    gsap.ticker.add(animUpdate);
  } else {
    // remove the ticker when the video is paused (progress bar is stopped)
    gsap.ticker.remove(animUpdate);
  }
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [videoId, startPlay]);

useEffect(() => {
if (loadedData.length > 3) {
if (!isPlaying) {
videoRef.current[videoId].pause();
} else {
startPlay && videoRef.current[videoId].play();
}
}
}, [startPlay, videoId, isPlaying, loadedData]);

const handleProcess = (type:string, i:number) => {
switch (type) {
case "video-end":
setVideo((pre) => ({ ...pre, isEnd: true, videoId: i + 1 }));
break;

  case "video-last":
    setVideo((pre) => ({ ...pre, isLastVideo: true }));
    break;

  case "video-reset":
    setVideo((pre) => ({ ...pre, videoId: 0, isLastVideo: false }));
    break;

  case "pause":
    setVideo((pre) => ({ ...pre, isPlaying: !pre.isPlaying }));
    break;

  case "play":
    setVideo((pre) => ({ ...pre, isPlaying: !pre.isPlaying }));
    break;

  default:
    return video;
}

};

const handleLoadedMetaData = (e:SyntheticEvent) =>{
setLoadedData((pre) => [...pre, e]);
}

return (
<>


{hightlightsSlides.map((list, i) => (



<video
id="video"
playsInline={true}
className={${ list.id === 2 && "translate-x-44" } pointer-events-none}
preload="auto"
muted
ref={(el) => (videoRef.current[i] = el!)}
onEnded={() =>
i !== 3
? handleProcess("video-end", i)
: handleProcess("video-last",0)
}
onPlay={() =>
setVideo((pre) => ({ ...pre, isPlaying: true }))
}
onLoadedMetadata={(e) => handleLoadedMetaData(e)}
>


          <div className="absolute top-12 left-[5%] z-10">
            {list.textLists.map((text, i) => (
              <p key={i} className="md:text-2xl text-xl font-medium">
                {text}
              </p>
            ))}
          </div>
        </div>
      </div>
    ))}
  </div>

  <div className="relative flex-center mt-10">
    <div className="flex-center py-5 px-7 bg-gray-300 backdrop-blur rounded-full">
      {videoRef.current.map((_, i) => (
        <span
          key={i}
          className="mx-2 w-3 h-3 bg-gray-200 rounded-full relative cursor-pointer"
          ref={(el) => (videoDivRef.current[i] = el!)}
        >
          <span
            className="absolute h-full w-full rounded-full"
            ref={(el) => (videoSpanRef.current[i] = el!)}
          />
        </span>
      ))}
    </div>

    <button className="control-btn">
      <Image
        src={isLastVideo ? '/assets/images/replay.svg' : !isPlaying ? '/assets/images/play.svg' : '/assets/images/pause.svg'}
        alt={isLastVideo ? "replay" : !isPlaying ? "play" : "pause"}
        width={20}
        height={20}
        onClick={
          isLastVideo
            ? () => handleProcess("video-reset",0)
            : !isPlaying
            ? () => handleProcess("play",0)
            : () => handleProcess("pause",0)
        }
      />
    </button>
  </div>
</>

);
};

export default VideoCarousel;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant