I’m working on a component that displays a video with a blurred mirrored canvas behind it here is the reference link.
The canvas is supposed to match the video dimensions and be updated in real-time. However the blur effect doesn’t appear as expected.
Here is the full component code and css to it.
///VideoWithBlur.tsx
"use client";
import { useEffect, useRef, useState } from 'react';
const VideoWithBlur = () => {
const [sidePadding, setSidePadding] = useState(20); // Initial padding in percentage
const videoWrapRef = useRef<HTMLDivElement>(null);
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
const maxPadding = 20;
const minPadding = 5;
const scrollMax = documentHeight - windowHeight;
const newPadding = Math.max(
minPadding,
maxPadding - (scrollPosition / scrollMax) * (maxPadding - minPadding)
);
setSidePadding(newPadding);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
useEffect(() => {
const tItem = videoWrapRef.current;
if (tItem) {
const canvas = tItem.querySelector(".canvas") as HTMLCanvasElement;
const video = tItem.querySelector(".reel") as HTMLVideoElement;
if (canvas && video) {
const ctx = canvas.getContext("2d");
if (ctx) {
const draw = () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
requestAnimationFrame(draw);
};
video.addEventListener("play", () => {
draw();
});
}
}
}
}, []);
return (
<div ref={videoWrapRef} className="h-screen w-screen flex items-center justify-center relative overflow-hidden">
<div
className="video-container"
style={{
paddingLeft: `${sidePadding}%`,
paddingRight: `${sidePadding}%`,
}}
>
<div className="video-wrap">
<canvas className="canvas"></canvas>
<video
ref={videoRef}
className="reel"
src="/Final.mp4"
autoPlay
muted
loop
playsInline
>
Your browser does not support the video tag.
</video>
</div>
</div>
</div>
);
};
export default VideoWithBlur;
//globals.css
.canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
filter: blur(150px); /* worked once until refresh */
}
.video-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80%;
transition: padding 0.3s ease;
box-sizing: border-box;
}
.video-wrap {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 20px;
}
.reel {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 20px;
}
Here what i have so far:
I set the canvas size to match the video dimensions in the useEffect hook using canvas.width = video.videoWidth and canvas.height = video.videoHeight.
I applied a CSS filter: blur(150px) to the canvas. I’ve manage to get this blur to work one time, however this solution doesn’t help. After i refresh the page the blur disappears until i manually adjust blur and/or size of canvas in code.
I implemented dynamic padding adjustment based on the scroll position using a state variable and event listeners. I expected canvas the padding to decrease as the user scrolls down and canvas to update it size then show blur, but that didn’t help.
Does anybody know about this?
sØt is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.