Recreate the Apple iPhone 15 Pro website, combining GSAP animations and Three.js 3D effects. From custom animations to animated 3D models, this tutorial covers it all.
i am making this in nextjs and typescript and got this error
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";
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);
}
}
i am making this in nextjs and typescript and got this error 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 });}, [isEnd, videoId]);
useEffect(() => { let currentProgress = 0; let span = videoSpanRef.current;
// 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;
};
const handleLoadedMetaData = (e:SyntheticEvent) =>{
setLoadedData((pre) => [...pre, e]);
}
return ( <>
{text}
))}); };
export default VideoCarousel;