I want that when user scrolls to that part of website animation triggers, means when that part comes in user's view the animation happens, here I am talking about the div class part 2, the part 1 working good but the part2 is not working, means animation works when website loads but at that time user is viewing part1 and when it scrolls to part 2, nothing happens as the animation has already happened when website was loaded. so please help me why it's not working.
Code Snippet
// Function to handle animation when elements are in view
const handleAnimation = () => {
const elements = document.querySelectorAll('.animate-slide-left-bg, .animate-slide-left, .animate-slide-right, .animate-slide-up');
elements.forEach(element => {
// Check if the element is in view
const rect = element.getBoundingClientRect();
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
if (rect.top >= 0 && rect.bottom <= windowHeight) {
// If the element is in view, add the animation class
element.classList.add('animate-visible');
}
});
};
// Add event listener for scroll event
window.addEventListener('scroll', handleAnimation);
// Trigger animation on page load
handleAnimation();
.part2 {
position: relative;
width: 100%;
height: 100%;
background-color: #fff6f2;
display: flex;
flex-direction: column;
font-family: 'Baskerville Old Face', serif;
overflow: hidden;
/* Hide content overflow */
}
.part2b {
display: flex;
flex-direction: row;
position: relative;
}
.part2a {
display: flex;
flex-direction: column;
}
.qq {
font-size: 35px;
margin-top: 50px;
margin-left: 60px;
opacity: 0;
transition: opacity 1s ease;
}
.q2 {
font-size: 25px;
margin-left: 60px;
margin-top: 100px;
height: fit-content;
width: fit-content;
opacity: 0;
transition: opacity 1s ease;
}
.q3 {
font-size: 80px;
margin-left: 70px;
margin-top: 20px;
opacity: 0;
transition: opacity 1s ease;
}
.bg3 {
width: 50%;
height: auto;
margin-left: auto;
/* Align the image to the right edge of the screen */
opacity: 0;
transition: opacity 1s ease;
}
.circle-image {
position: absolute;
top: 40%;
/* Adjust to your desired position */
left: 65%;
/* Adjust to your desired position */
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
border-radius: 50%;
object-fit: cover;
border: 17px solid #fff6f2;
z-index: 2;
opacity: 0;
transition: opacity 1s ease;
}
.animate-slide-right {
animation: slideRight 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-slide-left {
animation: slideLeft 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-slide-up {
animation: slideUp 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-slide-right-circle {
animation: slideRight 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-slide-left-bg {
animation: slideLeft 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
@keyframes slideRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideLeft {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
opacity: 1;
}
}
<body>
<div class="part1">
<div class="A1">
<div class="tt">
<p class="txt2">Creative Portfolio</p>
</div>
<div class="pv">
<p class="txt">PREMIUM<br> VIRTUAL ASSIST</p>
<p class="txt1">Elevating Your Efficiency</p>
</div>
</div>
<div class="A1">
<img src="{% static 'virtualAssist/bg1.jpg' %}" alt="Background Image" class="image">
</div>
<div class="logo-container">
<img src="{% static 'virtualAssist/logo.jpeg' %}" alt="Logo" class="logo">
</div>
</div>
<div class="part2">
<img src="{% static 'virtualAssist/bg4.jpg' %}" alt="Circle Image" class="circle-image animate-slide-up">
<div class="part2b">
<div class="part2a">
<div class="qq animate-slide-left-bg ">Introducing</div>
<div class="q2 animate-slide-left-bg">Premium Virtual Assist stands out for its<br>professional, sophisticated, and efficient <br>approach, making it the go-to choice for clients in<br>need of exceptional virtual assistant services</div>
</div>
<div class="bg3 animate-slide-right">
<img src="{% static 'virtualAssist/bg3.jpg' %}" alt="Background Image" class="image">
</div>
</div>
<div class="q3 animate-slide-up">
WELCOME TO MY </br>
PORTFOLIO
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
Full code:
// Function to handle animation when elements are in view
const handleAnimation = () => {
const elements = document.querySelectorAll('.animate-slide-left-bg, .animate-slide-left, .animate-slide-right, .animate-slide-up');
elements.forEach(element => {
// Check if the element is in view
const rect = element.getBoundingClientRect();
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
if ((rect.top >= 0 || rect.height >= windowHeight) && rect.bottom <= windowHeight) {
// If the element is in view, add the animation class
element.classList.add('animate-visible');
}
});
};
// Add event listener for scroll event
window.addEventListener('scroll', handleAnimation);
// Add event listener for resize event
window.addEventListener('resize', handleAnimation);
// Trigger animation on page load
window.addEventListener('load', handleAnimation);
.part2 {
position: relative;
width: 100%;
height: 100%;
background-color: #fff6f2;
display: flex;
flex-direction: column;
font-family: 'Baskerville Old Face', serif;
overflow: hidden;
/* Hide content overflow */
}
.part2b {
display: flex;
flex-direction: row;
position: relative;
}
.part2a {
display: flex;
flex-direction: column;
}
.qq {
font-size: 35px;
margin-top: 50px;
margin-left: 60px;
opacity: 0;
transition: opacity 1s ease;
}
.q2 {
font-size: 25px;
margin-left: 60px;
margin-top: 100px;
height: fit-content;
width: fit-content;
opacity: 0;
transition: opacity 1s ease;
}
.q3 {
font-size: 80px;
margin-left: 70px;
margin-top: 20px;
opacity: 0;
transition: opacity 1s ease;
}
.bg3 {
width: 50%;
height: auto;
margin-left: auto;
/* Align the image to the right edge of the screen */
opacity: 0;
transition: opacity 1s ease;
}
.circle-image {
position: absolute;
top: 40%;
/* Adjust to your desired position */
left: 65%;
/* Adjust to your desired position */
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
border-radius: 50%;
object-fit: cover;
border: 17px solid #fff6f2;
z-index: 2;
opacity: 0;
transition: opacity 1s ease;
}
.animate-slide-right {
animation: 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-visible.animate-slide-right {
animation-name: slideRight;
}
.animate-slide-left {
animation: 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-visible.animate-slide-left {
animation-name: slideLeft;
}
.animate-slide-up {
animation: 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-visible.animate-slide-up {
animation-name: slideUp;
}
.animate-slide-right-circle {
animation: 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-visible.animate-slide-right-circle {
animation-name: slideRight;
}
.animate-slide-left-bg {
animation: 1s forwards;
opacity: 0;
/* Initially hide the elements */
}
.animate-visible.animate-slide-left-bg {
animation-name: slideLeft;
}
@keyframes slideRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideLeft {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
opacity: 1;
}
}
<div class="part1">
<div class="A1">
<div class="tt">
<p class="txt2">Creative Portfolio</p>
</div>
<div class="pv">
<p class="txt">PREMIUM<br> VIRTUAL ASSIST</p>
<p class="txt1">Elevating Your Efficiency</p>
</div>
</div>
<div class="A1">
<img src="{% static 'virtualAssist/bg1.jpg' %}" alt="Background Image" class="image">
</div>
<div class="logo-container">
<img src="{% static 'virtualAssist/logo.jpeg' %}" alt="Logo" class="logo">
</div>
</div>
<div class="part2">
<img src="{% static 'virtualAssist/bg4.jpg' %}" alt="Circle Image" class="circle-image animate-slide-up">
<div class="part2b">
<div class="part2a">
<div class="qq animate-slide-left-bg ">Introducing</div>
<div class="q2 animate-slide-left-bg">Premium Virtual Assist stands out for its<br>professional, sophisticated, and efficient <br>approach, making it the go-to choice for clients in<br>need of exceptional virtual assistant services</div>
</div>
<div class="bg3 animate-slide-right">
<img src="{% static 'virtualAssist/bg3.jpg' %}" alt="Background Image" class="image">
</div>
</div>
<div class="q3 animate-slide-up">
WELCOME TO MY </br>
PORTFOLIO
</div>
</div>
All animations play immediately because their state is running
when defined like this:
.animate-slide-right {
animation: slideRight 1s forwards;
}
If changed to:
.animate-slide-right {
animation: 1s forwards;
}
.animate-visible.animate-slide-right {
animation-name: slideRight;
}
animation will start only when the element has animate-visible
class.
A view checking condition
rect.top >= 0 && rect.bottom <= windowHeight
should be extended
(rect.top >= 0 || rect.height >= windowHeight) && rect.bottom <= windowHeight
to make sure that elements with excessive height get activated too.
It might be better to change the initial invocation of handleAnimation()
to window.addEventListener('load', handleAnimation)
so the first animations don't start too soon. Adding window.addEventListener('resize', handleAnimation)
will improve the responsiveness.