Reputation: 21
React Developers, I am trying to achieve a functionality in REACT where I can play a limited part of the video using mouse scroll. Some how I came to a point where it is working. But still it's not working as expected. The functionality that I want to achieve is here: Open Link Here
Functionality Detail: 1: When I scroll down it plays few seconds of the video and it have to stop. 2: Scrolling up will play another video which is made is backward direction. 3: Custom Clickable progress bar
I have tried to make the same thing but it's not working properly. It does not stay on Video component while i am scrolling. It play's the video with scroll but it also went a little bit down to third component. It should stay on the same component till all the segments of videos completed. Scroll back also not working when i come to third component and comes back to the video component the reverse scroll does not works.
Here is my code:
ScrollVideo.js
import React, { useRef, useEffect, useState } from 'react';
import styled from 'styled-components';
import ScrollVid from '../content/videos/ft.mp4';
import VidImage from '../content/images/vidcover.JPG';
const VideoWrapper = styled.div`
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
video {
width: 100%;
height: 100%;
object-fit: cover;
}
`;
const ProgressBar = styled.div`
position: absolute;
bottom: 0;
left: 0;
height: 5px;
background: #fff;
transition: width 0.3s ease;
width: ${(props) => (props.$progress / 7) * 100}%;
`;
const ScrollVideo = () => {
const videoRef = useRef(null);
const containerRef = useRef(null);
const [scrollIndex, setScrollIndex] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
const [isInView, setIsInView] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
const entry = entries[0];
setIsInView(entry.isIntersecting);
},
{ threshold: 0.8 }
);
if (containerRef.current) {
observer.observe(containerRef.current);
}
return () => {
if (containerRef.current) {
observer.unobserve(containerRef.current);
}
};
}, []);
useEffect(() => {
if (isInView) {
const handleWheel = (event) => {
event.preventDefault();
if (isPlaying) return;
const { deltaY } = event;
const newScrollIndex = Math.min(
8,
Math.max(0, scrollIndex + (deltaY > 0 ? 1 : -1))
);
if (newScrollIndex !== scrollIndex) {
setScrollIndex(newScrollIndex);
}
};
window.addEventListener('wheel', handleWheel, { passive: false });
return () => {
window.removeEventListener('wheel', handleWheel);
};
}
}, [isInView, isPlaying, scrollIndex]);
useEffect(() => {
const video = videoRef.current;
if (video && scrollIndex > 0 && scrollIndex <= 7) {
setIsPlaying(true);
video.currentTime = (scrollIndex - 1) * 3;
video.play();
const timeout = setTimeout(() => {
video.pause();
setIsPlaying(false);
}, 3000);
return () => clearTimeout(timeout);
} else if (scrollIndex === 8) {
const nextSection = containerRef.current.nextElementSibling;
if (nextSection) {
setScrollIndex(9); // To ensure it doesn't keep transitioning
nextSection.scrollIntoView({ behavior: 'smooth' });
}
} else if (scrollIndex === 0) {
const prevSection = containerRef.current.previousElementSibling;
if (prevSection) {
prevSection.scrollIntoView({ behavior: 'smooth' });
}
}
}, [scrollIndex]);
return (
<VideoWrapper ref={containerRef}>
<video
ref={videoRef}
muted
preload="metadata"
poster={VidImage}
playsInline
className="w-full h-auto object-cover"
>
<source src={ScrollVid} type="video/mp4" />
</video>
<ProgressBar $progress={scrollIndex} />
</VideoWrapper>
);
};
export default ScrollVideo;
App.js
import React from 'react';
import Header from './components/Header';
import HeroSection from './components/HeroSection';
import SecondSection from './components/SecondSection';
import Specs from './components/SpecsTruck'
import Scroll from './components/ScrollVideo'
import Vid from './components/FullpageWithVideos'
import './style.css'
function App() {
return (
<div style={{ backgroundColor: 'black', color: 'white' }}>
<Header />
<HeroSection />
<Vid/>
<Scroll/>
<SecondSection />
<Specs/>
</div>
);
}
export default App;
Style.css
.video-section {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.video-section video {
width: 100%;
height: 100%;
object-fit: cover;
}
.progress-bar {
position: absolute;
bottom: 0;
left: 0;
height: 5px;
background: #fff;
transition: width 0.3s;
}
Upvotes: 0
Views: 23
Reputation: 41595
More than a React question this is a JavaScript one.
Here's how to do it:
var video = document.querySelector('.video');
// Play the video
video.play();
// Stop the video after 3 seconds
setTimeout(function() {
video.pause();
}, 3000);
And if you use fullpage.js, then you can use the beforeLeave callback.
Here's a simple demo: https://codepen.io/alvarotrigo/pen/ZEdrOaW
And the code:
new fullpage('#fullpage', {
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
beforeLeave: function(origin, destination, direction, trigger){
if(origin.index === 0){
var video = document.querySelector('.video');
// Play the video
video.play();
// Set a timeout to stop the video after 2 seconds
setTimeout(function() {
video.pause(); // Pause the video
}, 3000);
}
return false;
},
// Get your license at https://alvarotrigo.com/fullPage/pricing/
licenseKey: 'YOUR LICENSE KEY HERE '
});
Upvotes: 0