@@ -9,21 +9,26 @@ function init() {
9
9
] ;
10
10
let current = 0 ;
11
11
let scrollSlide = 0 ;
12
+ let isAnimating = false ;
13
+
14
+ function updateActiveDot ( index ) {
15
+ slides . forEach ( ( slide ) => slide . classList . remove ( "active" ) ) ;
16
+ slides [ index ] . classList . add ( "active" ) ;
17
+ }
12
18
13
19
slides . forEach ( ( slide , index ) => {
14
20
slide . addEventListener ( "click" , function ( ) {
15
- changeDots ( this ) ;
21
+ if ( isAnimating ) return ;
22
+ updateActiveDot ( index ) ;
16
23
nextSlide ( index ) ;
17
24
scrollSlide = index ;
18
25
} ) ;
19
26
} ) ;
20
27
21
- function changeDots ( dot ) {
22
- slides . forEach ( ( slide ) => slide . classList . remove ( "active" ) ) ;
23
- dot . classList . add ( "active" ) ;
24
- }
28
+ async function nextSlide ( pageNumber ) {
29
+ if ( isAnimating || pageNumber === current ) return ;
30
+ isAnimating = true ;
25
31
26
- function nextSlide ( pageNumber ) {
27
32
const nextPage = pages [ pageNumber ] ;
28
33
const currentPage = pages [ current ] ;
29
34
const nextLeft = nextPage . querySelector ( ".hero .model-left" ) ;
@@ -33,81 +38,84 @@ function init() {
33
38
const nextText = nextPage . querySelector ( ".details" ) ;
34
39
const portfolio = document . querySelector ( ".portfolio" ) ;
35
40
36
- const tl = new TimelineMax ( {
37
- // disable clicks during animations
38
- onStart : function ( ) {
39
- slides . forEach ( ( slide ) => ( slide . style . pointerEvents = "none" ) ) ;
40
- } ,
41
- onComplete : function ( ) {
42
- slides . forEach ( ( slide ) => ( slide . style . pointerEvents = "all" ) ) ;
43
- } ,
44
- } ) ;
45
-
46
- tl . fromTo ( currentLeft , 0.3 , { y : "-10%" } , { y : "-100%" } )
47
- . fromTo ( currentRight , 0.3 , { y : "10%" } , { y : "-100%" } , "-=0.2" )
48
- . to ( portfolio , 0.3 , { backgroundImage : backgrounds [ pageNumber ] } )
41
+ const tl = gsap . timeline ( { } ) ;
42
+ tl . fromTo ( currentLeft , { y : "-10%" } , { duration : 0.3 , y : "-100%" } )
43
+ . fromTo (
44
+ currentRight ,
45
+ { y : "10%" } ,
46
+ { duration : 0.3 , y : "-100%" } ,
47
+ "-=0.2"
48
+ )
49
+ . to ( portfolio , {
50
+ duration : 0.3 ,
51
+ backgroundImage : backgrounds [ pageNumber ] ,
52
+ } )
49
53
. fromTo (
50
54
currentPage ,
51
- 0.3 ,
52
- { opacity : 1 , pointerEvents : "all" } ,
53
- { opacity : 0 , pointerEvents : "none" }
55
+ { opacity : 1 } ,
56
+ { duration : 0.3 , opacity : 0 , pointerEvents : "none" }
54
57
)
55
58
. fromTo (
56
59
nextPage ,
57
- 0.3 ,
58
60
{ opacity : 0 , pointerEvents : "none" } ,
59
- { opacity : 1 , pointerEvents : "all" } ,
61
+ { duration : 0.3 , opacity : 1 , pointerEvents : "all" } ,
60
62
"-=0.6"
61
63
)
62
- . fromTo ( nextLeft , 0.3 , { y : "-100%" } , { y : "-10%" } , "-=0.6" )
63
- . fromTo ( nextRight , 0.3 , { y : "-100%" } , { y : "10%" } , "-=0.8" )
64
- . fromTo ( nextText , 0.3 , { opacity : 0 , y : 0 } , { opacity : 1 , y : 0 } )
64
+ . fromTo ( nextLeft , { y : "-100%" } , { duration : 0.3 , y : "-10%" } , "-=0.6" )
65
+ . fromTo ( nextRight , { y : "-100%" } , { duration : 0.3 , y : "10%" } , "-=0.8" )
66
+ . fromTo ( nextText , { opacity : 0 , y : 0 } , { duration : 0.3 , opacity : 1 } )
65
67
. set ( nextLeft , { clearProps : "all" } )
66
68
. set ( nextRight , { clearProps : "all" } ) ;
69
+
70
+ await tl ;
71
+
67
72
current = pageNumber ;
73
+ isAnimating = false ;
68
74
}
69
75
document . addEventListener ( "wheel" , throttle ( scrollChange , 1500 ) ) ;
70
- document . addEventListener ( "touchmove" , throttle ( scrollChange , 1500 ) ) ;
71
-
72
- function swithDots ( dotNumber ) {
73
- const activeDot = document . querySelectorAll ( ".slide" ) [ dotNumber ] ;
74
- slides . forEach ( ( slide ) => slide . classList . remove ( "active" ) ) ;
75
- activeDot . classList . add ( "active" ) ;
76
- }
77
76
78
77
function scrollChange ( e ) {
78
+ if ( isAnimating ) return ;
79
79
e . deltaY > 0 ? ( scrollSlide += 1 ) : ( scrollSlide -= 1 ) ;
80
- // reset
81
80
if ( scrollSlide > 2 ) scrollSlide = 0 ;
82
81
if ( scrollSlide < 0 ) scrollSlide = 2 ;
83
- swithDots ( scrollSlide ) ;
82
+ updateActiveDot ( scrollSlide ) ;
84
83
nextSlide ( scrollSlide ) ;
85
84
}
86
85
87
86
// menu
88
87
const hamburger = document . querySelector ( ".menu" ) ;
89
- const hamburgerLines = document . querySelectorAll ( ".menu line" ) ;
90
- const navOpen = document . querySelector ( ".nav-open" ) ;
91
- const contact = document . querySelector ( ".contact" ) ;
92
- const social = document . querySelector ( ".social" ) ;
93
- const logo = document . querySelector ( ".logo" ) ;
94
-
95
- const tl = new TimelineMax ( { paused : true , reversed : true } ) ;
96
88
97
- tl . to ( navOpen , 0.5 , { y : 0 } )
98
- . fromTo ( contact , 0.5 , { opacity : 0 , y : 10 } , { opacity : 1 , y : 0 } , "-=0.1" )
99
- . fromTo ( social , 0.5 , { opacity : 0 , y : 10 } , { opacity : 1 , y : 0 } , "-=0.5" )
100
- . fromTo ( logo , 0.2 , { color : "var(--white)" } , { color : "black" } , "-=1" )
89
+ const menuTl = gsap . timeline ( { paused : true , reversed : true } ) ;
90
+ menuTl
91
+ . to ( ".nav-open" , { duration : 0.5 , y : 0 } )
92
+ . fromTo (
93
+ ".contact" ,
94
+ { opacity : 0 , y : 10 } ,
95
+ { duration : 0.5 , opacity : 1 , y : 0 } ,
96
+ "-=0.1"
97
+ )
98
+ . fromTo (
99
+ ".social" ,
100
+ { opacity : 0 , y : 10 } ,
101
+ { duration : 0.5 , opacity : 1 , y : 0 } ,
102
+ "-=0.5"
103
+ )
104
+ . fromTo (
105
+ ".logo" ,
106
+ { color : "var(--white)" } ,
107
+ { duration : 0.2 , color : "black" } ,
108
+ "-=1"
109
+ )
101
110
. fromTo (
102
- hamburgerLines ,
103
- 0.2 ,
111
+ ".menu line" ,
104
112
{ stroke : "var(--white)" } ,
105
- { stroke : "black" } ,
113
+ { duration : 0.2 , stroke : "black" } ,
106
114
"-=1"
107
115
) ;
108
116
109
117
hamburger . addEventListener ( "click" , ( ) => {
110
- tl . reversed ( ) ? tl . play ( ) : tl . reverse ( ) ;
118
+ menuTl . reversed ( ) ? menuTl . play ( ) : menuTl . reverse ( ) ;
111
119
} ) ;
112
120
}
113
121
0 commit comments