My goal is to showcase videos on a webpage while utilizing border-radius to round the corners for a more aesthetically pleasing look.
The challenge arises as the videos come in varying aspect ratios, requiring them to be accommodated within containers without distorting their original proportions. With changing container and video dimensions over time, including potential resizing due to dynamic sources like getUserMedia or streaming, achieving a consistent and optimal display becomes complex.
In scenarios where the videos shrink too small, conventional methods like setting max-width and max-height fall short of satisfying the need to utilize all available space within the container effectively.
Upon exploration, it seems that using object-fit: contain offers the best solution for fitting videos into containers while preserving aspect ratios. However, compatibility issues with border-radius arise when the video fails to fully occupy the container.
Referring to an insightful answer, it suggests that a pure CSS approach might not address this specific issue. Thus, I seek clarification on whether this limitation still holds true.
To summarize the challenges faced:
- Sole reliance on max-width and max-height proves ineffective when videos are undersized and require expansion within the container.
- Despite its advantages, object-fit: contain encounters limitations when combined with border-radius under various circumstances.
Below presents a code snippet wherein JavaScript is employed to compare parent (border) and video aspect ratios, aiding in deciding between width: 100% or height: 100%. The CSS rules are externally defined through classnames.
// JavaScript component fetching and rendering videos
const DisplayVideo = ({
videoSrc = null,
// additional props
}) => {
const videoRef = useRef(null);
const borderRef = useRef(null);
const [fillMode, setFillMode] = useState(''); // fill-width or fill-height
useEffect(() => {
// Play video if new source provided
if (videoRef && videoRef.current && videoSrc) {
if (videoRef.current.srcObject !== videoSrc) {
videoRef.current.srcObject = videoSrc;
}
videoRef.current.play();
}
}, [videoRef, videoSrc]);
useEffect(() => {
// Determine fill mode based on aspect ratios
const video = videoRef.current;
const border = borderRef.current;
if (video && border) {
const vAspectRatio = video.videoWidth / video.videoHeight;
const bAspectRatio = border.clientWidth / border.clientHeight;
setFillMode((vAspectRatio > bAspectRatio) ? 'fill-width' : 'fill-height');
}
});
return (
<div className="display-video-wrapper" ref={borderRef}>
<video className={`display-video ${fillMode}`} ref={videoRef} />
// other content
</div>
);
};
const mapStateToProps = (state, ownProps) => {
// mapping relevant data
return { videoSrc: remoteVideoSrcs[mid] };
};
export default connect(mapStateToProps)(DisplayVideo);
An issue arises as the videoWidth and videoHeight values in the useEffect return as 0 during execution. Contrastingly, calling document.getElementsByClassName(...) from the console yields accurate values instead of 0. This anomaly potentially indicates unsuitability of useEffect placement. Considering redux triggers execution post-change in videoSrc only, how can the code be modified to reflect changes in videoWidth and videoHeight promptly?