I'm new to JS, especially working with gsap. I want to perform scrolling to certain sections via gsap ScrollTo. I want to make a smooth and not very fast scrolling. I also want to move elements in parallel with scrolling, creating a parallax effect. Maybe someone has encountered such a thing? Or recommend something to replace gsap. Very much need help.
My HTML:
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TEST</title>
<link rel="icon" type="image/x-icon" href="./static/img/favicon-32x32.ico" sizes="32x32">
<link rel="icon" type="image/x-icon" href="./static/img/favicon-192x192.ico"
sizes="192x192">
<link rel="apple-touch-icon" href="./static/img/favicon-192x192.ico">
<link rel="preconnect" href=";>
<link rel="preconnect" href="; crossorigin>
<link href=":[email protected]&display=swap" rel="stylesheet">
<script src="/[email protected]/dist/gsap.min.js"></script>
<script src="/[email protected]/dist/ScrollTrigger.min.js"></script>
<script src="/[email protected]/dist/ScrollToPlugin.min.js"></script>
<link rel="stylesheet" href="./static/css/style.css">
</head>
<body>
<main class="main">
<div class="section-top">
<section class="welcome">
<div class="block-logo animated ">
<img src="./static/img/logo.svg" alt="Logo">
<span>TEXT</span>
</div>
<div class="wrap-block-kan animated ">
<div class="block-kan">
<span>text</span>
<img src="./static/img/logo-kan.svg" alt="">
</div>
</div>
<picture>
<source srcset="./static/img/pattern-left-1-full.png"
media="(min-width: 576px)">
<img src="./static/img/mob/pattern-left-1.png" alt="Pattern"
class="pattern-left animated">
</picture>
<picture>
<source srcset="./static/img/pattern-right-1-full.png"
media="(min-width: 576px)">
<img src="./static/img/mob/pattern-right-1.png" alt="Pattern"
class="pattern-right animated">
</picture>
</section>
<section class="comming-soon">
<div class="container">
<h2 class="block-title animated ">TEXT <span class="text-blue">ТВІЙ</span>
<span class="img-rutm"><img src="./static/img/rutm-text.svg"
alt="Logo rutm"></span>TEXT!
</h2>
<div class="counter animated ">
<div class="element-count day">
<div class="number">07</div>
<span class="num-text">DAYS</span>
</div>
<div class="element-count hour">
<div class="number">11</div>
<span class="num-text">HOUR</span>
</div>
<div class="separator">:</div>
<div class="element-count minute">
<span class="number">01</span>
<span class="num-text">MIN</span>
</div>
<div class="separator gray">:</div>
<div class="element-count second">
<div class="number">02</div>
<span class="num-text">SEC</span>
</div>
</div>
</div>
</section>
<section class="block-img-top">
<img src="./static/img/mob/img-2.webp" alt="Photo kvartal 1"
class="main-block-img">
<img src="./static/img/mob/pattern-left-2.png" alt="Pattern"
class="pattern-left animated">
</section>
<section class="block-desc">
<div class="container">
<p class="animated paragraph-1">
TEXT
</p>
<p class="animated">
TEXT
</p>
<br>
<p class="animated paragraph-2"><strong>«TEXT»</strong> TEXT
</p>
</div>
<img src="./static/img/mob/pattern-right-2.png" alt="Pattern"
class="pattern-right animated">
</section>
</div>
</main>
<script src="./static/js/scripts.js"></script>
</body>
</html>
My code CSS:
body {
font-family: "Geologica", serif;
color: var(--color-font-1);
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
font-size: 16px;
background-color: #000000;
overflow: hidden;
}
@media screen and (min-width: 576px) {
body {
overflow: auto;
}
}
body.show-scrollbar {
overflow-y: scroll;
}
h1,
h2,
h3 {
text-transform: uppercase;
}
h2 {
font-size: 31px;
font-weight: 100;
letter-spacing: 0.1em;
line-height: 36px;
}
h3 {
font-size: 1.563rem;
font-weight: 100;
line-height: 28px;
}
main {
overflow: hidden;
}
.container {
padding: 0 4rem 0 2.125rem;
}
.pattern-left,
.pattern-right {
position: absolute;
}
.section-top {
position: relative;
}
.text-blue {
color: var(--color-blue);
}
.text-yellow {
color: var(--color-yellow);
}
.text-green {
color: var(--color-green);
}
.text-orange {
color: var(--color-orange);
}
.text-red {
color: var(--color-red);
}
/* welcome */
.welcome {
position: relative;
height: calc(100vw* 2.38);
width: auto;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 80%, rgba(0, 0, 0, 0.9) 100%), url("../img/mob/img-1.webp");
background-repeat: no-repeat;
background-origin: content-box;
background-size: cover;
z-index: 2;
}
@media screen and (min-width: 576px) {
.welcome {
height: calc(100vw* 1.43);
background-image: url("../img/img-1-full.webp");
}
}
.welcome .wrap-block-kan {
display: flex;
justify-content: right;
padding-top: 2.875rem;
padding-right: 12%;
}
.welcome .block-kan {
position: relative;
}
.welcome .block-kan img {
width: 5.25rem;
}
.welcome .block-kan span {
position: absolute;
top: 0.625em;
left: -0.75em;
font-size: 0.7em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 1px;
}
.welcome .pattern-left {
width: 18.67%;
left: -4.8vw;
top: 22vw;
}
.welcome .pattern-right {
width: 25vw;
top: 135vw;
right: -14%;
}
.block-logo {
padding-top: 2.5rem;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
opacity: 1;
transition: opacity .8s ease, scale 1s ease, transform .01s ease;
}
.block-logo img {
margin-bottom: 0.75em;
max-width: 53%;
}
.block-logo span {
font-size: .7em;
font-weight: 300;
letter-spacing: 4px;
text-transform: uppercase;
}
@media screen and (min-width: 576px) {
.welcome .block-logo img {
margin-bottom: .8em;
max-width: 25%;
}
.welcome .block-logo span {
font-size: .6em;
}
.welcome .pattern-left {
width: 10.55vw;
left: 0;
top: 62.5vw;
}
.welcome .pattern-right {
width: 6.72vw;
right: 0;
top: 18.92vw;
}
}
@media screen and (min-width: 768px) {
.welcome .block-logo img {
margin-bottom: 1.1em;
}
.welcome .block-logo span {
font-size: .7em;
letter-spacing: 5px;
}
.welcome .wrap-block-kan {
padding-top: 2.375rem;
padding-right: 27%;
}
}
@media screen and (min-width: 992px) {
.welcome .block-logo span {
font-size: .9em;
letter-spacing: 6px;
}
.welcome .wrap-block-kan {
padding-right: 29%;
}
}
@media screen and (min-width: 1200px) {
.welcome .block-logo span {
font-size: 1.1vw;
letter-spacing: 8px;
}
.welcome .wrap-block-kan {
padding-right: 31vw;
}
}
@media screen and (min-width: 1400px) {
.welcome .block-logo {
padding-top: 3.75vw;
}
.welcome .block-logo img {
margin-bottom: 1.4em;
}
.welcome .block-logo span {
font-size: 1.3vw;
}
.welcome .wrap-block-kan {
padding-top: 2.9vw;
padding-right: 30.1vw;
}
.welcome .block-kan img {
width: 7vw;
}
.welcome .block-kan span {
font-size: .9vw;
}
}
/* comming-soon */
ming-soon {
position: relative;
margin-top: -4.125rem;
margin-bottom: -1.25rem;
z-index: 2;
}
ming-soon .container {
padding: 0 1.65rem;
}
ming-soon .block-title {
margin-bottom: 2rem;
padding: 0 1.875rem 0 .25rem;
position: relative;
z-index: 1;
}
ming-soon .block-title .img-rutm {
display: inline-block;
width: 8rem;
margin-right: .5em;
margin-left: .1em;
}
@media screen and (min-width: 768px) {
ming-soon {
position: absolute;
top: 20rem;
right: 8%;
max-width: 40%;
}
ming-soon .container {
padding: 0;
}
ming-soon .block-title {
margin-bottom: 1rem;
padding: 0;
font-size: 1.2rem;
}
ming-soon .block-title .img-rutm {
width: 25%;
margin-bottom: -2px;
}
}
@media screen and (min-width: 992px) {
ming-soon {
top: 23rem;
right: 10%;
max-width: 37%;
}
ming-soon .block-title {
font-size: 1.45rem;
margin-bottom: 1.5rem;
}
}
@media screen and (min-width: 1200px) {
ming-soon {
right: 17%;
max-width: 30%;
}
}
@media screen and (min-width: 1400px) {
ming-soon {
top: 29vw;
right: 18%;
max-width: 29%;
}
ming-soon .block-title {
font-size: 1.875vw;
line-height: 120%;
}
ming-soon .block-title .img-rutm {
width: 27%;
margin-bottom: -1px;
}
}
/* counter */
.counter {
display: flex;
justify-content: space-between;
text-align: center;
font-size: 3.313rem;
}
.counter .element-count {
display: flex;
flex-direction: column;
min-width: 22%;
}
.counter .element-count.day {
min-width: auto;
}
.main .counter .element-count.day {
margin-right: 14px;
}
.counter .second .number,
.counter .separator.gray {
color: var(--color-gray);
}
.counter .separator.gray {
padding-left: 5px;
}
@media screen and (min-width: 768px) {
.counter .second .number,
.counter .separator.gray {
color: var(--color-white);
opacity: .5;
}
}
.counter .number {
letter-spacing: 1.32px;
}
.counter .separator {
margin-top: -4px;
margin-left: -5px;
}
.counter .num-text {
color: var(--color-gray);
font-size: 6px;
letter-spacing: 0.18px;
font-weight: 100;
}
@media screen and (min-width: 576px) {
.main .counter {
width: 100%;
}
.counter .number {
font-size: 4rem;
letter-spacing: 1.4px;
}
.counter .num-text {
font-size: 7px;
letter-spacing: 0.25px;
color: var(--color-white);
opacity: 0.6;
}
.counter .separator {
margin-left: -5px;
}
}
@media screen and (min-width: 768px) {
.counter .number {
font-size: 3.5rem;
letter-spacing: 1.62px;
}
.counter .num-text {
font-size: .5rem;
letter-spacing: 0.35px;
}
}
@media screen and (min-width: 992px) {
.counter .separator {
margin-top: 0;
}
}
@media screen and (min-width: 1400px) {
.main .counter {
font-size: 3.8vw;
}
.counter .num-text {
font-size: 0.7rem;
letter-spacing: 0.45px;
}
.counter .number {
font-size: 4.4vw;
letter-spacing: 3.08px;
}
}
/* block-img-top */
.block-img-top {
position: relative;
z-index: 1;
}
.block-img-top .pattern-left {
height: 52%;
bottom: 5%;
left: -1.5rem;
}
@media screen and (min-width: 768px) {
.block-img-top {
display: none;
}
}
/* block-desc */
.block-desc {
font-size: 1.063rem;
font-weight: 100;
line-height: 28px;
padding-bottom: .98rem;
position: relative;
z-index: 3;
}
.block-desc .pattern-right {
height: 17rem;
top: -2.156rem;
right: -3.5rem;
}
@media screen and (min-width: 576px) {
.block-desc {
max-width: 62.5%;
font-weight: 100;
font-size: 1.1rem;
line-height: 36px;
margin: -18% auto 0;
}
.block-desc .container {
padding: 0;
}
.block-desc .pattern-right {
display: none;
}
}
@media screen and (min-width: 1400px) {
.block-desc {
line-height: 1.9vw;
font-size: 1.4rem;
}
}
My JS:
document.addEventListener("DOMContentLoaded", (event) => {
const welcome = document.querySelector(".welcome");
const logo_head = document.querySelector(".welcome .block-logo");
const kan_logo_head = document.querySelector(".welcome .block-kan");
const welcome_p_left = document.querySelector(".welcome .pattern-left");
const welcome_p_right = document.querySelector(".welcome .pattern-right");
const comming_soon = document.querySelector("ming-soon");
const block_img_top = document.querySelector(".block-img-top");
gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);
// enable only on mobile
if (window.innerWidth < 768) {
/* SWITCH BEETWEEN SECTIONS */
// list Of section
const sections = gsap.utils.toArray([
".welcome",
"ming-soon",
".block-img-top",
".block-desc .paragraph-1",
".block-desc .paragraph-2",
".zones .pool-spa",
".zones .bbq-roof",
".zones .school",
".footer",
]);
let currentIndex = 0; // current index section
let isScrolling = false; // Flag to prevent multiple scrolls
function scrollToSection(index) {
if (isScrolling || index < 0 || index >= sections.length) return;
isScrolling = true;
let targetSection = sections[index];
let offset = 30; // Default top of section
if (index === 1) offset = window.innerHeight / 2 - 30; // For ming-soon the center of the screen
gsap.to(window, {
duration: 1,
scrollTo: { y: targetSection, offsetY: offset },
ease: "sine.out",
onComplete: () => {
isScrolling = false;
currentIndex = index;
// Show the standard scroll bar on the last section only
if (currentIndex === sections.length - 1) {
document.body.classList.add("show-scrollbar");
} else {
document.body.classList.remove("show-scrollbar");
}
},
});
}
let lastScrollTime = 0;
const scrollDelay = 500; // Delay between scrolls in milliseconds
function handleScroll(event) {
const currentTime = new Date().getTime();
if (isScrolling || currentTime - lastScrollTime < scrollDelay) {
return;
}
lastScrollTime = currentTime;
// Override the default scrolling behavior
if (currentIndex !== sections.length - 1) {
event.preventDefault();
}
let scrollAmount = event.deltaY || event.touches?.[0]?.clientY; // Defining the input type
if (Math.abs(scrollAmount) < 15) return; // Filter out movements that are too small
if (scrollAmount > 0 && currentIndex < sections.length - 1) {
// scroll up
scrollToSection(currentIndex + 1);
} else if (scrollAmount < 0 && currentIndex > 0) {
// scroll down
// Check if it is the last section and its top is not at the top of the window
if (currentIndex === sections.length - 1) {
let lastSectionTop =
sections[currentIndex].getBoundingClientRect().top;
if (lastSectionTop < 0) {
// If the top of the last section is not at the top of the window, do not allow scrolling upwards
return;
} else {
event.preventDefault();
document.body.classList.remove("show-scrollbar");
}
}
scrollToSection(currentIndex - 1);
}
}
// Track mouse scroll and touch events
let touchStart = 0;
window.addEventListener("wheel", handleScroll, { passive: false });
window.addEventListener(
"touchstart",
(e) => (touchStart = e.touches[0].clientY)
);
window.addEventListener("touchmove", (e) => {
let touchEnd = e.touches[0].clientY;
let delta = touchStart - touchEnd;
handleScroll({
deltaY: delta,
touches: e.touches,
preventDefault: () => e.preventDefault(),
});
});
// parallax effect for another elements
gsap.to(kan_logo_head, {
y: "-20rem",
x: "20rem",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(logo_head, {
y: "58vh",
opacity: 0,
scale: 1.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(comming_soon, {
marginTop: "-12rem",
duration: 0.3,
ease: "sine.inOut",
scrollTrigger: {
trigger: welcome,
start: "bottom 80%",
end: "bottom 40%",
toggleActions: "play none none reverse",
},
});
gsap.to(welcome_p_right, {
y: "-150vw",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(welcome_p_left, {
y: "206vw",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
}
});
I'm new to JS, especially working with gsap. I want to perform scrolling to certain sections via gsap ScrollTo. I want to make a smooth and not very fast scrolling. I also want to move elements in parallel with scrolling, creating a parallax effect. Maybe someone has encountered such a thing? Or recommend something to replace gsap. Very much need help.
My HTML:
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TEST</title>
<link rel="icon" type="image/x-icon" href="./static/img/favicon-32x32.ico" sizes="32x32">
<link rel="icon" type="image/x-icon" href="./static/img/favicon-192x192.ico"
sizes="192x192">
<link rel="apple-touch-icon" href="./static/img/favicon-192x192.ico">
<link rel="preconnect" href="https://fonts.googleapis">
<link rel="preconnect" href="https://fonts.gstatic" crossorigin>
<link href="https://fonts.googleapis/css2?family=Geologica:[email protected]&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/ScrollToPlugin.min.js"></script>
<link rel="stylesheet" href="./static/css/style.css">
</head>
<body>
<main class="main">
<div class="section-top">
<section class="welcome">
<div class="block-logo animated ">
<img src="./static/img/logo.svg" alt="Logo">
<span>TEXT</span>
</div>
<div class="wrap-block-kan animated ">
<div class="block-kan">
<span>text</span>
<img src="./static/img/logo-kan.svg" alt="">
</div>
</div>
<picture>
<source srcset="./static/img/pattern-left-1-full.png"
media="(min-width: 576px)">
<img src="./static/img/mob/pattern-left-1.png" alt="Pattern"
class="pattern-left animated">
</picture>
<picture>
<source srcset="./static/img/pattern-right-1-full.png"
media="(min-width: 576px)">
<img src="./static/img/mob/pattern-right-1.png" alt="Pattern"
class="pattern-right animated">
</picture>
</section>
<section class="comming-soon">
<div class="container">
<h2 class="block-title animated ">TEXT <span class="text-blue">ТВІЙ</span>
<span class="img-rutm"><img src="./static/img/rutm-text.svg"
alt="Logo rutm"></span>TEXT!
</h2>
<div class="counter animated ">
<div class="element-count day">
<div class="number">07</div>
<span class="num-text">DAYS</span>
</div>
<div class="element-count hour">
<div class="number">11</div>
<span class="num-text">HOUR</span>
</div>
<div class="separator">:</div>
<div class="element-count minute">
<span class="number">01</span>
<span class="num-text">MIN</span>
</div>
<div class="separator gray">:</div>
<div class="element-count second">
<div class="number">02</div>
<span class="num-text">SEC</span>
</div>
</div>
</div>
</section>
<section class="block-img-top">
<img src="./static/img/mob/img-2.webp" alt="Photo kvartal 1"
class="main-block-img">
<img src="./static/img/mob/pattern-left-2.png" alt="Pattern"
class="pattern-left animated">
</section>
<section class="block-desc">
<div class="container">
<p class="animated paragraph-1">
TEXT
</p>
<p class="animated">
TEXT
</p>
<br>
<p class="animated paragraph-2"><strong>«TEXT»</strong> TEXT
</p>
</div>
<img src="./static/img/mob/pattern-right-2.png" alt="Pattern"
class="pattern-right animated">
</section>
</div>
</main>
<script src="./static/js/scripts.js"></script>
</body>
</html>
My code CSS:
body {
font-family: "Geologica", serif;
color: var(--color-font-1);
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
font-size: 16px;
background-color: #000000;
overflow: hidden;
}
@media screen and (min-width: 576px) {
body {
overflow: auto;
}
}
body.show-scrollbar {
overflow-y: scroll;
}
h1,
h2,
h3 {
text-transform: uppercase;
}
h2 {
font-size: 31px;
font-weight: 100;
letter-spacing: 0.1em;
line-height: 36px;
}
h3 {
font-size: 1.563rem;
font-weight: 100;
line-height: 28px;
}
main {
overflow: hidden;
}
.container {
padding: 0 4rem 0 2.125rem;
}
.pattern-left,
.pattern-right {
position: absolute;
}
.section-top {
position: relative;
}
.text-blue {
color: var(--color-blue);
}
.text-yellow {
color: var(--color-yellow);
}
.text-green {
color: var(--color-green);
}
.text-orange {
color: var(--color-orange);
}
.text-red {
color: var(--color-red);
}
/* welcome */
.welcome {
position: relative;
height: calc(100vw* 2.38);
width: auto;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 80%, rgba(0, 0, 0, 0.9) 100%), url("../img/mob/img-1.webp");
background-repeat: no-repeat;
background-origin: content-box;
background-size: cover;
z-index: 2;
}
@media screen and (min-width: 576px) {
.welcome {
height: calc(100vw* 1.43);
background-image: url("../img/img-1-full.webp");
}
}
.welcome .wrap-block-kan {
display: flex;
justify-content: right;
padding-top: 2.875rem;
padding-right: 12%;
}
.welcome .block-kan {
position: relative;
}
.welcome .block-kan img {
width: 5.25rem;
}
.welcome .block-kan span {
position: absolute;
top: 0.625em;
left: -0.75em;
font-size: 0.7em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 1px;
}
.welcome .pattern-left {
width: 18.67%;
left: -4.8vw;
top: 22vw;
}
.welcome .pattern-right {
width: 25vw;
top: 135vw;
right: -14%;
}
.block-logo {
padding-top: 2.5rem;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
opacity: 1;
transition: opacity .8s ease, scale 1s ease, transform .01s ease;
}
.block-logo img {
margin-bottom: 0.75em;
max-width: 53%;
}
.block-logo span {
font-size: .7em;
font-weight: 300;
letter-spacing: 4px;
text-transform: uppercase;
}
@media screen and (min-width: 576px) {
.welcome .block-logo img {
margin-bottom: .8em;
max-width: 25%;
}
.welcome .block-logo span {
font-size: .6em;
}
.welcome .pattern-left {
width: 10.55vw;
left: 0;
top: 62.5vw;
}
.welcome .pattern-right {
width: 6.72vw;
right: 0;
top: 18.92vw;
}
}
@media screen and (min-width: 768px) {
.welcome .block-logo img {
margin-bottom: 1.1em;
}
.welcome .block-logo span {
font-size: .7em;
letter-spacing: 5px;
}
.welcome .wrap-block-kan {
padding-top: 2.375rem;
padding-right: 27%;
}
}
@media screen and (min-width: 992px) {
.welcome .block-logo span {
font-size: .9em;
letter-spacing: 6px;
}
.welcome .wrap-block-kan {
padding-right: 29%;
}
}
@media screen and (min-width: 1200px) {
.welcome .block-logo span {
font-size: 1.1vw;
letter-spacing: 8px;
}
.welcome .wrap-block-kan {
padding-right: 31vw;
}
}
@media screen and (min-width: 1400px) {
.welcome .block-logo {
padding-top: 3.75vw;
}
.welcome .block-logo img {
margin-bottom: 1.4em;
}
.welcome .block-logo span {
font-size: 1.3vw;
}
.welcome .wrap-block-kan {
padding-top: 2.9vw;
padding-right: 30.1vw;
}
.welcome .block-kan img {
width: 7vw;
}
.welcome .block-kan span {
font-size: .9vw;
}
}
/* comming-soon */
ming-soon {
position: relative;
margin-top: -4.125rem;
margin-bottom: -1.25rem;
z-index: 2;
}
ming-soon .container {
padding: 0 1.65rem;
}
ming-soon .block-title {
margin-bottom: 2rem;
padding: 0 1.875rem 0 .25rem;
position: relative;
z-index: 1;
}
ming-soon .block-title .img-rutm {
display: inline-block;
width: 8rem;
margin-right: .5em;
margin-left: .1em;
}
@media screen and (min-width: 768px) {
ming-soon {
position: absolute;
top: 20rem;
right: 8%;
max-width: 40%;
}
ming-soon .container {
padding: 0;
}
ming-soon .block-title {
margin-bottom: 1rem;
padding: 0;
font-size: 1.2rem;
}
ming-soon .block-title .img-rutm {
width: 25%;
margin-bottom: -2px;
}
}
@media screen and (min-width: 992px) {
ming-soon {
top: 23rem;
right: 10%;
max-width: 37%;
}
ming-soon .block-title {
font-size: 1.45rem;
margin-bottom: 1.5rem;
}
}
@media screen and (min-width: 1200px) {
ming-soon {
right: 17%;
max-width: 30%;
}
}
@media screen and (min-width: 1400px) {
ming-soon {
top: 29vw;
right: 18%;
max-width: 29%;
}
ming-soon .block-title {
font-size: 1.875vw;
line-height: 120%;
}
ming-soon .block-title .img-rutm {
width: 27%;
margin-bottom: -1px;
}
}
/* counter */
.counter {
display: flex;
justify-content: space-between;
text-align: center;
font-size: 3.313rem;
}
.counter .element-count {
display: flex;
flex-direction: column;
min-width: 22%;
}
.counter .element-count.day {
min-width: auto;
}
.main .counter .element-count.day {
margin-right: 14px;
}
.counter .second .number,
.counter .separator.gray {
color: var(--color-gray);
}
.counter .separator.gray {
padding-left: 5px;
}
@media screen and (min-width: 768px) {
.counter .second .number,
.counter .separator.gray {
color: var(--color-white);
opacity: .5;
}
}
.counter .number {
letter-spacing: 1.32px;
}
.counter .separator {
margin-top: -4px;
margin-left: -5px;
}
.counter .num-text {
color: var(--color-gray);
font-size: 6px;
letter-spacing: 0.18px;
font-weight: 100;
}
@media screen and (min-width: 576px) {
.main .counter {
width: 100%;
}
.counter .number {
font-size: 4rem;
letter-spacing: 1.4px;
}
.counter .num-text {
font-size: 7px;
letter-spacing: 0.25px;
color: var(--color-white);
opacity: 0.6;
}
.counter .separator {
margin-left: -5px;
}
}
@media screen and (min-width: 768px) {
.counter .number {
font-size: 3.5rem;
letter-spacing: 1.62px;
}
.counter .num-text {
font-size: .5rem;
letter-spacing: 0.35px;
}
}
@media screen and (min-width: 992px) {
.counter .separator {
margin-top: 0;
}
}
@media screen and (min-width: 1400px) {
.main .counter {
font-size: 3.8vw;
}
.counter .num-text {
font-size: 0.7rem;
letter-spacing: 0.45px;
}
.counter .number {
font-size: 4.4vw;
letter-spacing: 3.08px;
}
}
/* block-img-top */
.block-img-top {
position: relative;
z-index: 1;
}
.block-img-top .pattern-left {
height: 52%;
bottom: 5%;
left: -1.5rem;
}
@media screen and (min-width: 768px) {
.block-img-top {
display: none;
}
}
/* block-desc */
.block-desc {
font-size: 1.063rem;
font-weight: 100;
line-height: 28px;
padding-bottom: .98rem;
position: relative;
z-index: 3;
}
.block-desc .pattern-right {
height: 17rem;
top: -2.156rem;
right: -3.5rem;
}
@media screen and (min-width: 576px) {
.block-desc {
max-width: 62.5%;
font-weight: 100;
font-size: 1.1rem;
line-height: 36px;
margin: -18% auto 0;
}
.block-desc .container {
padding: 0;
}
.block-desc .pattern-right {
display: none;
}
}
@media screen and (min-width: 1400px) {
.block-desc {
line-height: 1.9vw;
font-size: 1.4rem;
}
}
My JS:
document.addEventListener("DOMContentLoaded", (event) => {
const welcome = document.querySelector(".welcome");
const logo_head = document.querySelector(".welcome .block-logo");
const kan_logo_head = document.querySelector(".welcome .block-kan");
const welcome_p_left = document.querySelector(".welcome .pattern-left");
const welcome_p_right = document.querySelector(".welcome .pattern-right");
const comming_soon = document.querySelector("ming-soon");
const block_img_top = document.querySelector(".block-img-top");
gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);
// enable only on mobile
if (window.innerWidth < 768) {
/* SWITCH BEETWEEN SECTIONS */
// list Of section
const sections = gsap.utils.toArray([
".welcome",
"ming-soon",
".block-img-top",
".block-desc .paragraph-1",
".block-desc .paragraph-2",
".zones .pool-spa",
".zones .bbq-roof",
".zones .school",
".footer",
]);
let currentIndex = 0; // current index section
let isScrolling = false; // Flag to prevent multiple scrolls
function scrollToSection(index) {
if (isScrolling || index < 0 || index >= sections.length) return;
isScrolling = true;
let targetSection = sections[index];
let offset = 30; // Default top of section
if (index === 1) offset = window.innerHeight / 2 - 30; // For ming-soon the center of the screen
gsap.to(window, {
duration: 1,
scrollTo: { y: targetSection, offsetY: offset },
ease: "sine.out",
onComplete: () => {
isScrolling = false;
currentIndex = index;
// Show the standard scroll bar on the last section only
if (currentIndex === sections.length - 1) {
document.body.classList.add("show-scrollbar");
} else {
document.body.classList.remove("show-scrollbar");
}
},
});
}
let lastScrollTime = 0;
const scrollDelay = 500; // Delay between scrolls in milliseconds
function handleScroll(event) {
const currentTime = new Date().getTime();
if (isScrolling || currentTime - lastScrollTime < scrollDelay) {
return;
}
lastScrollTime = currentTime;
// Override the default scrolling behavior
if (currentIndex !== sections.length - 1) {
event.preventDefault();
}
let scrollAmount = event.deltaY || event.touches?.[0]?.clientY; // Defining the input type
if (Math.abs(scrollAmount) < 15) return; // Filter out movements that are too small
if (scrollAmount > 0 && currentIndex < sections.length - 1) {
// scroll up
scrollToSection(currentIndex + 1);
} else if (scrollAmount < 0 && currentIndex > 0) {
// scroll down
// Check if it is the last section and its top is not at the top of the window
if (currentIndex === sections.length - 1) {
let lastSectionTop =
sections[currentIndex].getBoundingClientRect().top;
if (lastSectionTop < 0) {
// If the top of the last section is not at the top of the window, do not allow scrolling upwards
return;
} else {
event.preventDefault();
document.body.classList.remove("show-scrollbar");
}
}
scrollToSection(currentIndex - 1);
}
}
// Track mouse scroll and touch events
let touchStart = 0;
window.addEventListener("wheel", handleScroll, { passive: false });
window.addEventListener(
"touchstart",
(e) => (touchStart = e.touches[0].clientY)
);
window.addEventListener("touchmove", (e) => {
let touchEnd = e.touches[0].clientY;
let delta = touchStart - touchEnd;
handleScroll({
deltaY: delta,
touches: e.touches,
preventDefault: () => e.preventDefault(),
});
});
// parallax effect for another elements
gsap.to(kan_logo_head, {
y: "-20rem",
x: "20rem",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(logo_head, {
y: "58vh",
opacity: 0,
scale: 1.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(comming_soon, {
marginTop: "-12rem",
duration: 0.3,
ease: "sine.inOut",
scrollTrigger: {
trigger: welcome,
start: "bottom 80%",
end: "bottom 40%",
toggleActions: "play none none reverse",
},
});
gsap.to(welcome_p_right, {
y: "-150vw",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
gsap.to(welcome_p_left, {
y: "206vw",
duration: 0.5,
ease: "sine.inOut",
scrollTrigger: {
trigger: comming_soon,
start: "top bottom",
end: "bottom top",
toggleActions: "play none none reverse",
},
});
}
});
Share
Improve this question
asked Mar 3 at 12:13
Яша ПроценкоЯша Проценко
731 silver badge7 bronze badges
1 Answer
Reset to default 1The problem was that I had set a CSS property that caused conflicts. It was written in the documentation:
html {
scroll-behavior: smooth
}