-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
100 lines (87 loc) · 2.69 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { gsap } from 'https://cdn.skypack.dev/gsap';
const TRANSITION_DURATION = 0.8; // slide transition time in seconds
const PARALLAX_AMOUNT = 35; // percentage parallax overlap
class Slideshow {
constructor(slider) {
// Initialize DOM elements
this.slider = slider;
this.slides = Array.from(this.slider.querySelectorAll('.slide'));
this.slidesInner = this.slides.map((item) => item.querySelector('img'));
this.current = 0;
this.slidesTotal = this.slides.length;
this.isAnimating = false;
// Set initial states
this.slides[this.current].classList.add('is-current');
}
navigate(direction) {
// Exit is an animation is already in progress
if (this.isAnimating) return false;
this.isAnimating = true;
// Save current slide index
const previous = this.current;
// Update the current slide index based on direction
if (direction === 1) {
if (this.current < this.slidesTotal - 1) {
this.current += 1;
} else {
// If the last slide, wrap around to the first slide
this.current = 0;
}
} else {
if (this.current > 0) {
this.current -= 1;
} else {
// If the first slide, wrap around to the last slide
this.current = this.slidesTotal - 1;
}
}
this.animate(previous, this.current, direction);
}
animate(current, upcoming, direction) {
const currentSlide = this.slides[current];
const currentInner = this.slidesInner[current];
const upcomingSlide = this.slides[upcoming];
gsap
.timeline({
defaults: {
duration: TRANSITION_DURATION,
ease: 'power4.inOut',
},
onStart: () => {
upcomingSlide.classList.add('is-current');
gsap.set(upcomingSlide, { zIndex: 1 });
},
onComplete: () => {
currentSlide.classList.remove('is-current');
gsap.set(currentSlide, { xPercent: 0 });
gsap.set(currentInner, { xPercent: 0 });
gsap.set(upcomingSlide, { zIndex: 'auto' });
this.isAnimating = false;
},
})
.to(currentSlide, {
xPercent: -direction * 100,
})
.to(
currentInner,
{
xPercent: direction * PARALLAX_AMOUNT,
},
'<'
)
.fromTo(
upcomingSlide,
{
xPercent: direction * 100,
},
{
xPercent: 0,
},
'<'
);
}
}
const slider = document.querySelector('.slider');
const slideshow = new Slideshow(slider);
document.querySelector('.is-prev').addEventListener('click', () => slideshow.navigate(-1));
document.querySelector('.is-next').addEventListener('click', () => slideshow.navigate(1));