├── .DS_Store
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── css
└── base.css
├── favicon.ico
├── img
├── .DS_Store
├── 1.jpg
├── 10.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
├── 8.jpg
├── 9.jpg
└── noise.png
├── index.html
└── js
├── .DS_Store
├── ScrollTrigger.min.js
├── effect-1
└── stackMotionEffect.js
├── effect-2
└── stackMotionEffect.js
├── effect-3
└── stackMotionEffect.js
├── gsap.min.js
├── imagesloaded.pkgd.min.js
├── index.js
├── lenis.js
├── smoothscroll.js
└── utils.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/.DS_Store
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .cache
3 | .parcel-cache
4 | package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2009 - 2024 [Codrops](https://tympanus.net/codrops)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 3D Stack Motion on Scroll
2 |
3 | A [#3D](https://tympanus.net/codrops/demos/?tag=3d) [#stack](https://tympanus.net/codrops/demos/?tag=stack) motion effect on [#scroll](https://tympanus.net/codrops/demos/?tag=scroll) inspired by [Looksrare: NFT cards](https://dribbble.com/shots/23641913-Looksrare-NFT-cards).
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=75974)
8 |
9 | [Demo](https://tympanus.net/Development/3DStackMotion/)
10 |
11 | ## Installation
12 |
13 | Run this demo on a [local server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server).
14 |
15 | ## Credits
16 |
17 | - Images generated with [Midjourney](https://midjourney.com)
18 |
19 | ## Misc
20 |
21 | Follow Codrops: [X](http://www.X.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/)
22 |
23 | Subscribe to our frontend newsletter: [The Collective](https://tympanus.net/codrops/collective/)
24 |
25 | Need help with your animations? You can [hire us](mailto:contact@codrops.com).
26 |
27 | ## License
28 | [MIT](LICENSE)
29 |
30 | Made with :blue_heart: by [Codrops](http://www.codrops.com)
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/css/base.css:
--------------------------------------------------------------------------------
1 | *,
2 | *::after,
3 | *::before {
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | font-size: 12px;
9 | --color-text: #fff;
10 | --color-bg: #000;
11 | --color-link: #fff;
12 | --color-link-hover: #c471e1;
13 | --page-padding: 1.5rem;
14 | --color-card-1: #d09df2;
15 | --color-card-2: #9df2eb;
16 | --color-card-3: #f5e2a4;
17 | --color-card-4: #d09df2;
18 | --color-card-5: #9dcaf2;
19 | --color-card-6: #f29dcc;
20 | --color-bg-card: rgba(255, 255, 255, 0.2);
21 | --color-bg-card-inner: rgb(41 27 41);
22 | }
23 |
24 | body {
25 | margin: 0;
26 | color: var(--color-text);
27 | background-color: var(--color-bg);
28 | font-family: "Kode Mono", monospace;
29 | -webkit-font-smoothing: antialiased;
30 | -moz-osx-font-smoothing: grayscale;
31 | background-image: url(../img/noise.png), radial-gradient(circle, rgb(52 33 56) 0%, rgb(0 0 0) 100%);
32 | background-size: 400px, 100% 100vh;
33 | background-attachment: fixed;
34 | overflow-x: hidden;
35 | }
36 |
37 | /* Page Loader */
38 | .js .loading::before,
39 | .js .loading::after {
40 | content: '';
41 | position: fixed;
42 | z-index: 1000;
43 | }
44 |
45 | .js .loading::before {
46 | top: 0;
47 | left: 0;
48 | width: 100%;
49 | height: 100%;
50 | background: var(--color-bg);
51 | }
52 |
53 | .js .loading::after {
54 | top: 50%;
55 | left: 50%;
56 | width: 60px;
57 | height: 60px;
58 | margin: -30px 0 0 -30px;
59 | border-radius: 50%;
60 | opacity: 0.4;
61 | background: var(--color-link);
62 | animation: loaderAnim 0.7s linear infinite alternate forwards;
63 |
64 | }
65 |
66 | @keyframes loaderAnim {
67 | to {
68 | opacity: 1;
69 | transform: scale3d(0.5,0.5,1);
70 | }
71 | }
72 |
73 | a {
74 | text-decoration: underline;
75 | color: var(--color-link);
76 | outline: none;
77 | cursor: pointer;
78 | }
79 |
80 | a:hover {
81 | text-decoration: underline;
82 | color: var(--color-link-hover);
83 | outline: none;
84 | }
85 |
86 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
87 | a:focus {
88 | /* Provide a fallback style for browsers
89 | that don't support :focus-visible */
90 | outline: none;
91 | background: lightgrey;
92 | }
93 |
94 | a:focus:not(:focus-visible) {
95 | /* Remove the focus indicator on mouse-focus for browsers
96 | that do support :focus-visible */
97 | background: transparent;
98 | }
99 |
100 | a:focus-visible {
101 | /* Draw a very noticeable focus style for
102 | keyboard-focus on browsers that do support
103 | :focus-visible */
104 | outline: 2px solid red;
105 | background: transparent;
106 | }
107 |
108 | .unbutton {
109 | background: none;
110 | border: 0;
111 | padding: 0;
112 | margin: 0;
113 | font: inherit;
114 | cursor: pointer;
115 | }
116 |
117 | .unbutton:focus {
118 | outline: none;
119 | }
120 |
121 | .frame {
122 | padding: var(--page-padding);
123 | position: relative;
124 | display: grid;
125 | z-index: 1000;
126 | width: 100%;
127 | height: 100%;
128 | grid-row-gap: 1rem;
129 | grid-column-gap: 2rem;
130 | pointer-events: none;
131 | justify-items: start;
132 | grid-template-columns: auto auto;
133 | grid-template-areas: 'title title' 'back archive' 'sponsor sponsor' 'hire hire';
134 | }
135 |
136 | .frame a {
137 | pointer-events: auto;
138 | }
139 |
140 | .frame__title {
141 | grid-area: title;
142 | font-size: inherit;
143 | margin: 0;
144 | }
145 |
146 | .frame__back {
147 | grid-area: back;
148 | justify-self: start;
149 | }
150 |
151 | .frame__archive {
152 | grid-area: archive;
153 | justify-self: start;
154 | }
155 |
156 | .frame__sub {
157 | display: grid;
158 | position: fixed;
159 | bottom: var(--page-padding);
160 | right: var(--page-padding);
161 | width: 50px;
162 | height: 50px;
163 | border: 1px solid var(--color-link-hover);
164 | place-items: center;
165 | border-radius: 50%;
166 | }
167 |
168 | .frame__sub:hover::before,
169 | .frame__sub:focus::before {
170 | content: '';
171 | position: absolute;
172 | width: 30px;
173 | height: 30px;
174 | top: -30%;
175 | left: -30%;
176 | }
177 |
178 | .frame__sub svg {
179 | fill: var(--color-link-hover);
180 | width: 25px;
181 | height: 25px;
182 | }
183 |
184 | .modal {
185 | pointer-events: none;
186 | opacity: 0;
187 | transform: translate3d(0,20px,0);
188 | position: absolute;
189 | bottom: 55px;
190 | right: 0px;
191 | background: #8a74c4;
192 | color: #fff;
193 | width: 280px;
194 | max-width: calc(100vw - var(--page-padding) * 2);
195 | line-height: 1.4;
196 | padding: 1.5rem;
197 | font-size: 16px;
198 | border-radius: 8px;
199 | transition: all 0.3s;
200 | }
201 |
202 | .frame__sub:hover .modal,
203 | .frame__sub:focus .modal {
204 | pointer-events: auto;
205 | opacity: 1;
206 | transform: translate3d(0px,0px,0px);
207 | }
208 |
209 | .frame__hire {
210 | grid-area: hire;
211 | max-width: 200px;
212 | }
213 |
214 | .frame__demos {
215 | grid-area: demos;
216 | display: flex;
217 | gap: 1rem;
218 | }
219 |
220 | main {
221 | position: relative;
222 | }
223 |
224 | .intro {
225 | width: 100%;
226 | display: grid;
227 | grid-template-columns: 100%;
228 | grid-template-rows: 20vh 20vh auto;
229 | grid-template-areas: 'intro-title' 'intro-hint' '...';
230 | place-items: center;
231 | padding: 0 var(--page-padding);
232 | }
233 |
234 | .intro__title {
235 | text-transform: uppercase;
236 | font-size: clamp(2rem,7vw,8rem);
237 | font-weight: 400;
238 | grid-area: intro-title;
239 | position: relative;
240 | z-index: 100;
241 | align-self: center;
242 | margin: 0;
243 | text-align: center;
244 | }
245 |
246 | .intro__hint {
247 | grid-area: intro-hint;
248 | position: relative;
249 | z-index: 100;
250 | align-self: center;
251 | font-size: 1.5rem;
252 | text-align: center;
253 | }
254 |
255 | .intro__hint::after {
256 | content: '\00BB';
257 | position: absolute;
258 | top: 100%;
259 | left: 0%;
260 | text-align: center;
261 | font-size: 3rem;
262 | width: 100%;
263 | transform: rotate(90deg);
264 | animation: pulse 0.3s linear alternate infinite;
265 | }
266 |
267 | @keyframes pulse {
268 | to {
269 | top: 120%;
270 | }
271 | }
272 |
273 | .outro {
274 | display: grid;
275 | place-items: center;
276 | margin: 40vh 0;
277 | }
278 |
279 | .outro__title {
280 | font-weight: 300;
281 | font-size: clamp(1.5rem,10vw,2rem);
282 | }
283 |
284 | .grid {
285 | position: relative;
286 | perspective: 1000px;
287 | align-self: start;
288 | grid-area: intro-title;
289 | grid-row: 1 / span 3;
290 | display: grid;
291 | grid-template-columns: repeat(3,auto);
292 | justify-content: center;
293 | gap: 3rem;
294 | filter: brightness(70%);
295 | }
296 |
297 | .card {
298 | width: 30vw;
299 | max-width: 255px;
300 | min-width: 150px;
301 | aspect-ratio: 2/3;
302 | font-size: 9px;
303 | text-transform: uppercase;
304 | padding: 5px;
305 | display: grid;
306 | grid-template-columns: 1fr 1fr;
307 | border-radius: 10px;
308 | position: relative;
309 | align-items: stretch;
310 | outline: 1px solid var(--color-card);
311 | background: var(--color-bg-card);
312 | grid-template-areas: 'card-img card-img' 'card-title card-meta' 'card-subtitle card-subtitle' 'card-desc card-desc';
313 | }
314 |
315 | .grid .card {
316 | box-shadow: 0 2px 7px 0 rgba(0,0,0,0.8);
317 | }
318 |
319 | .card:nth-child(1n) {
320 | --color-card: var(--color-card-1);
321 | }
322 |
323 | .card:nth-child(2n) {
324 | --color-card: var(--color-card-2);
325 | }
326 |
327 | .card:nth-child(3n) {
328 | --color-card: var(--color-card-3);
329 | }
330 |
331 | .card:nth-child(4n) {
332 | --color-card: var(--color-card-4);
333 | }
334 |
335 | .card:nth-child(5n) {
336 | --color-card: var(--color-card-5);
337 | }
338 |
339 | .card:nth-child(6n) {
340 | --color-card: var(--color-card-6);
341 | }
342 |
343 | .card > * {
344 | background-color: var(--color-bg-card-inner);
345 | }
346 |
347 | .card__img {
348 | grid-area: card-img;
349 | background-size: cover;
350 | background-position: 50% 50%;
351 | aspect-ratio: 1;
352 | max-width: 100%;
353 | border-radius: 6px 6px 0 0;
354 | }
355 |
356 | .card__title {
357 | padding: 0.5rem 3px;
358 | grid-area: card-title;
359 | margin: 0;
360 | }
361 |
362 | .card__meta {
363 | grid-area: card-meta;
364 | padding: 0.5rem 3px;
365 | text-align: right;
366 | }
367 |
368 | .card__subtitle {
369 | grid-area: card-subtitle;
370 | margin: 0;
371 | padding: 0 3px;
372 | }
373 |
374 | .card__description {
375 | grid-area: card-desc;
376 | margin: 0;
377 | border-radius: 0 0 6px 6px;
378 | padding: 0 3px;
379 | }
380 |
381 | .card-wrap {
382 | margin-top: 5vh;
383 | display: grid;
384 | grid-gap: 2rem;
385 | grid-auto-flow: row;
386 | grid-template-columns: 250px;
387 | text-align: center;
388 | justify-items: center;
389 | }
390 |
391 | .card--rel {
392 | align-items: start;
393 | background: rgba(255,255,255,0.1);
394 | }
395 |
396 | .card--rel .card__img {
397 | aspect-ratio: 4 / 3;
398 | filter: contrast(0.8);
399 | }
400 |
401 | .card--rel .card__title {
402 | grid-column-end: 3;
403 | background: none;
404 | font-size: 1.5rem;
405 | font-weight: 400;
406 | text-transform: none;
407 | padding: 2rem 1rem 1rem;
408 | }
409 |
410 | .credits {
411 | font-size: 1.5rem;
412 | text-align: center;
413 | margin: 50vh auto 0;
414 | padding-bottom: 50vh;
415 | }
416 |
417 | .section-title {
418 | width: 100%;
419 | display: grid;
420 | place-items: center;
421 | font-size: clamp(2rem,6vw,6rem);
422 | line-height: 1;
423 | font-weight: 400;
424 | margin: 25vh auto 0;
425 | max-width: 600px;
426 | text-align: center;
427 | text-transform: uppercase;
428 | }
429 |
430 | .wrap {
431 | position: relative;
432 | min-height: 100vh;
433 | }
434 |
435 | .wrap__inner {
436 | position: relative;
437 | perspective: 1000px;
438 | }
439 |
440 | .content {
441 | width: 100vw;
442 | position: relative;
443 | transform-style: preserve-3d;
444 | display: grid;
445 | grid-template-areas: 'card';
446 | grid-template-columns: 100%;
447 | place-items: center;
448 | }
449 |
450 | .content .card {
451 | grid-area: card;
452 | background: rgba(132, 128, 143, 0.36);
453 | }
454 |
455 | @media screen and (min-width: 53em) {
456 | body {
457 | --page-padding: 2rem;
458 | }
459 | .frame {
460 | position: fixed;
461 | top: 0;
462 | left: 0;
463 | width: 100%;
464 | height: 100%;
465 | grid-template-columns: auto auto auto 1fr;
466 | grid-template-rows: auto auto;
467 | align-content: space-between;
468 | grid-template-areas: 'title back archive sponsor' 'hire ... ... sub';
469 | }
470 | .frame__sub {
471 | justify-self: end;
472 | }
473 | .frame__title {
474 | padding-right: 4rem;
475 | }
476 | .frame__hire {
477 | align-self: end;
478 | }
479 | .modal {
480 | bottom: 50px;
481 | right: 50px;
482 | }
483 | .intro {
484 | grid-template-rows: 60vh 40vh auto;
485 | }
486 | .intro__title {
487 | align-self: end;
488 | }
489 | .grid {
490 | padding-top: 12vh;
491 | }
492 | .content {
493 | min-height: 100vh;
494 | justify-content: center;
495 | align-items: center;
496 | }
497 | .card-wrap {
498 | grid-template-columns: repeat(2, 300px);
499 | }
500 | }
501 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/favicon.ico
--------------------------------------------------------------------------------
/img/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/.DS_Store
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/1.jpg
--------------------------------------------------------------------------------
/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/10.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/2.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/3.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/4.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/5.jpg
--------------------------------------------------------------------------------
/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/6.jpg
--------------------------------------------------------------------------------
/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/7.jpg
--------------------------------------------------------------------------------
/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/8.jpg
--------------------------------------------------------------------------------
/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/9.jpg
--------------------------------------------------------------------------------
/img/noise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/img/noise.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 3D Stack Motion Effect | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
36 |
37 |
The Next Evolution
38 |
Scroll into the future
39 |
40 |
41 |
42 |
AI Horizons
43 |
Beyond Human Limits
44 |
V1.0
45 |
Explore the future where AI transforms imagination into reality.
46 |
47 |
48 |
49 |
Tech Odyssey
50 |
Unveiling Tomorrow
51 |
V2.0
52 |
Embark on a journey into the realm of cutting-edge technology reshaping our world.
53 |
54 |
55 |
56 |
Digital Frontiers
57 |
Pushing Boundaries
58 |
V3.0
59 |
Enter the realm where innovation meets possibility, shaping the future of humanity.
60 |
61 |
62 |
63 |
AI Nexus
64 |
Bridging Realms
65 |
V4.0
66 |
Dive into the interconnected world of AI, where algorithms shape the future of human experience.
67 |
68 |
69 |
70 |
AI Innovate
71 |
Pioneering Tomorrow
72 |
V5.0
73 |
Join the forefront of AI innovation, where creativity meets computational intelligence to shape a better future.
74 |
75 |
76 |
77 |
AI Horizons
78 |
Beyond Human Limits
79 |
V6.0
80 |
Explore the future where AI transforms imagination into reality.
81 |
82 |
83 |
84 |
AI Frontier
85 |
Exploring New Horizons
86 |
V7.0
87 |
Venture into uncharted territories where AI blazes trails towards unprecedented possibilities.
88 |
89 |
90 |
91 |
AI Visionary
92 |
Envisioning Tomorrow
93 |
V8.0
94 |
Embrace the visionary realm of AI, where dreams of the future become the reality of today.
95 |
96 |
97 |
98 |
AI Odyssey
99 |
Journey to Tomorrow
100 |
V9.0
101 |
Embark on an epic odyssey through the realms of AI, where innovation knows no bounds.
102 |
103 |
104 |
105 | A New Frontier
106 |
107 |
108 |
109 |
112 |
115 |
118 |
121 |
124 |
127 |
130 |
133 |
136 |
139 |
142 |
145 |
148 |
151 |
154 |
157 |
160 |
163 |
166 |
169 |
172 |
175 |
178 |
181 |
184 |
187 |
190 |
191 |
192 |
193 | Chronicles of Circuitry
194 |
195 |
196 |
197 |
200 |
203 |
206 |
209 |
212 |
215 |
218 |
221 |
224 |
227 |
230 |
233 |
236 |
239 |
242 |
245 |
248 |
251 |
254 |
257 |
260 |
263 |
266 |
269 |
272 |
275 |
278 |
279 |
280 |
281 | Synthetica Sapiens
282 |
283 |
284 |
285 |
288 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
315 |
318 |
321 |
324 |
327 |
330 |
333 |
336 |
339 |
342 |
345 |
348 |
351 |
354 |
357 |
360 |
363 |
366 |
367 |
368 |
369 |
370 | More you might like
371 |
387 |
388 | Made by @codrops
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
--------------------------------------------------------------------------------
/js/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/3DStackMotion/75cbda91ed26d31aeeb5a5b9887848e5a7005c7f/js/.DS_Store
--------------------------------------------------------------------------------
/js/ScrollTrigger.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * ScrollTrigger 3.12.5
3 | * https://gsap.com
4 | *
5 | * @license Copyright 2024, GreenSock. All rights reserved.
6 | * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
7 | * @author: Jack Doyle, jack@greensock.com
8 | */
9 |
10 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).window=e.window||{})}(this,function(e){"use strict";function _defineProperties(e,t){for(var r=0;r=Math.abs(r)?t:r}function O(){(Ae=Ce.core.globals().ScrollTrigger)&&Ae.core&&function _integrate(){var e=Ae.core,r=e.bridge||{},t=e._scrollers,n=e._proxies;t.push.apply(t,Ie),n.push.apply(n,Le),Ie=t,Le=n,i=function _bridge(e,t){return r[e](t)}}()}function P(e){return Ce=e||r(),!Te&&Ce&&"undefined"!=typeof document&&document.body&&(Se=window,Pe=(ke=document).documentElement,Me=ke.body,t=[Se,ke,Pe,Me],Ce.utils.clamp,Be=Ce.core.context||function(){},Oe="onpointerenter"in Me?"pointer":"mouse",Ee=k.isTouch=Se.matchMedia&&Se.matchMedia("(hover: none), (pointer: coarse)").matches?1:"ontouchstart"in Se||0=o,n=Math.abs(t)>=o;S&&(r||n)&&S(se,e,t,me,ye),r&&(m&&0Math.abs(t)?"x":"y",ie=!0),"y"!==ae&&(me[2]+=e,se._vx.update(e,!0)),"x"!==ae&&(ye[2]+=t,se._vy.update(t,!0)),n?ee=ee||requestAnimationFrame(ff):ff()}function jf(e){if(!df(e,1)){var t=(e=M(e,s)).clientX,r=e.clientY,n=t-se.x,o=r-se.y,i=se.isDragging;se.x=t,se.y=r,(i||Math.abs(se.startX-t)>=a||Math.abs(se.startY-r)>=a)&&(h&&(re=!0),i||(se.isDragging=!0),hf(n,o),i||p&&p(se))}}function mf(e){return e.touches&&1=e)return a[n];return a[n-1]}for(n=a.length,e+=r;n--;)if(a[n]<=e)return a[n];return a[0]}:function(e,t,r){void 0===r&&(r=.001);var n=i(e);return!t||Math.abs(n-e)r&&(n*=t/100),e=e.substr(0,r-1)),e=n+(e in H?H[e]*t:~e.indexOf("%")?parseFloat(e)*t/100:parseFloat(e)||0)}return e}function Db(e,t,r,n,o,i,a,s){var l=o.startColor,c=o.endColor,u=o.fontSize,f=o.indent,d=o.fontWeight,p=Xe.createElement("div"),g=La(r)||"fixed"===z(r,"pinType"),h=-1!==e.indexOf("scroller"),v=g?We:r,b=-1!==e.indexOf("start"),m=b?l:c,y="border-color:"+m+";font-size:"+u+";color:"+m+";font-weight:"+d+";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;";return y+="position:"+((h||s)&&g?"fixed;":"absolute;"),!h&&!s&&g||(y+=(n===Fe?q:I)+":"+(i+parseFloat(f))+"px;"),a&&(y+="box-sizing:border-box;text-align:left;width:"+a.offsetWidth+"px;"),p._isStart=b,p.setAttribute("class","gsap-marker-"+e+(t?" marker-"+t:"")),p.style.cssText=y,p.innerText=t||0===t?e+"-"+t:e,v.children[0]?v.insertBefore(p,v.children[0]):v.appendChild(p),p._offset=p["offset"+n.op.d2],X(p,0,n,b),p}function Ib(){return 34We.clientWidth)||(Ie.cache++,v?D=D||requestAnimationFrame(Z):Z(),st||U("scrollStart"),st=at())}function Kb(){y=Ne.innerWidth,m=Ne.innerHeight}function Lb(){Ie.cache++,je||h||Xe.fullscreenElement||Xe.webkitFullscreenElement||b&&y===Ne.innerWidth&&!(Math.abs(Ne.innerHeight-m)>.25*Ne.innerHeight)||c.restart(!0)}function Ob(){return xb(ne,"scrollEnd",Ob)||Pt(!0)}function Rb(e){for(var t=0;tt,n=e._startClamp&&e.start>=t;(r||n)&&e.setPositions(n?t-1:e.start,r?Math.max(n?t:e.start+1,t):e.end,!0)}),Zb(!1),et=0,r.forEach(function(e){return e&&e.render&&e.render(-1)}),Ie.forEach(function(e){Ta(e)&&(e.smooth&&requestAnimationFrame(function(){return e.target.style.scrollBehavior="smooth"}),e.rec&&e(e.rec))}),Tb(w,1),c.pause(),kt++,Z(rt=2),Tt.forEach(function(e){return Ta(e.vars.onRefresh)&&e.vars.onRefresh(e)}),rt=ne.isRefreshing=!1,U("refresh")}else wb(ne,"scrollEnd",Ob)},Q=0,Mt=1,Z=function _updateAll(e){if(2===e||!rt&&!S){ne.isUpdating=!0,ot&&ot.update(0);var t=Tt.length,r=at(),n=50<=r-R,o=t&&Tt[0].scroll();if(Mt=o=Qa(be,he)){if(ie&&Ae()&&!de)for(i=ie.parentNode;i&&i!==We;)i._pinOffset&&(B-=i._pinOffset,q-=i._pinOffset),i=i.parentNode}else o=mb(ae),s=he===Fe,a=Ae(),G=parseFloat(j(he.a))+_,!y&&1=q})},Te.update=function(e,t,r){if(!de||r||e){var n,o,i,a,s,l,c,u=!0===rt?re:Te.scroll(),f=e?0:(u-B)/N,d=f<0?0:1u+(u-R)/(at()-Ke)*M&&(d=.9999)),d!==p&&Te.enabled){if(a=(s=(n=Te.isActive=!!d&&d<1)!=(!!p&&p<1))||!!d!=!!p,Te.direction=p=Qa(be,he),fe)if(e||!n&&!l)oc(ae,U);else{var g=wt(ae,!0),h=u-B;oc(ae,We,g.top+(he===Fe?h:0)+xt,g.left+(he===Fe?0:h)+xt)}Et(n||l?W:V),$&&d<1&&n||b(G+(1!==d||l?0:Q))}}else b(Ia(G+Q*d));!ue||A.tween||je||it||te.restart(!0),S&&(s||ce&&d&&(d<1||!tt))&&Ve(S.targets).forEach(function(e){return e.classList[n||ce?"add":"remove"](S.className)}),!T||ve||e||T(Te),a&&!je?(ve&&(c&&("complete"===i?O.pause().totalProgress(1):"reset"===i?O.restart(!0).pause():"restart"===i?O.restart(!0):O[i]()),T&&T(Te)),!s&&tt||(k&&s&&Xa(Te,k),xe[o]&&Xa(Te,xe[o]),ce&&(1===d?Te.kill(!1,1):xe[o]=0),s||xe[o=1===d?1:3]&&Xa(Te,xe[o])),pe&&!n&&Math.abs(Te.getVelocity())>(Ua(pe)?pe:2500)&&(Wa(Te.callbackAnimation),ee?ee.progress(1):Wa(O,"reverse"===i?1:!d,1))):ve&&T&&!je&&T(Te)}if(x){var v=de?u/de.duration()*(de._caScrollDist||0):u;y(v+(Y._isFlipped?1:0)),x(v)}C&&C(-u/de.duration()*(de._caScrollDist||0))}},Te.enable=function(e,t){Te.enabled||(Te.enabled=!0,wb(be,"resize",Lb),me||wb(be,"scroll",Jb),Se&&wb(ScrollTrigger,"refreshInit",Se),!1!==e&&(Te.progress=Oe=0,D=R=Me=Ae()),!1!==t&&Te.refresh())},Te.getTween=function(e){return e&&A?A.tween:ee},Te.setPositions=function(e,t,r,n){if(de){var o=de.scrollTrigger,i=de.duration(),a=o.end-o.start;e=o.start+a*e/i,t=o.start+a*t/i}Te.refresh(!1,!1,{start:Da(e,r&&!!Te._startClamp),end:Da(t,r&&!!Te._endClamp)},n),Te.update()},Te.adjustPinSpacing=function(e){if(Z&&e){var t=Z.indexOf(he.d)+1;Z[t]=parseFloat(Z[t])+e+xt,Z[1]=parseFloat(Z[1])+e+xt,Et(Z)}},Te.disable=function(e,t){if(Te.enabled&&(!1!==e&&Te.revert(!0,!0),Te.enabled=Te.isActive=!1,t||ee&&ee.pause(),re=0,n&&(n.uncache=1),Se&&xb(ScrollTrigger,"refreshInit",Se),te&&(te.pause(),A.tween&&A.tween.kill()&&(A.tween=0)),!me)){for(var r=Tt.length;r--;)if(Tt[r].scroller===be&&Tt[r]!==Te)return;xb(be,"resize",Lb),me||xb(be,"scroll",Jb)}},Te.kill=function(e,t){Te.disable(e,t),ee&&!t&&ee.kill(),a&&delete St[a];var r=Tt.indexOf(Te);0<=r&&Tt.splice(r,1),r===Qe&&0i&&(b()>i?a.progress(1)&&b(i):a.resetTo("scrollY",i))}Va(e)||(e={}),e.preventDefault=e.isNormalizer=e.allowClicks=!0,e.type||(e.type="wheel,touch"),e.debounce=!!e.debounce,e.id=e.id||"normalizer";var n,i,l,o,a,c,u,s,f=e.normalizeScrollX,t=e.momentum,r=e.allowNestedScroll,d=e.onRelease,p=J(e.target)||Je,g=He.core.globals().ScrollSmoother,h=g&&g.get(),v=E&&(e.content&&J(e.content)||h&&!1!==e.content&&!h.smooth()&&h.content()),b=K(p,Fe),m=K(p,Ye),y=1,x=(k.isTouch&&Ne.visualViewport?Ne.visualViewport.scale*Ne.visualViewport.width:Ne.outerWidth)/Ne.innerWidth,w=0,_=Ta(t)?function(){return t(n)}:function(){return t||2.8},C=xc(p,e.type,!0,r),T=Ha,S=Ha;return v&&He.set(v,{y:"+=0"}),e.ignoreCheck=function(e){return E&&"touchmove"===e.type&&function ignoreDrag(){if(o){requestAnimationFrame(zq);var e=Ia(n.deltaY/2),t=S(b.v-e);if(v&&t!==b.v+b.offset){b.offset=t-b.v;var r=Ia((parseFloat(v&&v._gsap.y)||0)-b.offset);v.style.transform="matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, "+r+", 0, 1)",v._gsap.y=r+"px",b.cacheID=Ie.cache,Z()}return!0}b.offset&&Dq(),o=!0}()||1.05=i||i-1<=r)&&He.to({},{onUpdate:Jq,duration:o})}else s.restart(!0);d&&d(e)},e.onWheel=function(){a._ts&&a.pause(),1e3 {
29 | winsize = { width: window.innerWidth, height: window.innerHeight };
30 | this.scroll();
31 | }, 100);
32 | window.addEventListener('resize', throttledResize);
33 | }
34 |
35 | // Defines the scroll effect logic for the stack.
36 | scroll() {
37 | // Initially hides the content element and prepares it for the animation by setting its transform property.
38 | // This sets the initial 3D rotation of the stack and its cards, defining their starting visual appearance.
39 | this.contentElement.style.transform = 'rotate3d(1, 0, 0, -25deg) rotate3d(0, 1, 0, 50deg) rotate3d(0, 0, 1, 25deg)';
40 | this.contentElement.style.opacity = 0;
41 |
42 | // Clears previous timeline if exists to prevent conflicts.
43 | if (this.tl) {
44 | this.tl.kill();
45 | }
46 |
47 | // Creates a new timeline for the scroll-triggered animation.
48 | this.tl = gsap.timeline({
49 | defaults: {
50 | ease: 'power1',
51 | },
52 | scrollTrigger: {
53 | trigger: this.wrapElement,
54 | start: 'top center',
55 | end: '+=150%',
56 | scrub: true,
57 | // Sets opacity to 1 when the element comes into view.
58 | onEnter: () => gsap.set(this.contentElement, {opacity: 1}),
59 | onEnterBack: () => gsap.set(this.contentElement, {opacity: 1}),
60 | // Hides the element when it leaves the view.
61 | onLeave: () => gsap.set(this.contentElement, {opacity: 0}),
62 | onLeaveBack: () => gsap.set(this.contentElement, {opacity: 0})
63 | },
64 | })
65 | .fromTo(this.imageElements, {
66 | // Animates from a starting z position based on the window size.
67 | z: (pos) => -2.65 * winsize.width - pos * 0.03 * winsize.width,
68 | }, {
69 | // Animates to an ending z position, creating a 3D effect as elements scroll.
70 | z: (pos) => 1.4 * winsize.width + (this.imagesTotal - pos - 1) * 0.03 * winsize.width,
71 | }, 0)
72 | .fromTo(this.imageElements, {
73 | rotationZ: -220,
74 | }, {
75 | rotationY: -30,
76 | rotationZ: 120,
77 | // Stagger effect for individual elements to animate sequentially.
78 | stagger: 0.005,
79 | }, 0)
80 | /*.fromTo(this.imageElements, {
81 | filter: 'brightness(20%)',
82 | }, {
83 | filter: 'brightness(150%)',
84 | stagger: 0.005,
85 | }, 0);*/
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/js/effect-2/stackMotionEffect.js:
--------------------------------------------------------------------------------
1 | import { throttle } from '../utils.js';
2 |
3 | let winsize = {width: window.innerWidth, height: window.innerHeight};
4 |
5 | export class StackMotionEffect {
6 | constructor(stackEl) {
7 | // Check if the provided element is valid.
8 | if (!stackEl || !(stackEl instanceof HTMLElement)) {
9 | throw new Error('Invalid element provided.');
10 | }
11 |
12 | this.wrapElement = stackEl;
13 | this.contentElement = this.wrapElement.querySelector('.content');
14 | this.imageElements = [this.contentElement.querySelectorAll('.card')];
15 | this.imagesTotal = this.imageElements.length;
16 |
17 | // Set up the effect for the provided element.
18 | this.initializeEffect(stackEl);
19 | }
20 |
21 | // Sets up the initial effect on the provided element.
22 | initializeEffect(element) {
23 | // Scroll effect.
24 | this.scroll();
25 |
26 | const throttledResize = throttle(() => {
27 | winsize = { width: window.innerWidth, height: window.innerHeight };
28 | this.scroll();
29 | }, 100);
30 | window.addEventListener('resize', throttledResize);
31 | }
32 |
33 | scroll() {
34 | // Let's set the initial rotation for the content element
35 | this.contentElement.style.transform = 'rotate3d(1, 0, 0, 55deg) rotate3d(0, 1, 0, 30deg)';
36 | this.contentElement.style.opacity = 0;
37 |
38 | if (this.tl) {
39 | this.tl.kill();
40 | }
41 |
42 | this.tl = gsap.timeline({
43 | defaults: {
44 | ease: 'sine.inOut',
45 | },
46 | scrollTrigger: {
47 | trigger: this.wrapElement,
48 | start: 'top center',
49 | end: '+=150%',
50 | scrub: true,
51 | onEnter: () => gsap.set(this.contentElement, {opacity: 1}),
52 | onEnterBack: () => gsap.set(this.contentElement, {opacity: 1}),
53 | onLeave: () => gsap.set(this.contentElement, {opacity: 0}),
54 | onLeaveBack: () => gsap.set(this.contentElement, {opacity: 0}),
55 | },
56 | })
57 | .fromTo(this.imageElements, {
58 | z: (pos) => -1.2 * winsize.height - pos * 0.08 * winsize.height,
59 | }, {
60 | z: (pos) => 3 * winsize.height + (this.imagesTotal - pos - 1) * 0.08 * winsize.height,
61 | }, 0)
62 | .fromTo(this.imageElements, {
63 | rotationZ: -130,
64 | }, {
65 | rotationZ: 360,
66 | stagger: 0.006,
67 | }, 0)
68 | /*.fromTo(this.imageElements, {
69 | filter: 'brightness(10%)',
70 | }, {
71 | filter: 'brightness(400%)',
72 | stagger: 0.005,
73 | }, 0);*/
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/js/effect-3/stackMotionEffect.js:
--------------------------------------------------------------------------------
1 | import { throttle } from '../utils.js';
2 |
3 | let winsize = {width: window.innerWidth, height: window.innerHeight};
4 |
5 | export class StackMotionEffect {
6 | constructor(stackEl) {
7 | // Check if the provided element is valid.
8 | if (!stackEl || !(stackEl instanceof HTMLElement)) {
9 | throw new Error('Invalid element provided.');
10 | }
11 |
12 | this.wrapElement = stackEl;
13 | this.contentElement = this.wrapElement.querySelector('.content');
14 | this.imageElements = [this.contentElement.querySelectorAll('.card')];
15 | this.imagesTotal = this.imageElements.length;
16 |
17 | // Set up the effect for the provided element.
18 | this.initializeEffect(stackEl);
19 | }
20 |
21 | // Sets up the initial effect on the provided element.
22 | initializeEffect(element) {
23 | // Scroll effect.
24 | this.scroll();
25 |
26 | const throttledResize = throttle(() => {
27 | winsize = { width: window.innerWidth, height: window.innerHeight };
28 | this.scroll();
29 | }, 100);
30 | window.addEventListener('resize', throttledResize);
31 | }
32 |
33 | scroll() {
34 | // Let's set the initial rotation for the content element
35 | this.contentElement.style.transform = 'rotate3d(1, 0, 0, 25deg) rotate3d(0, 1, 0, -50deg) rotate3d(0, 0, 1, 25deg)';
36 | this.contentElement.style.opacity = 0;
37 |
38 | if (this.tl) {
39 | this.tl.kill();
40 | }
41 |
42 | this.tl = gsap.timeline({
43 | defaults: {
44 | ease: 'power1',
45 | },
46 | scrollTrigger: {
47 | trigger: this.wrapElement,
48 | start: 'top center',
49 | end: '+=150%',
50 | scrub: true,
51 | onEnter: () => gsap.set(this.contentElement, {opacity: 1}),
52 | onEnterBack: () => gsap.set(this.contentElement, {opacity: 1}),
53 | onLeave: () => gsap.set(this.contentElement, {opacity: 0}),
54 | onLeaveBack: () => gsap.set(this.contentElement, {opacity: 0}),
55 | },
56 | })
57 | .fromTo(this.imageElements, {
58 | z: (pos) => -2.5 * winsize.width/2 - pos * 0.07 * winsize.width,
59 | }, {
60 | z: (pos) => 2.5 * winsize.width + (this.imagesTotal - pos - 1) * 0.07 * winsize.width,
61 | }, 0)
62 | .fromTo(this.imageElements, {
63 | rotationZ: 10,
64 | }, {
65 | rotationX: 20,
66 | rotationZ: 280,
67 | yPercent: -100,
68 | stagger: 0.005,
69 | }, 0)
70 | /*.fromTo(this.imageElements, {
71 | filter: 'brightness(20%)',
72 | }, {
73 | filter: 'brightness(350%)',
74 | stagger: 0.005,
75 | }, 0);*/
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/js/gsap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * GSAP 3.12.5
3 | * https://gsap.com
4 | *
5 | * @license Copyright 2024, GreenSock. All rights reserved.
6 | * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
7 | * @author: Jack Doyle, jack@greensock.com
8 | */
9 |
10 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).window=t.window||{})}(this,function(e){"use strict";function _inheritsLoose(t,e){t.prototype=Object.create(e.prototype),(t.prototype.constructor=t).__proto__=e}function _assertThisInitialized(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function r(t){return"string"==typeof t}function s(t){return"function"==typeof t}function t(t){return"number"==typeof t}function u(t){return void 0===t}function v(t){return"object"==typeof t}function w(t){return!1!==t}function x(){return"undefined"!=typeof window}function y(t){return s(t)||r(t)}function P(t){return(i=yt(t,ot))&&ze}function Q(t,e){return console.warn("Invalid property",t,"set to",e,"Missing plugin? gsap.registerPlugin()")}function R(t,e){return!e&&console.warn(t)}function S(t,e){return t&&(ot[t]=e)&&i&&(i[t]=e)||ot}function T(){return 0}function ea(t){var e,r,i=t[0];if(v(i)||s(i)||(t=[t]),!(e=(i._gsap||{}).harness)){for(r=gt.length;r--&&!gt[r].targetTest(i););e=gt[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new Vt(t[r],e)))||t.splice(r,1);return t}function fa(t){return t._gsap||ea(Mt(t))[0]._gsap}function ga(t,e,r){return(r=t[e])&&s(r)?t[e]():u(r)&&t.getAttribute&&t.getAttribute(e)||r}function ha(t,e){return(t=t.split(",")).forEach(e)||t}function ia(t){return Math.round(1e5*t)/1e5||0}function ja(t){return Math.round(1e7*t)/1e7||0}function ka(t,e){var r=e.charAt(0),i=parseFloat(e.substr(2));return t=parseFloat(t),"+"===r?t+i:"-"===r?t-i:"*"===r?t*i:t/i}function la(t,e){for(var r=e.length,i=0;t.indexOf(e[i])<0&&++ia;)s=s._prev;return s?(e._next=s._next,s._next=e):(e._next=t[r],t[r]=e),e._next?e._next._prev=e:t[i]=e,e._prev=s,e.parent=e._dp=t,e}function ya(t,e,r,i){void 0===r&&(r="_first"),void 0===i&&(i="_last");var n=e._prev,a=e._next;n?n._next=a:t[r]===e&&(t[r]=a),a?a._prev=n:t[i]===e&&(t[i]=n),e._next=e._prev=e.parent=null}function za(t,e){t.parent&&(!e||t.parent.autoRemoveChildren)&&t.parent.remove&&t.parent.remove(t),t._act=0}function Aa(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var r=t;r;)r._dirty=1,r=r.parent;return t}function Ca(t,e,r,i){return t._startAt&&(L?t._startAt.revert(ht):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,i))}function Ea(t){return t._repeat?Tt(t._tTime,t=t.duration()+t._rDelay)*t:0}function Ga(t,e){return(t-e._start)*e._ts+(0<=e._ts?0:e._dirty?e.totalDuration():e._tDur)}function Ha(t){return t._end=ja(t._start+(t._tDur/Math.abs(t._ts||t._rts||X)||0))}function Ia(t,e){var r=t._dp;return r&&r.smoothChildTiming&&t._ts&&(t._start=ja(r._time-(0X)&&e.render(r,!0)),Aa(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur(n=Math.abs(n))&&(a=i,o=n);return a}function tb(t){return za(t),t.scrollTrigger&&t.scrollTrigger.kill(!!L),t.progress()<1&&Ct(t,"onInterrupt"),t}function wb(t){if(t)if(t=!t.name&&t.default||t,x()||t.headless){var e=t.name,r=s(t),i=e&&!r&&t.init?function(){this._props=[]}:t,n={init:T,render:he,add:Wt,kill:ce,modifier:fe,rawVars:0},a={targetTest:0,get:0,getSetter:ne,aliases:{},register:0};if(Ft(),t!==i){if(pt[e])return;qa(i,qa(ua(t,n),a)),yt(i.prototype,yt(n,ua(t,a))),pt[i.prop=e]=i,t.targetTest&&(gt.push(i),ft[e]=1),e=("css"===e?"CSS":e.charAt(0).toUpperCase()+e.substr(1))+"Plugin"}S(e,i),t.register&&t.register(ze,i,_e)}else At.push(t)}function zb(t,e,r){return(6*(t+=t<0?1:1>16,e>>8&St,e&St]:0:zt.black;if(!p){if(","===e.substr(-1)&&(e=e.substr(0,e.length-1)),zt[e])p=zt[e];else if("#"===e.charAt(0)){if(e.length<6&&(e="#"+(n=e.charAt(1))+n+(a=e.charAt(2))+a+(s=e.charAt(3))+s+(5===e.length?e.charAt(4)+e.charAt(4):"")),9===e.length)return[(p=parseInt(e.substr(1,6),16))>>16,p>>8&St,p&St,parseInt(e.substr(7),16)/255];p=[(e=parseInt(e.substr(1),16))>>16,e>>8&St,e&St]}else if("hsl"===e.substr(0,3))if(p=c=e.match(tt),r){if(~e.indexOf("="))return p=e.match(et),i&&p.length<4&&(p[3]=1),p}else o=+p[0]%360/360,u=p[1]/100,n=2*(h=p[2]/100)-(a=h<=.5?h*(u+1):h+u-h*u),3=U?u.endTime(!1):t._dur;return r(e)&&(isNaN(e)||e in o)?(a=e.charAt(0),s="%"===e.substr(-1),n=e.indexOf("="),"<"===a||">"===a?(0<=n&&(e=e.replace(/=/,"")),("<"===a?u._start:u.endTime(0<=u._repeat))+(parseFloat(e.substr(1))||0)*(s?(n<0?u:i).totalDuration()/100:1)):n<0?(e in o||(o[e]=h),o[e]):(a=parseFloat(e.charAt(n-1)+e.substr(n+1)),s&&i&&(a=a/100*(Z(i)?i[0]:i).totalDuration()),1=r&&te)return i;i=i._next}else for(i=t._last;i&&i._start>=r;){if("isPause"===i.data&&i._start=n._start)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0=this.totalDuration()||!v&&_)&&(f!==this._start&&Math.abs(l)===Math.abs(this._ts)||this._lock||(!t&&g||!(v===m&&0=i&&(a instanceof $t?e&&n.push(a):(r&&n.push(a),t&&n.push.apply(n,a.getChildren(!0,e,r)))),a=a._next;return n},e.getById=function getById(t){for(var e=this.getChildren(1,1,1),r=e.length;r--;)if(e[r].vars.id===t)return e[r]},e.remove=function remove(t){return r(t)?this.removeLabel(t):s(t)?this.killTweensOf(t):(ya(this,t),t===this._recent&&(this._recent=this._last),Aa(this))},e.totalTime=function totalTime(t,e){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=ja(Rt.time-(0r:!r||s.isActive())&&n.push(s):(i=s.getTweensOf(a,r)).length&&n.push.apply(n,i),s=s._next;return n},e.tweenTo=function tweenTo(t,e){e=e||{};var r,i=this,n=xt(i,t),a=e.startAt,s=e.onStart,o=e.onStartParams,u=e.immediateRender,h=$t.to(i,qa({ease:e.ease||"none",lazy:!1,immediateRender:!1,time:n,overwrite:"auto",duration:e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale())||X,onStart:function onStart(){if(i.pause(),!r){var t=e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale());h._dur!==t&&Ra(h,t,0,1).render(h._time,!0,!0),r=1}s&&s.apply(h,o||[])}},e));return u?h.render(0):h},e.tweenFromTo=function tweenFromTo(t,e,r){return this.tweenTo(e,qa({startAt:{time:xt(this,t)}},r))},e.recent=function recent(){return this._recent},e.nextLabel=function nextLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t))},e.previousLabel=function previousLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t),1)},e.currentLabel=function currentLabel(t){return arguments.length?this.seek(t,!0):this.previousLabel(this._time+X)},e.shiftChildren=function shiftChildren(t,e,r){void 0===r&&(r=0);for(var i,n=this._first,a=this.labels;n;)n._start>=r&&(n._start+=t,n._end+=t),n=n._next;if(e)for(i in a)a[i]>=r&&(a[i]+=t);return Aa(this)},e.invalidate=function invalidate(t){var e=this._first;for(this._lock=0;e;)e.invalidate(t),e=e._next;return i.prototype.invalidate.call(this,t)},e.clear=function clear(t){void 0===t&&(t=!0);for(var e,r=this._first;r;)e=r._next,this.remove(r),r=e;return this._dp&&(this._time=this._tTime=this._pTime=0),t&&(this.labels={}),Aa(this)},e.totalDuration=function totalDuration(t){var e,r,i,n=0,a=this,s=a._last,o=U;if(arguments.length)return a.timeScale((a._repeat<0?a.duration():a.totalDuration())/(a.reversed()?-t:t));if(a._dirty){for(i=a.parent;s;)e=s._prev,s._dirty&&s.totalDuration(),o<(r=s._start)&&a._sort&&s._ts&&!a._lock?(a._lock=1,Ka(a,s,r-s._delay,1)._lock=0):o=r,r<0&&s._ts&&(n-=r,(!i&&!a._dp||i&&i.smoothChildTiming)&&(a._start+=r/a._ts,a._time-=r,a._tTime-=r),a.shiftChildren(-r,!1,-Infinity),o=0),s._end>n&&s._ts&&(n=s._end),s=e;Ra(a,a===I&&a._time>n?a._time:n,1,1),a._dirty=0}return a._tDur},Timeline.updateRoot=function updateRoot(t){if(I._ts&&(na(I,Ga(t,I)),f=Rt.frame),Rt.frame>=mt){mt+=q.autoSleep||120;var e=I._first;if((!e||!e._ts)&&q.autoSleep&&Rt._listeners.length<2){for(;e&&!e._ts;)e=e._next;e||Rt.sleep()}}},Timeline}(Ut);qa(Xt.prototype,{_lock:0,_hasPause:0,_forcing:0});function ac(t,e,i,n,a,o){var u,h,l,f;if(pt[t]&&!1!==(u=new pt[t]).init(a,u.rawVars?e[t]:function _processVars(t,e,i,n,a){if(s(t)&&(t=Kt(t,a,e,i,n)),!v(t)||t.style&&t.nodeType||Z(t)||$(t))return r(t)?Kt(t,a,e,i,n):t;var o,u={};for(o in t)u[o]=Kt(t[o],a,e,i,n);return u}(e[t],n,a,o,i),i,n,o)&&(i._pt=h=new _e(i._pt,a,t,0,1,u.render,u,0,u.priority),i!==d))for(l=i._ptLookup[i._targets.indexOf(a)],f=u._props.length;f--;)l[u._props[f]]=h;return u}function gc(t,r,e,i){var n,a,s=r.ease||i||"power1.inOut";if(Z(r))a=e[t]||(e[t]=[]),r.forEach(function(t,e){return a.push({t:e/(r.length-1)*100,v:t,e:s})});else for(n in r)a=e[n]||(e[n]=[]),"ease"===n||a.push({t:parseFloat(t),v:r[n],e:s})}var Nt,Gt,Wt=function _addPropTween(t,e,i,n,a,o,u,h,l,f){s(n)&&(n=n(a||0,t,o));var d,c=t[e],p="get"!==i?i:s(c)?l?t[e.indexOf("set")||!s(t["get"+e.substr(3)])?e:"get"+e.substr(3)](l):t[e]():c,_=s(c)?l?re:te:Zt;if(r(n)&&(~n.indexOf("random(")&&(n=ob(n)),"="===n.charAt(1)&&(!(d=ka(p,n)+(Ya(p)||0))&&0!==d||(n=d))),!f||p!==n||Gt)return isNaN(p*n)||""===n?(c||e in t||Q(e,n),function _addComplexStringPropTween(t,e,r,i,n,a,s){var o,u,h,l,f,d,c,p,_=new _e(this._pt,t,e,0,1,ue,null,n),m=0,g=0;for(_.b=r,_.e=i,r+="",(c=~(i+="").indexOf("random("))&&(i=ob(i)),a&&(a(p=[r,i],t,e),r=p[0],i=p[1]),u=r.match(it)||[];o=it.exec(i);)l=o[0],f=i.substring(m,o.index),h?h=(h+1)%5:"rgba("===f.substr(-5)&&(h=1),l!==u[g++]&&(d=parseFloat(u[g-1])||0,_._pt={_next:_._pt,p:f||1===g?f:",",s:d,c:"="===l.charAt(1)?ka(d,l)-d:parseFloat(l)-d,m:h&&h<4?Math.round:0},m=it.lastIndex);return _.c=m")}),s.duration();else{for(l in u={},x)"ease"===l||"easeEach"===l||gc(l,x[l],u,x.easeEach);for(l in u)for(A=u[l].sort(function(t,e){return t.t-e.t}),o=E=0;o=t._tDur||e<0)&&t.ratio===u&&(u&&za(t,1),r||L||(Ct(t,u?"onComplete":"onReverseComplete",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)}(this,t,e,r);return this},e.targets=function targets(){return this._targets},e.invalidate=function invalidate(t){return t&&this.vars.runBackwards||(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(t),D.prototype.invalidate.call(this,t)},e.resetTo=function resetTo(t,e,r,i,n){c||Rt.wake(),this._ts||this.play();var a,s=Math.min(this._dur,(this._dp._time-this._start)*this._ts);return this._initted||Qt(this,s),a=this._ease(s/this._dur),function _updatePropTweens(t,e,r,i,n,a,s,o){var u,h,l,f,d=(t._pt&&t._ptCache||(t._ptCache={}))[e];if(!d)for(d=t._ptCache[e]=[],l=t._ptLookup,f=t._targets.length;f--;){if((u=l[f][e])&&u.d&&u.d._pt)for(u=u.d._pt;u&&u.p!==e&&u.fp!==e;)u=u._next;if(!u)return Gt=1,t.vars[e]="+=0",Qt(t,s),Gt=0,o?R(e+" not eligible for reset"):1;d.push(u)}for(f=d.length;f--;)(u=(h=d[f])._pt||h).s=!i&&0!==i||n?u.s+(i||0)+a*u.c:i,u.c=r-u.s,h.e&&(h.e=ia(r)+Ya(h.e)),h.b&&(h.b=u.s+Ya(h.b))}(this,t,e,r,i,a,s,n)?this.resetTo(t,e,r,i,1):(Ia(this,0),this.parent||xa(this._dp,this,"_first","_last",this._dp._sort?"_start":0),this.render(0))},e.kill=function kill(t,e){if(void 0===e&&(e="all"),!(t||e&&"all"!==e))return this._lazy=this._pt=0,this.parent?tb(this):this;if(this.timeline){var i=this.timeline.totalDuration();return this.timeline.killTweensOf(t,e,Nt&&!0!==Nt.vars.overwrite)._first||tb(this),this.parent&&i!==this.timeline.totalDuration()&&Ra(this,this._dur*this.timeline._tDur/i,0,1),this}var n,a,s,o,u,h,l,f=this._targets,d=t?Mt(t):f,c=this._ptLookup,p=this._pt;if((!e||"all"===e)&&function _arraysMatch(t,e){for(var r=t.length,i=r===e.length;i&&r--&&t[r]===e[r];);return r<0}(f,d))return"all"===e&&(this._pt=0),tb(this);for(n=this._op=this._op||[],"all"!==e&&(r(e)&&(u={},ha(e,function(t){return u[t]=1}),e=u),e=function _addAliasesToVars(t,e){var r,i,n,a,s=t[0]?fa(t[0]).harness:0,o=s&&s.aliases;if(!o)return e;for(i in r=yt({},e),o)if(i in r)for(n=(a=o[i].split(",")).length;n--;)r[a[n]]=r[i];return r}(f,e)),l=f.length;l--;)if(~d.indexOf(f[l]))for(u in a=c[l],"all"===e?(n[l]=e,o=a,s={}):(s=n[l]=n[l]||{},o=e),o)(h=a&&a[u])&&("kill"in h.d&&!0!==h.d.kill(u)||ya(this,h,"_pt"),delete a[u]),"all"!==s&&(s[u]=1);return this._initted&&!this._pt&&p&&tb(this),this},Tween.to=function to(t,e,r){return new Tween(t,e,r)},Tween.from=function from(t,e){return Va(1,arguments)},Tween.delayedCall=function delayedCall(t,e,r,i){return new Tween(e,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:t,onComplete:e,onReverseComplete:e,onCompleteParams:r,onReverseCompleteParams:r,callbackScope:i})},Tween.fromTo=function fromTo(t,e,r){return Va(2,arguments)},Tween.set=function set(t,e){return e.duration=0,e.repeatDelay||(e.repeat=0),new Tween(t,e)},Tween.killTweensOf=function killTweensOf(t,e,r){return I.killTweensOf(t,e,r)},Tween}(Ut);qa($t.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0}),ha("staggerTo,staggerFrom,staggerFromTo",function(r){$t[r]=function(){var t=new Xt,e=kt.call(arguments,0);return e.splice("staggerFromTo"===r?5:4,0,0),t[r].apply(t,e)}});function oc(t,e,r){return t.setAttribute(e,r)}function wc(t,e,r,i){i.mSet(t,e,i.m.call(i.tween,r,i.mt),i)}var Zt=function _setterPlain(t,e,r){return t[e]=r},te=function _setterFunc(t,e,r){return t[e](r)},re=function _setterFuncWithParam(t,e,r,i){return t[e](i.fp,r)},ne=function _getSetter(t,e){return s(t[e])?te:u(t[e])&&t.setAttribute?oc:Zt},ae=function _renderPlain(t,e){return e.set(e.t,e.p,Math.round(1e6*(e.s+e.c*t))/1e6,e)},se=function _renderBoolean(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},ue=function _renderComplexString(t,e){var r=e._pt,i="";if(!t&&e.b)i=e.b;else if(1===t&&e.e)i=e.e;else{for(;r;)i=r.p+(r.m?r.m(r.s+r.c*t):Math.round(1e4*(r.s+r.c*t))/1e4)+i,r=r._next;i+=e.c}e.set(e.t,e.p,i,e)},he=function _renderPropTweens(t,e){for(var r=e._pt;r;)r.r(t,r.d),r=r._next},fe=function _addPluginModifier(t,e,r,i){for(var n,a=this._pt;a;)n=a._next,a.p===i&&a.modifier(t,e,r),a=n},ce=function _killPropTweensOf(t){for(var e,r,i=this._pt;i;)r=i._next,i.p===t&&!i.op||i.op===t?ya(this,i,"_pt"):i.dep||(e=1),i=r;return!e},pe=function _sortPropTweensByPriority(t){for(var e,r,i,n,a=t._pt;a;){for(e=a._next,r=i;r&&r.pr>a.pr;)r=r._next;(a._prev=r?r._prev:n)?a._prev._next=a:i=a,(a._next=r)?r._prev=a:n=a,a=e}t._pt=i},_e=(PropTween.prototype.modifier=function modifier(t,e,r){this.mSet=this.mSet||this.set,this.set=wc,this.m=t,this.mt=r,this.tween=e},PropTween);function PropTween(t,e,r,i,n,a,s,o,u){this.t=e,this.s=i,this.c=n,this.p=r,this.r=a||ae,this.d=s||this,this.set=o||Zt,this.pr=u||0,(this._next=t)&&(t._prev=this)}ha(vt+"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger",function(t){return ft[t]=1}),ot.TweenMax=ot.TweenLite=$t,ot.TimelineLite=ot.TimelineMax=Xt,I=new Xt({sortChildren:!1,defaults:V,autoRemoveChildren:!0,id:"root",smoothChildTiming:!0}),q.stringFilter=Fb;function Ec(t){return(ye[t]||Te).map(function(t){return t()})}function Fc(){var t=Date.now(),o=[];2{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));
--------------------------------------------------------------------------------
/js/index.js:
--------------------------------------------------------------------------------
1 | // Importing utility function for preloading images
2 | import { preloadImages } from './utils.js';
3 | // Importing StackMotionEffect classes from different effect files with renamed imports to avoid name conflicts
4 | import { StackMotionEffect as StackMotionEffect1 } from './effect-1/stackMotionEffect.js';
5 | import { StackMotionEffect as StackMotionEffect2 } from './effect-2/stackMotionEffect.js';
6 | import { StackMotionEffect as StackMotionEffect3 } from './effect-3/stackMotionEffect.js';
7 |
8 | // Registers ScrollTrigger plugin with GSAP for scroll-based animations.
9 | gsap.registerPlugin(ScrollTrigger);
10 |
11 | // Initialize function to set up motion effects and animations
12 | const init = () => {
13 | // Apply the first stack motion effect to all elements with a specific data attribute
14 | document.querySelectorAll('[data-stack-1]').forEach((stackEl) => {
15 | new StackMotionEffect1(stackEl);
16 | });
17 | // Apply the second stack motion effect to all elements with a different specific data attribute
18 | document.querySelectorAll('[data-stack-2]').forEach((stackEl) => {
19 | new StackMotionEffect2(stackEl);
20 | });
21 | // Apply the third stack motion effect to all elements with yet another specific data attribute
22 | document.querySelectorAll('[data-stack-3]').forEach((stackEl) => {
23 | new StackMotionEffect3(stackEl);
24 | });
25 |
26 | // Select all grid intro card elements and apply animations on scroll
27 | const introCards = document.querySelectorAll('.intro .card');
28 | introCards.forEach(introCard => {
29 | gsap.to(introCard, {
30 | ease: 'power1.in',
31 | startAt: {
32 | transformOrigin: '100% 50%',
33 | filter: 'brightness(70%)'
34 | },
35 | rotationX: () => -60,
36 | yPercent: () => gsap.utils.random(-100,0),
37 | z: () => gsap.utils.random(-100,0),
38 | filter: 'brightness(0%)',
39 | scrollTrigger: {
40 | trigger: introCard,
41 | start: 'clamp(top bottom)',
42 | end: 'clamp(bottom top)',
43 | scrub: true,
44 | }
45 | });
46 | });
47 | };
48 |
49 | // Preloading images and initializing setup when complete
50 | preloadImages('.grid__img').then(() => {
51 | document.body.classList.remove('loading');
52 | init();
53 | });
54 |
--------------------------------------------------------------------------------
/js/lenis.js:
--------------------------------------------------------------------------------
1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).Lenis=e()}(this,function(){function t(t,e){for(var i=0;i1,hasPointer:!!window.navigator.msPointerEnabled,hasKeyDown:"onkeydown"in document,isFirefox:navigator.userAgent.indexOf("Firefox")>-1}),i(this,l)[l]=Object.assign({mouseMultiplier:1,touchMultiplier:2,firefoxMultiplier:15,keyStep:120,preventTouch:!1,unpreventTouchClass:"vs-touchmove-allowed",useKeyboard:!0,useTouch:!0},t),i(this,a)[a]=new n,i(this,c)[c]={y:0,x:0,deltaX:0,deltaY:0},i(this,u)[u]={x:null,y:null},i(this,d)[d]=null,void 0!==i(this,l)[l].passive&&(this.listenerOptions={passive:i(this,l)[l].passive})}var e=t.prototype;return e._notify=function(t){var e=i(this,c)[c];e.x+=e.deltaX,e.y+=e.deltaY,i(this,a)[a].emit(s,{x:e.x,y:e.y,deltaX:e.deltaX,deltaY:e.deltaY,originalEvent:t})},e._bind=function(){r.hasWheelEvent&&i(this,h)[h].addEventListener("wheel",this._onWheel,this.listenerOptions),r.hasMouseWheelEvent&&i(this,h)[h].addEventListener("mousewheel",this._onMouseWheel,this.listenerOptions),r.hasTouch&&i(this,l)[l].useTouch&&(i(this,h)[h].addEventListener("touchstart",this._onTouchStart,this.listenerOptions),i(this,h)[h].addEventListener("touchmove",this._onTouchMove,this.listenerOptions)),r.hasPointer&&r.hasTouchWin&&(i(this,d)[d]=document.body.style.msTouchAction,document.body.style.msTouchAction="none",i(this,h)[h].addEventListener("MSPointerDown",this._onTouchStart,!0),i(this,h)[h].addEventListener("MSPointerMove",this._onTouchMove,!0)),r.hasKeyDown&&i(this,l)[l].useKeyboard&&document.addEventListener("keydown",this._onKeyDown)},e._unbind=function(){r.hasWheelEvent&&i(this,h)[h].removeEventListener("wheel",this._onWheel),r.hasMouseWheelEvent&&i(this,h)[h].removeEventListener("mousewheel",this._onMouseWheel),r.hasTouch&&(i(this,h)[h].removeEventListener("touchstart",this._onTouchStart),i(this,h)[h].removeEventListener("touchmove",this._onTouchMove)),r.hasPointer&&r.hasTouchWin&&(document.body.style.msTouchAction=i(this,d)[d],i(this,h)[h].removeEventListener("MSPointerDown",this._onTouchStart,!0),i(this,h)[h].removeEventListener("MSPointerMove",this._onTouchMove,!0)),r.hasKeyDown&&i(this,l)[l].useKeyboard&&document.removeEventListener("keydown",this._onKeyDown)},e.on=function(t,e){i(this,a)[a].on(s,t,e);var o=i(this,a)[a].e;o&&o[s]&&1===o[s].length&&this._bind()},e.off=function(t,e){i(this,a)[a].off(s,t,e);var o=i(this,a)[a].e;(!o[s]||o[s].length<=0)&&this._unbind()},e.destroy=function(){i(this,a)[a].off(),this._unbind()},t}()}()}(e),e.exports}();function l(t,e){var i=t%e;return(e>0&&i<0||e<0&&i>0)&&(i+=e),i}var h=["duration","easing"],a=/*#__PURE__*/function(){function t(){}var o=t.prototype;return o.to=function(t,e){var o=this,n=void 0===e?{}:e,r=n.duration,s=void 0===r?1:r,l=n.easing,a=void 0===l?function(t){return t}:l,c=function(t,e){if(null==t)return{};var i,o,n={},r=Object.keys(t);for(o=0;o=0||(n[i]=t[i]);return n}(n,h);this.target=t,this.fromKeys=i({},c),this.toKeys=i({},c),this.keys=Object.keys(i({},c)),this.keys.forEach(function(e){o.fromKeys[e]=t[e]}),this.duration=s,this.easing=a,this.currentTime=0,this.isRunning=!0},o.stop=function(){this.isRunning=!1},o.raf=function(t){var e=this;if(this.isRunning){this.currentTime=Math.min(this.currentTime+t,this.duration);var i=this.progress>=1?1:this.easing(this.progress);this.keys.forEach(function(t){var o=e.fromKeys[t];e.target[t]=o+(e.toKeys[t]-o)*i}),1===i&&this.stop()}},e(t,[{key:"progress",get:function(){return this.currentTime/this.duration}}]),t}();/*#__PURE__*/
2 | return function(t){var i,n;function r(e){var i,o,n,r,l=void 0===e?{}:e,h=l.duration,c=void 0===h?1.2:h,u=l.easing,d=void 0===u?function(t){return Math.min(1,1.001-Math.pow(2,-10*t))}:u,p=l.smooth,f=void 0===p||p,v=l.mouseMultiplier,w=void 0===v?1:v,y=l.smoothTouch,m=void 0!==y&&y,g=l.touchMultiplier,b=void 0===g?2:g,T=l.direction,M=void 0===T?"vertical":T,S=l.gestureDirection,_=void 0===S?"vertical":S,O=l.infinite,E=void 0!==O&&O,W=l.wrapper,x=void 0===W?window:W,D=l.content,N=void 0===D?document.body:D;(r=t.call(this)||this).onWindowResize=function(){r.wrapperWidth=window.innerWidth,r.wrapperHeight=window.innerHeight},r.onWrapperResize=function(t){var e=t[0];if(e){var i=e.contentRect;r.wrapperWidth=i.width,r.wrapperHeight=i.height}},r.onContentResize=function(t){var e=t[0];if(e){var i=e.contentRect;r.contentWidth=i.width,r.contentHeight=i.height}},r.onVirtualScroll=function(t){var e=t.deltaY,i=t.deltaX,o=t.originalEvent;if(!("vertical"===r.gestureDirection&&0===e||"horizontal"===r.gestureDirection&&0===i)){var n=!!o.composedPath().find(function(t){return t.hasAttribute&&t.hasAttribute("data-lenis-prevent")});o.ctrlKey||n||(r.smooth=o.changedTouches?r.smoothTouch:r.options.smooth,r.stopped?o.preventDefault():r.smooth&&4!==o.buttons&&(r.smooth&&o.preventDefault(),r.targetScroll-="both"===r.gestureDirection?i+e:"horizontal"===r.gestureDirection?i:e,r.scrollTo(r.targetScroll)))}},r.onScroll=function(t){r.isScrolling&&r.smooth||(r.targetScroll=r.scroll=r.lastScroll=r.wrapperNode[r.scrollProperty],r.notify())},window.lenisVersion="0.2.28",r.options={duration:c,easing:d,smooth:f,mouseMultiplier:w,smoothTouch:m,touchMultiplier:b,direction:M,gestureDirection:_,infinite:E,wrapper:x,content:N},r.duration=c,r.easing=d,r.smooth=f,r.mouseMultiplier=w,r.smoothTouch=m,r.touchMultiplier=b,r.direction=M,r.gestureDirection=_,r.infinite=E,r.wrapperNode=x,r.contentNode=N,r.wrapperNode.addEventListener("scroll",r.onScroll),r.wrapperNode===window?(r.wrapperNode.addEventListener("resize",r.onWindowResize),r.onWindowResize()):(r.wrapperHeight=r.wrapperNode.offsetHeight,r.wrapperWidth=r.wrapperNode.offsetWidth,r.wrapperObserver=new ResizeObserver(r.onWrapperResize),r.wrapperObserver.observe(r.wrapperNode)),r.contentHeight=r.contentNode.offsetHeight,r.contentWidth=r.contentNode.offsetWidth,r.contentObserver=new ResizeObserver(r.onContentResize),r.contentObserver.observe(r.contentNode),r.targetScroll=r.scroll=r.lastScroll=r.wrapperNode[r.scrollProperty],r.animate=new a;var P=(null==(i=navigator)||null==(o=i.userAgentData)?void 0:o.platform)||(null==(n=navigator)?void 0:n.platform)||"unknown";return r.virtualScroll=new s({el:r.wrapperNode,firefoxMultiplier:50,mouseMultiplier:r.mouseMultiplier*(P.includes("Win")||P.includes("Linux")?.84:.4),touchMultiplier:r.touchMultiplier,passive:!1,useKeyboard:!1,useTouch:!0}),r.virtualScroll.on(r.onVirtualScroll),r}n=t,(i=r).prototype=Object.create(n.prototype),i.prototype.constructor=i,o(i,n);var h=r.prototype;return h.start=function(){var t=this.wrapperNode;this.wrapperNode===window&&(t=document.documentElement),t.classList.remove("lenis-stopped"),this.stopped=!1},h.stop=function(){var t=this.wrapperNode;this.wrapperNode===window&&(t=document.documentElement),t.classList.add("lenis-stopped"),this.stopped=!0,this.animate.stop()},h.destroy=function(){var t;this.wrapperNode===window&&this.wrapperNode.removeEventListener("resize",this.onWindowResize),this.wrapperNode.removeEventListener("scroll",this.onScroll),this.virtualScroll.destroy(),null==(t=this.wrapperObserver)||t.disconnect(),this.contentObserver.disconnect()},h.raf=function(t){var e=t-(this.now||0);this.now=t,!this.stopped&&this.smooth&&(this.lastScroll=this.scroll,this.animate.raf(.001*e),this.scroll===this.targetScroll&&(this.lastScroll=this.scroll),this.isScrolling&&(this.setScroll(this.scroll),this.notify()),this.isScrolling=this.scroll!==this.targetScroll)},h.setScroll=function(t){var e=this.infinite?l(t,this.limit):t;"horizontal"===this.direction?this.wrapperNode.scrollTo(e,0):this.wrapperNode.scrollTo(0,e)},h.notify=function(){var t=this.infinite?l(this.scroll,this.limit):this.scroll;this.emit("scroll",{scroll:t,limit:this.limit,velocity:this.velocity,direction:0===this.velocity?0:this.velocity>0?1:-1,progress:t/this.limit})},h.scrollTo=function(t,e){var i=void 0===e?{}:e,o=i.offset,n=void 0===o?0:o,r=i.immediate,s=void 0!==r&&r,l=i.duration,h=void 0===l?this.duration:l,a=i.easing,c=void 0===a?this.easing:a;if(null!=t&&!this.stopped){var u;if("number"==typeof t)u=t;else if("top"===t||"#top"===t)u=0;else if("bottom"===t)u=this.limit;else{var d;if("string"==typeof t)d=document.querySelector(t);else{if(null==t||!t.nodeType)return;d=t}if(!d)return;var p=0;if(this.wrapperNode!==window){var f=this.wrapperNode.getBoundingClientRect();p="horizontal"===this.direction?f.left:f.top}var v=d.getBoundingClientRect();u=("horizontal"===this.direction?v.left:v.top)+this.scroll-p}u+=n,this.targetScroll=this.infinite?u:Math.max(0,Math.min(u,this.limit)),!this.smooth||s?(this.animate.stop(),this.scroll=this.lastScroll=this.targetScroll,this.setScroll(this.targetScroll)):this.animate.to(this,{duration:h,easing:c,scroll:this.targetScroll})}},e(r,[{key:"scrollProperty",get:function(){return this.wrapperNode===window?"horizontal"===this.direction?"scrollX":"scrollY":"horizontal"===this.direction?"scrollLeft":"scrollTop"}},{key:"limit",get:function(){return"horizontal"===this.direction?this.contentWidth-this.wrapperWidth:this.contentHeight-this.wrapperHeight}},{key:"velocity",get:function(){return this.scroll-this.lastScroll}}]),r}(r)});
--------------------------------------------------------------------------------
/js/smoothscroll.js:
--------------------------------------------------------------------------------
1 | // Initializes smooth scrolling with Lenis and integrates it with GSAP's ScrollTrigger.
2 | // Function to set up smooth scrolling.
3 | const initSmoothScrolling = () => {
4 | // Initialize Lenis for smooth scroll effects. Lerp value controls the smoothness.
5 | const lenis = new Lenis({ lerp: 0.2 });
6 |
7 | // Sync ScrollTrigger with Lenis' scroll updates.
8 | lenis.on('scroll', ScrollTrigger.update);
9 |
10 | // Ensure GSAP animations are in sync with Lenis' scroll frame updates.
11 | gsap.ticker.add((time) => {
12 | lenis.raf(time * 1000); // Convert GSAP's time to milliseconds for Lenis.
13 | });
14 |
15 | // Turn off GSAP's default lag smoothing to avoid conflicts with Lenis.
16 | gsap.ticker.lagSmoothing(0);
17 | };
18 |
19 | // Activate the smooth scrolling feature.
20 | initSmoothScrolling();
21 |
--------------------------------------------------------------------------------
/js/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Preloads images specified by the CSS selector.
3 | * @function
4 | * @param {string} [selector='img'] - CSS selector for target images.
5 | * @returns {Promise} - Resolves when all specified images are loaded.
6 | */
7 | export const preloadImages = (selector = 'img') => {
8 | return new Promise((resolve) => {
9 | // The imagesLoaded library is used to ensure all images (including backgrounds) are fully loaded.
10 | imagesLoaded(document.querySelectorAll(selector), {background: true}, resolve);
11 | });
12 | };
13 |
14 | /**
15 | * Throttles a function call, allowing it to be executed only once every specified time period.
16 | * This is useful for controlling the rate at which a function is executed, preventing it from being called too frequently.
17 | * @function
18 | * @param {Function} func - The function to be throttled.
19 | * @param {number} limit - The time, in milliseconds, to wait before allowing the function to be called again.
20 | * @returns {Function} - A throttled version of the passed function, which when invoked, will only execute
21 | * at most once in every `limit` milliseconds, and ignores subsequent calls within the same period.
22 | */
23 | export const throttle = (func, limit) => {
24 | let inThrottle;
25 | return function() {
26 | const args = arguments;
27 | const context = this;
28 | if (!inThrottle) {
29 | func.apply(context, args);
30 | inThrottle = true;
31 | setTimeout(() => inThrottle = false, limit);
32 | }
33 | };
34 | };
--------------------------------------------------------------------------------