I have taken the source code from this codepen page. It changes the image on scroll, but instead of image, I want to change the video on scroll.
Here is the code I have so far. The first video plays but it won't change on scroll. I added id="mainImage" in the Video Source tag, so it should work? What am I doing wrong?
CSS
.mouse_scroll {
overflow: visible;
position: relative;
}
.side_sec {
display: flex;
}
.img-links div.text-sec {
text-align: left;
padding: 10px 20px;
border-radius: 10px;
margin: 500px 0px;
background: transparent;
}
.img-links div.active {
border: none;
background: var(--box-bg-color);
}
.featured-img::before {
content: "";
position: absolute;
background-size: 60%;
background-repeat: no-repeat;
background-position: left;
left: 15%;
right: 0px;
top: -50px;
width: 100%;
height: 100%;
z-index: 1;
margin-right: 0px;
}
.featured-img {
position: sticky;
top: 140px;
height: 700px;
}
.featured-img img {
position: absolute;
left: 75px;
top: 35px;
width: 55%;
height: auto;
border-radius: 30px;
}
.side-text {
display: flex;
}
.side-text h3{
color:orange;
}
.side-text p{
color:#000;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<section id="videoonscroll">
<div class="container">
<div class="row">
<div class="side-text">
<div class="col-xl-7 col-lg-7 col-md-12 col-sm-12 col-12">
<div class="img-links">
<div data-src="video1.mp4" class="text-sec active">
<h3 class="margin-10px-bottom">Better writing,<br>better results</h3>
<p class="text-16 width-90">Be perfectly professional, clear, and convincing in a few clicks, not a few hours.</p>
</div>
<div class="text-sec" data-src="video2.mp4">
<h3 class="margin-10px-bottom">The right text<br>for the context</h3>
<p class="text-16 width-90">Get personalized suggestions based on what you’re writing and who will read it.</p>
</div>
<div class="text-sec" data-src="video3.mp4">
<h3 class="margin-10px-bottom">Works where<br>you work</h3>
<p class="text-16 width-90">Grammarly works across all the apps and sites you use. No copying, no pasting, no context switching.</p>
</div>
<div class="text-sec" data-src="video4.mp4">
<h3 class="text-25 font-weight-700 margin-10px-bottom">Never go out of style</h3>
<p class="text-16 width-90">Grammarly understands both your personal style and your brand style guide to help you find your voice.</p>
</div>
<div class="text-sec" data-src="video5.mp4">
<h3 class="text-25 font-weight-700 margin-10px-bottom">This is responsible AI</h3>
<p class="text-16 width-90">Don’t compromise on security. We never sell your data, provide it for advertising purposes, or allow third parties to use it to train their models.</p>
</div>
<!-- Add more divs as needed -->
</div>
</div>
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-12 sm-display-none">
<div class="featured-img">
<video class="video-player_video__8GR5s" autoplay="" loop="" muted="" playsinline="" poster="video1.png">
<source src="video1.mp4" type="video/mp4" data-component-name="default-render-source" id="mainImage" />
</video>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js'></script>
Javascript
$(document).ready(function () {
// Function to handle mouse wheel events
function handleMouseWheel(ele) {
// Your logic here
console.log("Mouse wheel event detected!");
$('.img-links div.text-sec').removeClass('active');
$(ele).addClass('active');
// Update the main image based on the active div
var newImageSrc = $(ele).data('src');
$('#mainImage').attr('src', newImageSrc);
}
const options = { threshold: 0.4 };
// Set up Intersection Observer
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Add scroll event listener when target element is visible
$(window).on('wheel', () => handleMouseWheel(entry.target));
} else {
// Remove scroll event listener when target element is not visible
$(window).off('wheel', () => handleMouseWheel(entry.target));
}
});
}, options);
// Define the target elements you want to observe
const targetElements = $('.img-links div.text-sec');
// Start observing each target element
targetElements.each(function () {observer.observe(this);});
});
I'd like to address some issues in your code first:
</body> taglet variable elTextSecCurrent to store the currently active Element, in order to not reapply some logic on the already active one!elTextSecCurrent || entry.isIntersecting && elTextSecCurrent !== entry.targetHere's the final code with simplified CSS, HTML, and JS:
const $textSec = $(".text-sec"); // Cache your elements!
const $mainImg = $("#mainImage"); // Cache your elements!
let elTextSecCurrent; // to store the currently active textSec Element
function inViewportTextSec(entry) {
if (!elTextSecCurrent || entry.isIntersecting && elTextSecCurrent !== entry.target) {
// If the element is in the viewport, add the active class
$textSec.removeClass("active");
$(entry.target).addClass("active");
$mainImg.attr("src", $(entry.target).data("src"));
elTextSecCurrent = entry.target;
console.log( /*TEST!*/ `Current video src: ${entry.target.dataset.src}`);
}
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(inViewportTextSec);
}, {
threshold: 0.4
});
$textSec.each(function() {
observer.observe(this);
});
:root {
--box-bg-color: #f0f0f0;
}
.text-sec {
padding: 10px 20px;
border-radius: 10px;
margin: 50vh 0;
translate: 0 -50%;
&.active {
border: none;
background: var(--box-bg-color);
}
h3 {
color: orange;
}
}
.featured-img {
position: sticky;
top: 0px;
width: 100%;
height: 100vh;
background: #000;
video {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
crossorigin="anonymous">
<section id="videoonscroll" class="container">
<div class="row side-text">
<div class="col img-links">
<div class="text-sec" data-src="video1.mp4">
<h3>Better writing,<br>better results</h3>
<p>Be perfectly professional, clear, and convincing in a few
clicks, not a few hours.</p>
</div>
<div class="text-sec" data-src="video2.mp4">
<h3>The right text<br>for the context</h3>
<p>Get personalized suggestions based on what you"re writing
and who will read it.</p>
</div>
<div class="text-sec" data-src="video3.mp4">
<h3>Works where<br>you work</h3>
<p>Grammarly works across all the apps and sites you use. No
copying, no pasting, no context switching.</p>
</div>
<div class="text-sec" data-src="video4.mp4">
<h3>Never go out of style</h3>
<p>Grammarly understands both your personal style and your
brand style guide to help you find your voice.</p>
</div>
<div class="text-sec" data-src="video5.mp4">
<h3>This is responsible AI</h3>
<p>Don"t compromise on security. We never sell your data,
provide it for advertising purposes, or allow third parties to use it to train their
models.</p>
</div>
<!-- Add more divs as needed -->
</div>
<div class="col">
<div class="featured-img">
<video id="mainImage" src="video1.mp4" poster="video1.png" autoplay loop muted playsinline></video>
</div>
</div>
</div>
</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With