I am new to frontend and have started using gsap for animations. I use gsap mainly for switching between sections. On screens larger than 576px I have a problem: when switching between sections there are jumps and they disappear after a while if you scroll up and down the page. Maybe someone has encountered this ? I don't seem to have a lot of animations so far, but already so laggy.
Here's what I tried to do:
Remove all possible negative margins.
Add to all elements to which the transition is made, properties:
transform: translate3d(0,0,0,); will-change: transform; backface-visibility: hidden;
Set property ease - sine, power1, power2.
've noticed that by removing the lags and jumps on large screens disappear. On normal laptops everything is displayed normally.
As soon as I return the element, everything starts lagging again. The resolution of the image used is 2560 x 3072 pixels and the size is 272kb. The sizes of the other images for the background are: 2560 x 3658 and 2560 x 1534 pixels. All of them are set via css as backgroud.
I've already resized all the large images for the background and it still lags and jumps when scrolling.
All this had no effect.
In the mobile version I have a lot of animation that works perfectly with gsap.
I tried to recreate a minimal demonstration of the project. The jumps and lags when switching to different sections remain.
/* FORM HANDLER */
// Disable automatic scroll recovery
window.history.scrollRestoration = "manual";
// Force a scroll to the beginning of the page
window.scrollTo(0, 0);
// PARALLAX
document.addEventListener("DOMContentLoaded", () => {
const welcome = document.querySelector(".welcome");
const block_desc = document.querySelector(".block-desc");
const zones = document.querySelector(".zones");
const pool = document.querySelector(".zones .pool-spa");
const fitness = document.querySelector(".zones .fitness-roof");
gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);
let currentIndex = 0; // Current section index
let isScrolling = false; // Flag to prevent multiple scrolls
let footerReachedTopOnce = false; // Flag that is turned on after the top of the footer is reached for the first time
const window_width = window.innerWidth;
// ENABLE ONLY ON MOBILE
if (window_width < 576) {
} else {
// ENABLE ON DEVICE WITH WINDOW WIDTH >= 576px
// List of sections tables to be switched
const sections_tb = gsap.utils.toArray([
".welcome",
".zones .pool-spa",
".zones .fitness-roof",
".block-img-bottom",
]);
// List of sections PC to be switched
const sections_pc = gsap.utils.toArray([
".welcome",
".block-desc",
".zones .pool-spa",
".zones .fitness-roof",
".block-img-bottom",
]);
/* TABLET <1200px */
if (window_width < 1200) {
const duration_main = 1.8; // Duration of animation of transitions between sections
/* Parallax for bg of zones */
gsap.to(".zones .zones-bg", {
y: "80%", // Параллакс-эффект
ease: "power1.inOut",
scrollTrigger: {
trigger: ".zones",
start: "top top",
end: "bottom bottom",
scrub: true,
},
});
function scrollToSectionTB(index) {
if (isScrolling || index < 0 || index >= sections_tb.length) return;
isScrolling = true;
let targetSection = sections_tb[index];
let offset = 60; // По умолчанию смещение составляет 60px от верха секции
// set offset for different section or execution prevent action before change section
switch (index) {
case 1: //
break;
case 3: //
break;
case 7: //
break;
}
// change section
gsap.to(window, {
duration: duration_main,
scrollTo: { y: targetSection, offsetY: offset},
ease: "power1.inOut",
onStart: () => updateClassesTB(index),
onComplete: () => {
isScrolling = false;
currentIndex = index;
},
});
}
function updateClassesTB(index) {
// Display logo of head on all sections_tb but not on welcome
}
// Page reloading fix with saving last section
window.history.scrollRestoration = "manual";
window.addEventListener("load", () => {
let savedIndex = sessionStorage.getItem("currentSection") || 0;
setTimeout(() => {
ScrollTrigger.refresh();
scrollToSectionTB(parseInt(savedIndex, 10));
}, 500);
});
window.addEventListener("beforeunload", () => {
sessionStorage.setItem("currentSection", currentIndex);
});
/* ONLY PC >=1200px*/
} else {
/* Parallax for bg of zones */
gsap.to(".zones .zones-bg", {
y: "50vw", // Параллакс-эффект
ease: "none",
scrollTrigger: {
trigger: ".zones",
start: "top top",
end: "bottom bottom",
scrub: true,
},
});
function scrollToSectionPC(index) {
if (isScrolling || index < 0 || index >= sections_pc.length) return;
let duration_main = 1.8; // Duration of animation of transitions between sections
if (
(currentIndex === 1 && index === 0) ||
(currentIndex === 0 && index === 1)
) {
duration_main = 2.2;
}
isScrolling = true;
let targetSection = sections_pc[index];
let offset = 0; // По умолчанию смещение составляет 30px от верха секции
const height_section = sections_pc[index].offsetHeight / 2;
let offset_center = window.innerHeight / 2 - height_section;
offset = offset_center;
// change section
gsap.to(window, {
duration: duration_main,
scrollTo: { y: targetSection, offsetY: offset},
ease: "power1.inOut",
onStart: () => updateClassesPC(index),
onComplete: () => {
isScrolling = false;
currentIndex = index;
},
});
}
function updateClassesPC(index) {
switch (index) {
case 0: // welcome
welcome.classList.remove("animate");
break;
case 1: // .block-desc
welcome.classList.add("animate");
break;
case 2: //
welcome.classList.add("animate");
break;
}
}
// Page reloading fix with saving last section
window.history.scrollRestoration = "manual";
window.addEventListener("load", () => {
let savedIndex = sessionStorage.getItem("currentSection") || 0;
setTimeout(() => {
ScrollTrigger.refresh();
scrollToSectionPC(parseInt(savedIndex, 10));
}, 500);
});
window.addEventListener("beforeunload", () => {
sessionStorage.setItem("currentSection", currentIndex);
});
}
let touchStart = 0;
let scrollToSection =
window_width < 1200 ? scrollToSectionTB : scrollToSectionPC;
const sections = window_width < 1200 ? sections_tb : sections_pc;
/* HANDLE SCROLL ON TABLET AND PC */
function handleScrollTabletPC(event) {
if (isScrolling) {
return;
}
let scrollAmount = event.deltaY || event.touches?.[0]?.clientY; // Define input type
if (Math.abs(scrollAmount) < 20) return; // Filter out movements that are too small
if (scrollAmount > 0 && currentIndex < sections.length - 1) {
// scroll down
scrollToSection(currentIndex + 1);
} else if (scrollAmount < 0 && currentIndex > 0) {
// scroll up
scrollToSection(currentIndex - 1);
}
}
/* GLOBAL SCROLL FOR ALL SECTIONS FOR TABLET AND PC*/
/* Handler scroll on PC */
if (window_width >= 1200) {
window.addEventListener("wheel", handleScrollTabletPC, {
passive: false,
});
}
/* Handler scroll and swipe on tablet */
if (window_width < 1200) {
window.addEventListener("wheel", handleScrollTabletPC, {
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;
handleScrollTabletPC({
deltaY: delta,
touches: e.touches,
preventDefault: () => e.preventDefault(),
});
});
}
}
});
/* RESET */
/* 2. Remove default margin */
* {
margin: 0;
}
body {
font-family: "Geologica", serif;
color: white;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
font-size: 16px;
background-color: #000000;
overflow: hidden;
height: 100%;
}
main {
overflow: hidden;
}
.container {
padding: 0 4rem 0 2.125rem;
}
.section-top {
position: relative;
z-index: 1;
}
@media screen and (min-width: 1200px) {
.section-top {
padding-bottom: 10rem;
}
}
/* 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(".webp?rlkey=7f8r2t5cdqhcxw0a0eji9z862&st=ema78f0y&raw=1");
background-repeat: no-repeat;
background-origin: content-box;
background-size: 105%;
z-index: 2;
}
@media screen and (min-width: 576px) {
.welcome {
height: calc(100vw* 1.43);
background-image: url(".webp?rlkey=nvvhv52h9fx9h4m2e7epra1q3&st=pn7vfzw3&raw=1");
}
}
@media screen and (min-width: 576px) {
.welcome {
transition: transform 1s linear 0.2s;
will-change: transform;
}
.welcome.animate {
transform: scale(108%);
}
/* block-desc */
.block-desc {
font-size: 1.063rem;
font-weight: 100;
line-height: 28px;
padding-bottom: .98rem;
position: relative;
z-index: 3;
}
@media screen and (min-width: 576px) {
.block-desc {
font-weight: 100;
font-size: .9rem;
line-height: 26px;
display: flex;
justify-content: center;
margin-top: -50vh;
background-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 40%, rgba(0, 0, 0, 0) 100%);
background-size: cover;
will-change: transform;
z-index: 3;
}
.block-desc .container {
max-width: 75%;
padding: 0 5rem 0 0;
}
}
@media screen and (min-width: 992px) {
.block-desc {
font-size: 1rem;
line-height: 28px;
margin-top: -35vh;
}
}
@media screen and (min-width: 1200px) {
.block-desc {
display: flex;
justify-content: center;
margin-top: -40vh;
}
.block-desc .container {
padding: 0 10rem 0 0;
}
}
@media screen and (min-width: 1400px) {
.block-desc {
line-height: 1.9vw;
font-size: 1.4rem;
margin-top: -45vh;
}
.block-desc .container {
max-width: 80%;
padding: 0 20rem 0 0;
}
}
/* ZONES */
.zones {
position: relative;
z-index: 2;
}
.zones .zones-bg {
display: none;
}
.zones .container {
padding: 0;
}
.zones article {
margin-top: 2.5rem;
padding-left: 2.5rem;
position: relative;
}
.zones article:nth-child(even) {
text-align: right;
padding-left: 0;
padding-right: 2.5rem;
}
@media screen and (min-width: 576px) {
.zones {
overflow: hidden;
position: relative;
margin-top: 5rem;
margin-bottom: -3rem;
z-index: 0;
}
.zones .zones-bg {
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100vw* 1.2);
background-image: url('.webp?rlkey=ihans0tn7dlm4v4c2lrhnyfa0&st=jl91itao&raw=1');
background-repeat: no-repeat;
background-size: cover;
will-change: transform;
}
.zones article {
margin-top: 8rem;
will-change: transform;
}
}
@media screen and (min-width: 1400px) {
.zones {
margin-top: 0;
}
}
/* block-img-bottom */
.block-img-bottom {
height: calc(100vw* 1.6);
width: auto;
background-image: url(".webp?rlkey=nphbrwu55p1sv02583ms08hy9&st=93xi3n4p&raw=1");
background-repeat: no-repeat;
background-size: cover;
position: relative;
z-index: 1;
margin-top: -15rem;
}
@media screen and (min-width: 576px) {
.block-img-bottom {
height: calc(100vw* 0.6);
background-image: url(".webp?rlkey=og6pxmowaqikv2mi7cn9sbfek&st=l0y92ly5&raw=1");
background-repeat: no-repeat;
background-size: cover;
margin-top: 0;
z-index: -1;
}
}
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>БіоРитм</title>
<meta property="og:title" content="БіоРитм">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ url_for('main.index', _external=True) }}">
<meta property="og:image" content="{{ url_for('static', filename='img/mob/img-1.webp') }}">
<meta property="og:description" content="Незабаром ми змінимо ритм життя">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='img/favicon-32x32.ico') }}" sizes="32x32">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='img/favicon-192x192.ico') }}"
sizes="192x192">
<link rel="apple-touch-icon" href="{{ url_for('static', filename='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>
</head>
<body>
<main class="main">
<div class="section-top">
<section class="welcome">
</section>
<section class="block-desc animated-element">
<div class="container">
<p>
Це саме те, на що Ви чекали… Все, що ви любите, що робить життя комфортним і натхненним, тепер
поєднано в одному місці. Вишуканий рівень, продумані до дрібниць планування, сміливі
архітектурні рішення та інфраструктура, що підлаштовується під ваш ритм.
</p>
</div>
</section>
</div>
<section class="zones">
<div class="zones-bg"></div>
<div class="container">
<article class="pool-spa">
<div class="inside-wrap-article">
<h3 class="animated-element"><span class="text-blue">Твої</span> басейни та спа зона на вершині
міста</h3>
<picture>
<source srcset=".webp?rlkey=64jm9dqxgoovi10b69p2crcn3&st=yi025a75&raw=1"
media="(min-width: 576px)">
<img src=".webp?rlkey=yggqes2hnw4a2fyef9vfvjtqm&st=ecgrbs7m&raw=1" alt="Spa and poll"
class="main-img animated-element">
</picture>
</div>
</article>
<article class="fitness-roof">
<div class="inside-wrap-article">
<h3 class="animated-element"><span class="text-yellow">Твій</span> фітнес на краю неба</h3>
<picture>
<source srcset=".webp?rlkey=1dchmn44wfa862stpv64x71yg&st=mbsrfqx2&raw=1"
media="(min-width: 576px)">
<img src=".webp?rlkey=wusxpb632d62vzx4d5c8alsrl&st=3riucaiz&raw=1" alt="Fitness roof"
class="main-img animated-element">
</picture>
</div>
</article>
</div>
</section>
<section class="block-img-bottom">
</section>
</main>
</body>
</html>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744840808a4596545.html
评论列表(0条)