Not so long ago I worked at an advertising company where my team was responsible for creating custom campaigns in the form of websites for our clients.
I’ve worked with several big companies at this time, and one of their favourite was the component we are about to create. Essentially, it’s just a video that gets played when you land on the page, and when it finishes it slowly disappears allowing you to access the website, click buttons etc. Obviously the better video you have to show the user, the bigger the “wow” factor will be.
You can find the Github repository here with the completed code.
Now, we’ll start with creating a new component called VideoReveal
and have this code for it:
import { useRef } from "react";
interface VideoRevelProps {
onVideoEnd: () => void;
}
export const VideoReveal = ({ onVideoEnd }: VideoRevelProps) => {
const wrapperRef = useRef<HTMLDivElement | null>(null);
const handleVideoEnded = () => {
wrapperRef?.current?.classList?.add("opacity-0", "pointer-events-none");
setTimeout(() => {
onVideoEnd();
}, 500);
};
return (
<div
ref={wrapperRef}
onClick={handleVideoEnded}
className="fixed top-0 left-0 w-full h-full z-50 transition-opacity duration-500"
>
<video
autoPlay
muted
className="w-full h-full object-cover"
onEnded={handleVideoEnded}
>
<source src="/door.mp4" type="video/mp4" />
</video>
</div>
);
};
Here’s what happens:
We have a video defined here that has the autoplay
property, meaning it will start playing the video as soon the component mounts. We also set it to take the full height and screen of the viewport, and gave it a z-index to make it appear over everything already on the page.
Once this video ends, we want to remove this component. But instead of abruptly unmounting the component, we set it’s opacity
to 0
over 500ms
and also invoke our onVideoEnd
once the CSS transition finished (500ms).
Why do we need the `onVideoEnd`
callback?
In the parent component where you want to use the VideoReveal
component, here’s how you can use it:
"use client";
import { VideoReveal } from "./components/VideoReveal";
import { useState } from "react";
export default function Home() {
const [isVideoPlaying, setIsVideoPlaying] = useState(true);
return (
<main>
<h1>Homepage content</h1>
{isVideoPlaying ? (
<VideoReveal onVideoEnd={() => setIsVideoPlaying(false)} />
) : null}
</main>
);
}
With this we mount our VideoReveal
because isVideoPlaying
is set to true
by default and the video start playing. Once the video is finished playing, it calls whatever we pass in to onVideoEnd.
In this scenario, we know that when the video stopped playing, we want to remove our video component as we don’t need it anymore, and we want to display the content on the page so the user can interact with it etc.
Disclaimer
This solution might not be for you if you want the fastest page and interactivity for the user. This is meant to be used as more of a creative approach to “woo” or “charm” the user.
That’s all, hope you enjoyed it and let me know if you have any questions, I’m happy to answer.
You can find the Github repository here with the completed code.