I’m working on a web project where I want to create a video player similar to YouTube Shorts. The idea is to have a series of videos that change automatically when the user scrolls past the current one. I’ve set up the basic HTML, CSS, and JavaScript, but I’m having trouble getting the videos to change correctly on scroll.
Here’s what I have so far:
console.log("Scroller");
// Get all video player elements
const videoPlayers = document.querySelectorAll('.video-player');
// Initialize a flag to indicate whether the user has interacted with the document
let userHasInteracted = false;
// Add an event listener to each video player to listen for user interaction
videoPlayers.forEach(videoPlayer => {
videoPlayer.addEventListener('click', () => {
// Set the flag to indicate that the user has interacted with the document
userHasInteracted = true;
// If the video is paused, play it
if (videoPlayer.paused) {
videoPlayer.play();
}
});
});
// Add an event listener to the container to detect scroll
const container = document.querySelector('.container');
container.addEventListener('scroll', () => {
videoPlayers.forEach((videoPlayer, index) => {
const videoOffset = videoPlayer.offsetTop;
const videoHeight = videoPlayer.offsetHeight;
const scrollPosition = container.scrollTop;
// Check if the video is in view
if (scrollPosition >= videoOffset && scrollPosition < videoOffset + videoHeight) {
// Play the video if the user has interacted
if (userHasInteracted && videoPlayer.paused) {
videoPlayer.play();
}
} else {
// Pause the video if it's out of view
videoPlayer.pause();
}
});
});
/* Global Styles */
body, html {
margin: 0;
padding: 0;
overflow-x: hidden;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
/* width: 30vh; */
overflow-y: scroll;
scroll-snap-type: y mandatory; /* Enable snap scrolling */
}
.video-container {
width: 100%;
height: 100vh; /* Full viewport height */
scroll-snap-align: start; /* Snap to start of each video */
position: relative;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Follow Button */
.follow-button {
position: absolute;
top: 10px;
right: 10px;
padding: 8px 12px;
background-color: #ff0000;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s ease;
}
.follow-button:hover {
background-color: #cc0000;
}
/* Actions Section: Buttons on the right side of the video */
.actions {
position: absolute;
right: 10px;
top: 20%;
display: flex;
flex-direction: column;
align-items: center;
}
.action-button {
margin: 10px 0;
color: white;
text-align: center;
cursor: pointer;
padding: 10px;
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
border-radius: 50%;
width: 50px;
height: 50px;
opacity: 0.8; /* Transparency effect */
transition: opacity 0.3s ease;
}
.action-button:hover {
opacity: 1;
}
/* Ensure icons are centered within the buttons */
.action-button span {
display: block;
}
/* Responsive Media Queries */
@media (max-width: 768px) {
.actions {
right: 5px;
top: 15%;
}
}
@media (max-width: 480px) {
.video-container {
max-width: 100%;
}
.actions {
position: static;
flex-direction: row;
width: 100%;
justify-content: space-evenly;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Shorts Design</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<!-- Video Sections -->
<div class="video-container">
<video class="video-player" src="videos/video1.mp4" controls></video>
<button class="follow-button">Follow</button>
<div class="actions">
<div class="action-button like">
<span><i class="fa-regular fa-heart"></i></span>
<span>452</span>
</div>
<div class="action-button comment">
<span><i class="fa-regular fa-comment"></i></span>
<span>6</span>
</div>
<div class="action-button share">
<span><i class="fa-solid fa-share"></i></span>
<span>Share</span>
</div>
</div>
</div>
<div class="video-container">
<video class="video-player" src="videos/video2.mp4" controls></video>
<button class="follow-button">Follow</button>
<div class="actions">
<div class="action-button like">
<span><i class="fa-regular fa-heart"></i></span>
<span>452</span>
</div>
<div class="action-button comment">
<span><i class="fa-regular fa-comment"></i></span>
<span>6</span>
</div>
<div class="action-button share">
<span><i class="fa-solid fa-share"></i></span>
<span>Share</span>
</div>
</div>
</div>
<div class="video-container">
<video class="video-player" src="videos/video3.mp4" controls></video>
<button class="follow-button">Follow</button>
<div class="actions">
<div class="action-button like">
<span><i class="fa-regular fa-heart"></i></span>
<span>452</span>
</div>
<div class="action-button comment">
<span><i class="fa-regular fa-comment"></i></span>
<span>6</span>
</div>
<div class="action-button share">
<span><i class="fa-solid fa-share"></i></span>
<span>Share</span>
</div>
</div>
</div>
<!-- Add more video containers as needed -->
</div>
<script src="scripts.js"></script>
</body>
</html>
Problem:
The video player currently covers the whole webpage, and I want it to look more like YouTube Shorts, where the video player is centered and doesn’t take up the entire screen. Additionally, the videos should change automatically when the user scrolls past the current one.
Question:
How can I adjust my code to achieve this effect? Any help or suggestions would be greatly appreciated!