我有一个使用 nuxt /vue 和 gsap / scrolltrigger 的水平轮播滑块。一切都按预期工作,但是当我尝试使用导航控制滑块时,它非常笨拙。它没有滑动到正确的面板,不确定我在哪里犯了错误,但如果有人有任何想法,我将不胜感激!
https://codepen.io/mDDDD/pen/QWvqVzV
<div class="grand-carousel-container" id="pinInnovationCarousel">
<div class="container__timeline">
<div class="timeline-nav">
<ul class="timeline-nav__list">
<li class="is-active timeline-nav__list-item">Slide One</li>
<li class="timeline-nav__list-item">Slide Two</li>
<li class="timeline-nav__list-item">Slide Three</li>
</ul>
</div>
<div class="timeline-slides">
<div class="slide">
Slide One
</div>
<div class="slide">
Slide Two
</div>
<div class="slide">
Slide Three
</div>
</div>
</div>
</div>
.container__timeline,
.grand-carousel-panel {
overflow: hidden;
width: 100%;
max-width: 1250px;
}
.container__timeline {
position: relative;
}
.timeline-nav {
display: flex;
justify-content: flex-end;
max-width: 100px;
}
.timeline-nav__list {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
min-height: 175px;
cursor: pointer;
}
.timeline-nav__list-item {
position: relative;
margin-right: 15px;
padding-bottom: 20px;
&:after {
position: absolute;
top: 0;
right: 0;
width: 5px;
height: 55px;
content: '';
border-radius: 5px;
background-color: grey;
}
&.is-active {
position: relative;
color: green;
&::after {
position: absolute;
z-index: 1;
top: 0;
right: 0px;
width: 5px;
height: 55px;
content: '';
border-radius: 5px;
background-color: green;
}
}
}
.slide {
display: flex;
align-items: flex-end;
flex: 1 0 auto;
width: 100vw;
}
.timeline-slides {
display: flex;
justify-content: space-between;
width: 100vw;
}
.slide:nth-child(1){
background-color: lightblue;
}
.slide:nth-child(2){
background-color: black;
color: white;
}
.slide:nth-child(3){
background-color: purple;
color: white;
}
const sections = gsap.utils.toArray('.slide');
const numSections = sections.length - 1;
const snapVal = 1 / numSections;
let lastIndex = 0;
const navList = document.querySelectorAll('.timeline-nav__list-item');
gsap.to(sections, {
xPercent: -100 * numSections,
ease: 'none',
scrollTrigger: {
id: 'innovationPin',
scrub: true,
snap: snapVal,
trigger: '#pinInnovationCarousel',
pin: true,
start: 'top top',
end: () => '+=' + innerWidth * sections.length,
onUpdate: (self) => {
const newIndex = Math.round(self.progress / snapVal);
if (newIndex !== lastIndex) {
navList[lastIndex].classList.remove('is-active');
navList[newIndex].classList.add('is-active');
lastIndex = newIndex;
}
},
},
});
navList.forEach((a, i) => {
a.addEventListener('click', (e) => {
e.preventDefault();
gsap.to(window, {
scrollTo: {
y: i * innerWidth,
},
});
});
});