Anonymous
Прыжки и лаги при переключении между секциями (GSAP Scrolltrigger)
Сообщение
Anonymous » 11 мар 2025, 17:47
Я новичок в Frontend и начал использовать GSAP для анимации. Я использую GSAP в основном для переключения между секциями. На экранах более 576px у меня есть проблема: при переключении между разделами появляются прыжки, и они исчезают через некоторое время, если вы прокручиваете вверх и вниз по странице. Может, кто -то столкнулся с этим? Свойства: < /p>
transform: translate3d (0,0,0,);
will-change: transform;
Backface-visibuity: Hidden; < /p>
< /li>
Свойство-Sine, Power1, Power2. < /p>
< /li>
Удаление лагов и прыжков на больших экранах исчезает. На нормальных ноутбуках все отображается обычно. Размеры других изображений для фона: 2560 x 3658 и 2560 x 1534 пикселей. Все они установлены через CSS как BackGroud. < /P>
< /li>
Я уже изменил все большие изображения для фона, и он все еще отстает и прыгает при прокрутке. < /P>
< /li>
< /ol>
. Идеально с GSAP. < /p>
Я попытался воссоздать минимальную демонстрацию проекта.
Прыжки и лаги при переключении на разные разделы.
Код: Выделить всё
/* 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 = 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(),
});
});
}
}
});< /code>
/* 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("https://www.dropbox.com/scl/fi/xkeyr55fuxfa8u07var71/img-1.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("https://www.dropbox.com/scl/fi/456qcczsc1tbnv6545orj/img-1-full.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('https://www.dropbox.com/scl/fi/74y2j170jouiswn1s6kaq/img-3-full.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("https://www.dropbox.com/scl/fi/exou5etr6u99zrcvnp71t/img-3.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("https://www.dropbox.com/scl/fi/ol5phxaganv7ep2rzw1me/img-2-full.webp?rlkey=og6pxmowaqikv2mi7cn9sbfek&st=l0y92ly5&raw=1");
background-repeat: no-repeat;
background-size: cover;
margin-top: 0;
z-index: -1;
}
}< /code>
БіоРитм
Це саме те, на що Ви чекали… Все, що ви любите, що робить життя комфортним і натхненним, тепер
поєднано в одному місці. Вишуканий рівень, продумані до дрібниць планування, сміливі
архітектурні рішення та інфраструктура, що підлаштовується під ваш ритм.
Твої басейни та спа зона на вершині
міста
[img]https://www.dropbox.com/scl/fi/cqptfkzfrg3ntvxppjtyu/pool-spa.webp?rlkey=yggqes2hnw4a2fyef9vfvjtqm&st=ecgrbs7m&raw=1[/img]
class="main-img animated-element">
Твій фітнес на краю неба
[img]https://www.dropbox.com/scl/fi/5ygtfda1ud0p24e1xu1im/fitness-roof.webp?rlkey=wusxpb632d62vzx4d5c8alsrl&st=3riucaiz&raw=1[/img]
class="main-img animated-element">
Подробнее здесь:
https://stackoverflow.com/questions/794 ... olltrigger
1741704453
Anonymous
Я новичок в Frontend и начал использовать GSAP для анимации. Я использую GSAP в основном для переключения между секциями. На экранах более 576px у меня есть проблема: при переключении между разделами появляются прыжки, и они исчезают через некоторое время, если вы прокручиваете вверх и вниз по странице. Может, кто -то столкнулся с этим? Свойства: < /p> transform: translate3d (0,0,0,); will-change: transform; Backface-visibuity: Hidden; < /p> < /li> Свойство-Sine, Power1, Power2. < /p> < /li> Удаление лагов и прыжков на больших экранах исчезает. На нормальных ноутбуках все отображается обычно. Размеры других изображений для фона: 2560 x 3658 и 2560 x 1534 пикселей. Все они установлены через CSS как BackGroud. < /P> < /li> Я уже изменил все большие изображения для фона, и он все еще отстает и прыгает при прокрутке. < /P> < /li> < /ol> . Идеально с GSAP. < /p> Я попытался воссоздать минимальную демонстрацию проекта. Прыжки и лаги при переключении на разные разделы.[code]/* 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 = 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(), }); }); } } });< /code> /* 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("https://www.dropbox.com/scl/fi/xkeyr55fuxfa8u07var71/img-1.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("https://www.dropbox.com/scl/fi/456qcczsc1tbnv6545orj/img-1-full.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('https://www.dropbox.com/scl/fi/74y2j170jouiswn1s6kaq/img-3-full.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("https://www.dropbox.com/scl/fi/exou5etr6u99zrcvnp71t/img-3.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("https://www.dropbox.com/scl/fi/ol5phxaganv7ep2rzw1me/img-2-full.webp?rlkey=og6pxmowaqikv2mi7cn9sbfek&st=l0y92ly5&raw=1"); background-repeat: no-repeat; background-size: cover; margin-top: 0; z-index: -1; } }< /code> БіоРитм Це саме те, на що Ви чекали… Все, що ви любите, що робить життя комфортним і натхненним, тепер поєднано в одному місці. Вишуканий рівень, продумані до дрібниць планування, сміливі архітектурні рішення та інфраструктура, що підлаштовується під ваш ритм. Твої басейни та спа зона на вершині міста [img]https://www.dropbox.com/scl/fi/cqptfkzfrg3ntvxppjtyu/pool-spa.webp?rlkey=yggqes2hnw4a2fyef9vfvjtqm&st=ecgrbs7m&raw=1[/img] class="main-img animated-element"> Твій фітнес на краю неба [img]https://www.dropbox.com/scl/fi/5ygtfda1ud0p24e1xu1im/fitness-roof.webp?rlkey=wusxpb632d62vzx4d5c8alsrl&st=3riucaiz&raw=1[/img] class="main-img animated-element"> [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79498333/jumps-and-lags-when-switching-between-sections-gsap-scrolltrigger[/url]