├── .DS_Store
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── css
└── base.css
├── favicon.ico
├── img
├── .DS_Store
├── 1.jpg
├── 10.jpg
├── 11.jpg
├── 12.jpg
├── 13.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
├── 8.jpg
├── 9.jpg
├── main.jpg
└── noise.png
├── index.html
└── js
├── .DS_Store
├── Flip.min.js
├── ScrollTrigger.min.js
├── gsap.min.js
├── imagesloaded.pkgd.min.js
├── index.js
├── lenis.min.js
├── smoothscroll.js
└── utils.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/.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 | # Consecutive Scroll Animations with One Element
2 |
3 | A simple concept of animating one element across different waypoints on scroll using GSAP Flip and ScrollTrigger.
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=82884)
8 |
9 | [Demo](https://tympanus.net/Development/OneElementScroll/)
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: [Bluesky](https://bsky.app/profile/codrops.bsky.social), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/), [X](http://www.x.com/codrops)
22 |
23 | ## License
24 | [MIT](LICENSE)
25 |
26 | Made with :blue_heart: by [Codrops](http://www.codrops.com)
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/css/base.css:
--------------------------------------------------------------------------------
1 | *,
2 | *::after,
3 | *::before {
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | font-size: 16px;
9 | --color-text: #503717;
10 | --color-bg: rgb(234 234 234);
11 | --color-link: #b19162;
12 | --color-link-hover: #e1c093;
13 | --color-title: #000;
14 | --page-padding: 2rem;
15 | --gradient-1: rgb(234 234 234 / 80%);
16 | --gradient-2: rgb(229 134 27 / 30%);
17 | }
18 |
19 | body {
20 | margin: 0;
21 | color: var(--color-text);
22 | background-color: var(--color-bg);
23 | font-family: "capitana", sans-serif;
24 | -webkit-font-smoothing: antialiased;
25 | -moz-osx-font-smoothing: grayscale;
26 | width: 100vw;
27 | overflow-x: hidden;
28 | background-image: url(../img/noise.png), radial-gradient(ellipse at top, var(--gradient-1), transparent), radial-gradient(ellipse at bottom, var(--gradient-2), transparent);
29 | background-size: 180px, 100%, 200%;
30 | background-attachment: fixed;
31 | }
32 |
33 | .font-alt {
34 | font-family: "harpagan", sans-serif;
35 | font-weight: 500;
36 | }
37 |
38 | .outro__title,
39 | .credits {
40 | font-size: clamp(1rem,5vw,3rem);
41 | text-transform: uppercase;
42 | text-align: center;
43 | margin: 50vh auto 0;
44 | padding-bottom: 10vh;
45 | }
46 |
47 | .js .loading:before,.js .loading:after {
48 | content: "";
49 | position: fixed;
50 | z-index: 10000
51 | }
52 |
53 | .js .loading:before {
54 | top: 0;
55 | left: 0;
56 | width: 100%;
57 | height: 100%;
58 | background: var(--color-bg)
59 | }
60 |
61 | .js .loading:after {
62 | top: 50%;
63 | left: 50%;
64 | width: 100px;
65 | height: 1px;
66 | margin: 0 0 0 -50px;
67 | background: var(--color-link);
68 | animation: loaderAnim 1.5s ease-in-out infinite alternate forwards
69 | }
70 |
71 | @keyframes loaderAnim {
72 | 0% {
73 | transform: scaleX(0);
74 | transform-origin: 0% 50%
75 | }
76 |
77 | 50% {
78 | transform: scaleX(1);
79 | transform-origin: 0% 50%
80 | }
81 |
82 | 50.1% {
83 | transform: scaleX(1);
84 | transform-origin: 100% 50%
85 | }
86 |
87 | to {
88 | transform: scaleX(0);
89 | transform-origin: 100% 50%
90 | }
91 | }
92 |
93 | a {
94 | text-decoration: none;
95 | color: var(--color-link);
96 | outline: none;
97 | cursor: pointer;
98 | }
99 |
100 | a:hover {
101 | color: var(--color-link-hover);
102 | outline: none;
103 | }
104 |
105 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
106 | a:focus {
107 | /* Provide a fallback style for browsers
108 | that don't support :focus-visible */
109 | outline: none;
110 | background: lightgrey;
111 | }
112 |
113 | a:focus:not(:focus-visible) {
114 | /* Remove the focus indicator on mouse-focus for browsers
115 | that do support :focus-visible */
116 | background: transparent;
117 | }
118 |
119 | a:focus-visible {
120 | /* Draw a very noticeable focus style for
121 | keyboard-focus on browsers that do support
122 | :focus-visible */
123 | outline: 2px solid red;
124 | background: transparent;
125 | }
126 |
127 | main {
128 | position: relative;
129 | overflow: hidden;
130 | width: 100vw;
131 | }
132 |
133 | .unbutton {
134 | background: none;
135 | border: 0;
136 | padding: 0;
137 | margin: 0;
138 | font: inherit;
139 | cursor: pointer;
140 | }
141 |
142 | .unbutton:focus {
143 | outline: none;
144 | }
145 |
146 | .frame {
147 | position: fixed;
148 | margin: 10px;
149 | top: 0;
150 | left: 0;
151 | right: 0;
152 | display: grid;
153 | z-index: 6000;
154 | grid-template-columns: 100%;
155 | grid-template-areas: 'title' 'wrap' 'sponsor';
156 | justify-items: start;
157 | align-items: start;
158 | }
159 |
160 | .font-cap {
161 | text-transform: uppercase;
162 | font-size: 10px;
163 | }
164 |
165 | .frame__title {
166 | grid-area: title;
167 | font-size: inherit;
168 | margin: 0;
169 | font-weight: inherit;
170 | padding: 5px 0;
171 | }
172 |
173 | .frame-wrap {
174 | max-width: 22rem;
175 | grid-area: wrap;
176 | justify-self: start;
177 | display: flex;
178 | flex-wrap: wrap;
179 | column-gap: 1rem;
180 | padding: 5px 13px;
181 | border-radius: 2rem;
182 | background: #000;
183 | }
184 |
185 | .frame #cdawrap {
186 | opacity: 1;
187 | padding: 5px 0;
188 | transition: opacity 0.3s 1s linear;
189 | max-width: 300px;
190 | }
191 |
192 | .frame #cdawrap a {
193 | color: var(--color-text) !important;
194 | }
195 |
196 | .loading .frame #cdawrap {
197 | opacity: 0;
198 | }
199 |
200 | .tags {
201 | display: flex;
202 | flex-wrap: wrap;
203 | gap: 1rem;
204 | align-self: start;
205 | }
206 |
207 | .content {
208 | display: grid;
209 | align-items: center;
210 | justify-content: center;
211 | width: 100%;
212 | height: 100vh;
213 | grid-template-columns: 1fr;
214 | grid-template-rows: auto;
215 | grid-template-areas: 'content';
216 | position: relative;
217 | z-index: 90;
218 | }
219 |
220 | .content--blend {
221 | mix-blend-mode: overlay;
222 | }
223 |
224 | .content--center {
225 | height: 100vh;
226 | text-align: center;
227 | justify-items: center;
228 | display: grid;
229 | gap: 1.5rem;
230 | align-content: center;
231 | position: relative;
232 | }
233 |
234 | .content--column {
235 | grid-template-columns: repeat(5,1fr);
236 | grid-template-areas: unset;
237 | gap: 2rem;
238 | max-width: 1400px;
239 | margin: 0 auto 20vh;
240 | z-index: 80;
241 | justify-items: center;
242 | }
243 |
244 | .content--grid {
245 | grid-template-columns: repeat(3,1fr);
246 | grid-template-rows: repeat(3,1fr);
247 | grid-template-areas: unset;
248 | width: 120%;
249 | height: 100vh;
250 | left: -10%;
251 | gap: 1rem;
252 | margin: 0 auto;
253 | }
254 |
255 | .content--grid .content__img {
256 | width: 100%;
257 | height: 100%;
258 | }
259 |
260 | .content__title {
261 | grid-area: content;
262 | margin: 0;
263 | line-height: .9;
264 | margin: 0;
265 | text-transform: uppercase;
266 | font-size: clamp(3rem,19vw,8rem);
267 | max-width: 1000px;
268 | color: var(--color-title);
269 | }
270 |
271 | .content__title span {
272 | display: inline-block;
273 | }
274 |
275 | .content__title--medium {
276 | line-height: 1.1;
277 | max-width: none;
278 | font-size: clamp(2rem,12vw,6rem);
279 | }
280 |
281 | .content__text {
282 | grid-area: content;
283 | padding: var(--page-padding);
284 | margin: 0 auto;
285 | font-size: 1rem;
286 | font-weight: 400;
287 | position: relative;
288 | max-width: 500px;
289 | }
290 |
291 | .content__text--large {
292 | font-size: clamp(1rem,4vw,2rem);
293 | max-width: none;
294 | }
295 |
296 | .one {
297 | width: 100%;
298 | height: 100%;
299 | position: relative;
300 | z-index: 10;
301 | background-size: cover;
302 | background-position: 50% 50%;
303 | will-change: transform, width, height, filter;
304 | }
305 |
306 | .content__img {
307 | background-size: cover;
308 | background-position: 50% 50%;
309 | will-change: transform, filter, opacity;
310 | }
311 |
312 | .content--sides {
313 | display: grid;
314 | grid-template-columns: 1fr;
315 | grid-template-areas: 'img' 'content';
316 | }
317 |
318 | .content--sides .content__img {
319 | grid-area: img;
320 | height: 50vh;
321 | }
322 |
323 | .content--center .content__img {
324 | height: 38vh;
325 | width: auto;
326 | aspect-ratio: 0.8;
327 | grid-area: 1 / 1 / -1 / -1;
328 | }
329 |
330 | .content--center-tall {
331 | padding-top: 20vh;
332 | margin-bottom: 30vh;
333 | }
334 |
335 | .content--center-tall .content__img {
336 | height: 30vh;
337 | width: auto;
338 | aspect-ratio: 0.8;
339 | }
340 |
341 | .content--column .content__img {
342 | height: auto;
343 | width: 100%;
344 | max-width: 150px;
345 | aspect-ratio: 0.8;
346 | background-size: cover;
347 | background-position: 50% 50%;
348 | }
349 |
350 | .content--lines {
351 | display: flex;
352 | flex-direction: column;
353 | }
354 |
355 | .content--lines .content__title {
356 | display: flex;
357 | flex-wrap: wrap;
358 | align-self: center;
359 | gap: 10px;
360 | }
361 |
362 | .content--lines .content__img {
363 | height: 0.725em;
364 | width: auto;
365 | aspect-ratio: 16/9;
366 | background-size: cover;
367 | align-self: center;
368 | flex: none;
369 | }
370 |
371 | .outro {
372 | display: grid;
373 | place-items: center;
374 | margin: 40vh 0;
375 | padding: 0 10vw;
376 | }
377 |
378 | .outro__title {
379 | font-weight: 300;
380 | margin-bottom: 3rem;
381 | }
382 |
383 | .card-wrap {
384 | width: 100%;
385 | display: grid;
386 | grid-gap: 2rem;
387 | grid-auto-flow: row;
388 | grid-auto-columns: 1fr;
389 | justify-items: center;
390 | justify-content: center;
391 | }
392 |
393 | .card {
394 | width: 100%;
395 | max-width: 255px;
396 | min-width: 150px;
397 | gap: 1rem;
398 | display: flex;
399 | flex-direction: column;
400 | position: relative;
401 | }
402 |
403 | .card__img {
404 | background-size: cover;
405 | background-position: 50% 50%;
406 | aspect-ratio: 1;
407 | max-width: 100%;
408 | }
409 |
410 | .card__title a {
411 | color: var(--color-text);
412 | }
413 |
414 | @media screen and (min-width: 53em) {
415 | .frame {
416 | grid-template-columns: 25% 50% 25%;
417 | grid-template-areas: 'title wrap sponsor';
418 | }
419 | .frame-wrap {
420 | justify-self: center;
421 | }
422 | .frame #cdawrap {
423 | max-width: 300px;
424 | text-align: right;
425 | justify-self: end;
426 | }
427 | .card-wrap {
428 | grid-auto-flow: column;
429 | }
430 | .content--sides {
431 | grid-template-columns: 40% 1fr;
432 | grid-template-areas: 'img content';
433 | }
434 | .content--lines .content__title {
435 | white-space: nowrap;
436 | flex-wrap: nowrap;
437 | }
438 | .content--grid {
439 | height: 160vh;
440 | }
441 | }
442 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/favicon.ico
--------------------------------------------------------------------------------
/img/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/.DS_Store
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/1.jpg
--------------------------------------------------------------------------------
/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/10.jpg
--------------------------------------------------------------------------------
/img/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/11.jpg
--------------------------------------------------------------------------------
/img/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/12.jpg
--------------------------------------------------------------------------------
/img/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/13.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/2.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/3.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/4.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/5.jpg
--------------------------------------------------------------------------------
/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/6.jpg
--------------------------------------------------------------------------------
/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/7.jpg
--------------------------------------------------------------------------------
/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/8.jpg
--------------------------------------------------------------------------------
/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/9.jpg
--------------------------------------------------------------------------------
/img/main.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/main.jpg
--------------------------------------------------------------------------------
/img/noise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/img/noise.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | One Element Scroll | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
One Element Scroll
18 |
27 |
28 |
31 |
32 |
33 | Seraph Kamos
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | Natural
Garments
44 | Crafted with
love
45 | with
respect
46 |
47 |
48 |
49 |
50 |
Welcome to Seraph Kamos where time meets the eternal.
51 | We believe in crafting more than garments—we create connections. Connections to the earth, to human hands, and to the moments that matter. Our designs are born from natural fabrics, each fiber carrying the whispers of its origin: the rustle of flax in a summer breeze, the soft strength of organic cotton, the warmth of wool from sheep raised with care.
52 |
53 |
54 |
55 |
56 |
57 |
We honor the hands that touch every thread, partnering with artisans and communities to ensure fairness, respect, and dignity at every step. No shortcuts, no exploitation—just honest, thoughtful craftsmanship. Every piece you wear carries a story, one rooted in sustainability, transparency, and timeless design.
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | More you might like
73 |
74 |
80 |
86 |
92 |
100 |
108 |
109 |
110 | Browse all demos
111 | Made by @codrops
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/js/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OneElementScroll/feb7ad7fbc602b8cdbb5109da83442ff5995cdaf/js/.DS_Store
--------------------------------------------------------------------------------
/js/Flip.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Flip 3.11.4
3 | * https://greensock.com
4 | *
5 | * @license Copyright 2022, GreenSock. All rights reserved.
6 | * Subject to the terms at https://greensock.com/standard-license or for Club GreenSock 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 p(t){var e=t.ownerDocument||t;!(w in t.style)&&"msTransform"in t.style&&(S=(w="msTransform")+"Origin");for(;e.parentNode&&(e=e.parentNode););if(y=window,d=new _,e){r=(g=e).documentElement,b=e.body,(a=g.createElementNS("http://www.w3.org/2000/svg","g")).style.transform="none";var i=e.createElement("div"),n=e.createElement("div");b.appendChild(i),i.appendChild(n),i.style.position="static",i.style[w]="translate3d(0,0,1px)",m=n.offsetParent!==i,b.removeChild(i)}return e}function t(){return y.pageYOffset||g.scrollTop||r.scrollTop||b.scrollTop||0}function u(){return y.pageXOffset||g.scrollLeft||r.scrollLeft||b.scrollLeft||0}function v(t){return t.ownerSVGElement||("svg"===(t.tagName+"").toLowerCase()?t:null)}function x(t,e){if(t.parentNode&&(g||p(t))){var i=v(t),n=i?i.getAttribute("xmlns")||"http://www.w3.org/2000/svg":"http://www.w3.org/1999/xhtml",r=i?e?"rect":"g":"div",a=2!==e?0:100,s=3===e?100:0,o="position:absolute;display:block;pointer-events:none;margin:0;padding:0;",l=g.createElementNS?g.createElementNS(n.replace(/^https/,"http"),r):g.createElement(r);return e&&(i?(f=f||x(t),l.setAttribute("width",.01),l.setAttribute("height",.01),l.setAttribute("transform","translate("+a+","+s+")"),f.appendChild(l)):(c||((c=x(t)).style.cssText=o),l.style.cssText=o+"width:0.1px;height:0.1px;top:"+s+"px;left:"+a+"px",c.appendChild(l))),l}throw"Need document and parent."}function z(t){var e,i=t.getCTM();return i||(e=t.style[w],t.style[w]="none",t.appendChild(a),i=a.getCTM(),t.removeChild(a),e?t.style[w]=e:t.style.removeProperty(w.replace(/([A-Z])/g,"-$1").toLowerCase())),i||d.clone()}function A(t,e){var i,n,r,a,s,o,l=v(t),u=t===l,p=l?k:C,h=t.parentNode;if(t===y)return t;if(p.length||p.push(x(t,1),x(t,2),x(t,3)),i=l?f:c,l)u?(a=-(r=z(t)).e/r.a,s=-r.f/r.d,n=d):t.getBBox?(r=t.getBBox(),a=(n=(n=t.transform?t.transform.baseVal:{}).numberOfItems?1=o;t&&!n&&ga(G,!x),F&&W(e,F,t?"remove":"add")})},k&&(S=G.filter(function(t){return!t.sd&&!t.a.isVisible&&t.b.isVisible}).map(function(t){return t.a.element})),tt?(S&&(v=tt._abs).push.apply(v,ja(G,S)),tt._run.push(m)):(S&&ka(ja(G,S)),m());var J=tt?tt.timeline:D;return J.revert=function(){return lt(J,1)},J}function Ca(t){for(var e,i=t.idLookup={},n=t.alt={},r=t.elementStates,a=r.length;a--;)i[(e=r[a]).id]?n[e.id]=e:i[e.id]=e}var T,Q,tt,s,o,P,l,n,h=1,E={},O=180/Math.PI,N=Math.PI/180,M={},F={},et={},it=R("onStart,onUpdate,onComplete,onReverseComplete,onInterrupt"),nt=R("transform,transformOrigin,width,height,position,top,left,opacity,zIndex,maxWidth,maxHeight,minWidth,minHeight"),rt={zIndex:1,kill:1,simple:1,spin:1,clearProps:1,targets:1,toggleClass:1,onComplete:1,onUpdate:1,onInterrupt:1,onStart:1,delay:1,repeat:1,repeatDelay:1,yoyo:1,scale:1,fade:1,absolute:1,props:1,onEnter:1,onLeave:1,custom:1,paused:1,nested:1,prune:1,absoluteOnLeave:1},at={zIndex:1,simple:1,clearProps:1,scale:1,absolute:1,fitChild:1,getVars:1,props:1},st={},I="paddingTop,paddingRight,paddingBottom,paddingLeft,gridArea,transition".split(","),L=function _parseElementState(t,e,i,n){return t instanceof pt?t:t instanceof ut?function _findElStateInState(t,e){return e&&t.idLookup[L(e).id]||t.elementStates[0]}(t,n):new pt("string"==typeof t?U(t)||console.warn(t+" not found"):t,e,i)},ot=function _fit(t,e,i,n,r,a){var s,o,l,u,p,h,c,f=t.element,d=t.cache,m=t.parent,g=t.x,y=t.y,v=e.width,x=e.height,b=e.scaleX,w=e.scaleY,S=e.rotation,k=e.bounds,C=a&&f.style.cssText,_=a&&f.getBBox&&f.getAttribute("transform"),E=t,B=e.matrix,M=B.e,F=B.f,I=t.bounds.width!==k.width||t.bounds.height!==k.height||t.scaleX!==b||t.scaleY!==w||t.rotation!==S,L=!I&&t.simple&&e.simple&&!r;return L||!m?(b=w=1,S=s=0):(h=(p=function _getInverseGlobalMatrix(t){var e=t._gsap||Q.core.getCache(t);return e.gmCache===Q.ticker.frame?e.gMatrix:(e.gmCache=Q.ticker.frame,e.gMatrix=getGlobalMatrix(t,!0,!1,!0))}(m)).clone().multiply(e.ctm?e.matrix.clone().multiply(e.ctm):e.matrix),S=V(Math.atan2(h.b,h.a)*O),s=V(Math.atan2(h.c,h.d)*O+S)%360,b=Math.sqrt(Math.pow(h.a,2)+Math.pow(h.b,2)),w=Math.sqrt(Math.pow(h.c,2)+Math.pow(h.d,2))*Math.cos(s*N),r&&(r=T(r)[0],u=Q.getProperty(r),c=r.getBBox&&"function"==typeof r.getBBox&&r.getBBox(),E={scaleX:u("scaleX"),scaleY:u("scaleY"),width:c?c.width:Math.ceil(parseFloat(u("width","px"))),height:c?c.height:parseFloat(u("height","px"))}),d.rotation=S+"deg",d.skewX=s+"deg"),i?(b*=v!==E.width&&E.width?v/E.width:1,w*=x!==E.height&&E.height?x/E.height:1,d.scaleX=b,d.scaleY=w):(v=P(v*b/E.scaleX,0),x=P(x*w/E.scaleY,0),f.style.width=v+"px",f.style.height=x+"px"),n&&oa(f,e.props),L||!m?(g+=M-t.matrix.e,y+=F-t.matrix.f):I||m!==e.parent?(d.renderTransform(1,d),h=getGlobalMatrix(r||f,!1,!1,!0),o=p.apply({x:h.e,y:h.f}),g+=(l=p.apply({x:M,y:F})).x-o.x,y+=l.y-o.y):(p.e=p.f=0,g+=(l=p.apply({x:M-t.matrix.e,y:F-t.matrix.f})).x,y+=l.y),g=P(g,.02),y=P(y,.02),!a||a instanceof pt?(d.x=g+"px",d.y=y+"px",d.renderTransform(1,d)):(f.style.cssText=C,f.getBBox&&f.setAttribute("transform",_||""),d.uncache=1),a&&(a.x=g,a.y=y,a.rotation=S,a.skewX=s,i?(a.scaleX=b,a.scaleY=w):(a.width=v,a.height=x)),a||d},X=[],D="width,height,overflowX,overflowY".split(","),lt=function _killFlip(t,e){if(t&&t.progress()<1&&!t.paused())return e&&(function _interrupt(t){t.vars.onInterrupt&&t.vars.onInterrupt.apply(t,t.vars.onInterruptParams||[]),t.getChildren(!0,!1,!0).forEach(_interrupt)}(t),e<2&&t.progress(1),t.kill()),!0},ut=((n=FlipState.prototype).update=function update(t){var e=this;return this.elementStates=this.targets.map(function(t){return new pt(t,e.props,e.simple)}),Ca(this),this.interrupt(t),this.recordInlineStyles(),this},n.clear=function clear(){return this.targets.length=this.elementStates.length=0,Ca(this),this},n.fit=function fit(t,e,i){for(var n,r,a=da(this.elementStates.slice(0),!1,!0),s=(t||this).idLookup,o=0;o=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(),1e3a;)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 | import { preloadImages } from './utils.js'; // Import utility function to preload images
2 |
3 | gsap.registerPlugin(ScrollTrigger, Flip); // Register GSAP's ScrollTrigger and Flip plugins
4 |
5 | // Select the element that will be animated with Flip and its parent
6 | const oneElement = document.querySelector('.one');
7 | const parentElement = oneElement.parentNode;
8 |
9 | // Select all elements with a `data-step` attribute for the Flip animation steps
10 | const stepElements = [...document.querySelectorAll('[data-step]')];
11 |
12 | let flipCtx; // Variable to store the Flip animation context
13 |
14 | // Function to create a Flip animation tied to scroll events
15 | const createFlipOnScrollAnimation = () => {
16 | // Revert any previous animation context
17 | flipCtx && flipCtx.revert();
18 |
19 | flipCtx = gsap.context(() => {
20 | const flipConfig = {
21 | duration: 1, // Duration of each Flip animation
22 | ease: 'sine.inOut' // Easing for smooth transitions
23 | };
24 |
25 | // Store Flip states for each step element
26 | const states = stepElements.map(stepElement => Flip.getState(stepElement));
27 |
28 | // Create a GSAP timeline with ScrollTrigger for the Flip animation
29 | const tl = gsap.timeline({
30 | scrollTrigger: {
31 | trigger: parentElement, // Trigger animation based on the parent element
32 | start: 'clamp(center center)', // Start animation when parent is in the center of the viewport
33 | endTrigger: stepElements[stepElements.length - 1], // End at the last step element
34 | end: 'clamp(center center)', // End animation when the last step is centered
35 | scrub: true, // Synchronize animation with scroll
36 | immediateRender: false
37 | }
38 | });
39 |
40 | // Add Flip animations to the timeline for each state
41 | states.forEach((state, index) => {
42 | const customFlipConfig = {
43 | ...flipConfig,
44 | ease: index === 0 ? 'none' : flipConfig.ease // Use 'none' easing for the first step
45 | };
46 | tl.add(Flip.fit(oneElement, state, customFlipConfig), index ? '+=0.5' : 0);
47 | });
48 | });
49 | };
50 |
51 | // Animate spans within `.content__title` elements on scroll
52 | const animateSpansOnScroll = () => {
53 | const spans = document.querySelectorAll('.content__title > span'); // Select all spans
54 |
55 | spans.forEach((span, index) => {
56 | const direction = index % 2 === 0 ? -150 : 150; // Alternate direction for animation
57 |
58 | // Determine the scroll trigger dynamically based on the parent section
59 | const triggerElement = span.closest('.content--center') ? span.parentNode : span;
60 |
61 | gsap.from(span, {
62 | x: direction, // Animate from the left or right
63 | duration: 1,
64 | ease: 'sine', // Smooth easing
65 | scrollTrigger: {
66 | trigger: triggerElement, // Trigger element
67 | start: 'top bottom', // Start animation when element enters viewport
68 | end: '+=45%', // End animation after 45% of the viewport
69 | scrub: true, // Synchronize with scroll
70 | },
71 | });
72 | });
73 | };
74 |
75 | // Animate specific images on scroll
76 | const animateImagesOnScroll = () => {
77 | const images = document.querySelectorAll('.content--lines .content__img:not([data-step]), .content--grid .content__img:not([data-step])');
78 |
79 | images.forEach((image) => {
80 | gsap.fromTo(image, {
81 | scale: 0, // Start small
82 | autoAlpha: 0, // Start transparent
83 | filter: 'brightness(180%) saturate(0%)' // Start desaturated and bright
84 | }, {
85 | scale: 1, // Scale to full size
86 | autoAlpha: 1, // Fade in
87 | filter: 'brightness(100%) saturate(100%)', // Restore normal brightness and saturation
88 | duration: 1,
89 | ease: 'sine', // Smooth easing
90 | scrollTrigger: {
91 | trigger: image,
92 | start: 'top bottom', // Start animation when element enters viewport
93 | end: '+=45%', // End animation after 45% of the viewport
94 | scrub: true,
95 | },
96 | });
97 | });
98 | };
99 |
100 | // Add a parallax effect to `.content__text` elements
101 | const addParallaxToText = () => {
102 | const firstTextElement = document.querySelector('.content__text'); // Select the first text element
103 | if (!firstTextElement) return; // Exit if no element is found
104 |
105 | gsap.fromTo(
106 | firstTextElement, {
107 | y: 250, // Start below its original position
108 | }, {
109 | y: -250, // Move above its original position
110 | ease: 'sine', // Smooth easing
111 | scrollTrigger: {
112 | trigger: firstTextElement,
113 | start: 'top bottom', // Start when top of element enters viewport
114 | end: 'top top', // End when top of element reaches top of viewport
115 | scrub: true, // Synchronize with scroll
116 | },
117 | }
118 | );
119 | };
120 |
121 | // Animate the filter effect on the `.one` element during the first scroll
122 | const animateFilterOnFirstSwitch = () => {
123 | gsap.fromTo(oneElement, {
124 | filter: 'brightness(80%)' // Start with high brightness and reduced saturation
125 | }, {
126 | filter: 'brightness(100%)', // Transition to normal state
127 | ease: 'sine', // Smooth easing
128 | scrollTrigger: {
129 | trigger: parentElement,
130 | start: 'clamp(top bottom)', // Start when parent enters viewport
131 | end: 'clamp(bottom top)', // End when parent leaves viewport
132 | scrub: true,
133 | }
134 | });
135 | };
136 |
137 | // Add a parallax effect to images in the `.content--column` section
138 | const addParallaxToColumnImages = () => {
139 | const columnImages = [...document.querySelectorAll('.content--column .content__img:not([data-step])')];
140 | const totalImages = columnImages.length;
141 | const middleIndex = (totalImages - 1) / 2; // Calculate the virtual center index for symmetry
142 |
143 | columnImages.forEach((image, index) => {
144 | const intensity = Math.abs(index - middleIndex) * 75; // Calculate intensity based on distance from center
145 |
146 | gsap.fromTo(image, {
147 | y: intensity // Start with offset based on intensity
148 | }, {
149 | y: -intensity, // Move in the opposite direction
150 | ease: 'sine', // Smooth easing
151 | scrollTrigger: {
152 | trigger: image,
153 | start: 'top bottom', // Start when top of element enters viewport
154 | end: 'bottom top', // End when bottom of element leaves viewport
155 | scrub: true,
156 | },
157 | });
158 | });
159 | };
160 |
161 | const animateRelatedDemos = () => {
162 | const relatedSection = document.querySelector('.card-wrap');
163 | const relatedDemos = [...relatedSection.querySelectorAll('.card-wrap > .card')];
164 |
165 | gsap.from(relatedDemos, {
166 | scale: 0,
167 | ease: 'sine',
168 | stagger: {
169 | each: 0.04,
170 | from: 'center'
171 | },
172 | scrollTrigger: {
173 | trigger: relatedSection,
174 | start: 'top bottom',
175 | end: 'clamp(center center)',
176 | scrub: true,
177 | },
178 | });
179 | };
180 |
181 | // Main initialization function
182 | const init = () => {
183 | createFlipOnScrollAnimation(); // Initialize Flip animations
184 | animateSpansOnScroll(); // Animate spans on scroll
185 | animateImagesOnScroll(); // Animate images on scroll
186 | addParallaxToText(); // Add parallax effect to text
187 | addParallaxToColumnImages(); // Add parallax effect to column images
188 | animateFilterOnFirstSwitch(); // Animate the filter on the `.one` element
189 | animateRelatedDemos(); // Animate the related demos section
190 | window.addEventListener('resize', createFlipOnScrollAnimation); // Reinitialize Flip animations on resize
191 | };
192 |
193 | // Preload images and initialize animations after images have loaded
194 | preloadImages('.one__img').then(() => {
195 | document.body.classList.remove('loading'); // Remove the 'loading' class from the body
196 | init(); // Initialize animations
197 | });
198 |
--------------------------------------------------------------------------------
/js/lenis.min.js:
--------------------------------------------------------------------------------
1 | !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=i()}(this,(function(){"use strict";function clamp(t,i,e){return Math.max(t,Math.min(i,e))}class Animate{constructor(){this.isRunning=!1,this.value=0,this.from=0,this.to=0,this.duration=0,this.currentTime=0}advance(t){var i;if(!this.isRunning)return;let e=!1;if(this.duration&&this.easing){this.currentTime+=t;const i=clamp(0,this.currentTime/this.duration,1);e=i>=1;const s=e?1:this.easing(i);this.value=this.from+(this.to-this.from)*s}else this.lerp?(this.value=function damp(t,i,e,s){return function lerp(t,i,e){return(1-e)*t+e*i}(t,i,1-Math.exp(-e*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0)):(this.value=this.to,e=!0);e&&this.stop(),null===(i=this.onUpdate)||void 0===i||i.call(this,this.value,e)}stop(){this.isRunning=!1}fromTo(t,i,{lerp:e,duration:s,easing:o,onStart:n,onUpdate:l}){this.from=this.value=t,this.to=i,this.lerp=e,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,null==n||n(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:i,autoResize:e=!0,debounce:s=250}={}){this.width=0,this.height=0,this.scrollWidth=0,this.scrollHeight=0,this.resize=()=>{this.onWrapperResize(),this.onContentResize()},this.onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):this.wrapper instanceof HTMLElement&&(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)},this.onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):this.wrapper instanceof HTMLElement&&(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)},this.wrapper=t,this.content=i,e&&(this.debouncedResize=function debounce(t,i){let e;return function(){let s=arguments,o=this;clearTimeout(e),e=setTimeout((function(){t.apply(o,s)}),i)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){var t,i;null===(t=this.wrapperResizeObserver)||void 0===t||t.disconnect(),null===(i=this.contentResizeObserver)||void 0===i||i.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...i){let e=this.events[t]||[];for(let t=0,s=e.length;t{var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}}off(t,i){var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}destroy(){this.events={}}}const t=100/6;class VirtualScroll{constructor(i,{wheelMultiplier:e=1,touchMultiplier:s=1}){this.lastDelta={x:0,y:0},this.windowWidth=0,this.windowHeight=0,this.onTouchStart=t=>{const{clientX:i,clientY:e}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=i,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})},this.onTouchMove=t=>{var i,e,s,o;const{clientX:n,clientY:l}=t.targetTouches?t.targetTouches[0]:t,r=-(n-(null!==(e=null===(i=this.touchStart)||void 0===i?void 0:i.x)&&void 0!==e?e:0))*this.touchMultiplier,h=-(l-(null!==(o=null===(s=this.touchStart)||void 0===s?void 0:s.y)&&void 0!==o?o:0))*this.touchMultiplier;this.touchStart.x=n,this.touchStart.y=l,this.lastDelta={x:r,y:h},this.emitter.emit("scroll",{deltaX:r,deltaY:h,event:t})},this.onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})},this.onWheel=i=>{let{deltaX:e,deltaY:s,deltaMode:o}=i;e*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,e*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:e,deltaY:s,event:i})},this.onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight},this.element=i,this.wheelMultiplier=e,this.touchMultiplier=s,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,i){return this.emitter.on(t,i)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd)}}return class Lenis{constructor({wrapper:t=window,content:i=document.documentElement,wheelEventsTarget:e=t,eventsTarget:s=e,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=.1,infinite:d=!1,orientation:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f=!1}={}){this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.userData={},this.lastVelocity=0,this.velocity=0,this.direction=0,this.onPointerDown=t=>{1===t.button&&this.reset()},this.onVirtualScroll=t=>{if("function"==typeof this.options.virtualScroll&&!1===this.options.virtualScroll(t))return;const{deltaX:i,deltaY:e,event:s}=t;if(this.emitter.emit("virtual-scroll",{deltaX:i,deltaY:e,event:s}),s.ctrlKey)return;const o=s.type.includes("touch"),n=s.type.includes("wheel");this.isTouching="touchstart"===s.type||"touchmove"===s.type;if(this.options.syncTouch&&o&&"touchstart"===s.type&&!this.isStopped&&!this.isLocked)return void this.reset();const l=0===i&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===i;if(l||r)return;let h=s.composedPath();h=h.slice(0,h.indexOf(this.rootElement));const a=this.options.prevent;if(h.find((t=>{var i,e,s,l,r;return t instanceof Element&&("function"==typeof a&&(null==a?void 0:a(t))||(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent"))||o&&(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent-touch"))||n&&(null===(s=t.hasAttribute)||void 0===s?void 0:s.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped")))})))return;if(this.isStopped||this.isLocked)return void s.preventDefault();if(!(this.options.syncTouch&&o||this.options.smoothWheel&&n))return this.isScrolling="native",void this.animate.stop();s.preventDefault();let c=e;"both"===this.options.gestureOrientation?c=Math.abs(e)>Math.abs(i)?e:i:"horizontal"===this.options.gestureOrientation&&(c=i);const d=o&&this.options.syncTouch,u=o&&"touchend"===s.type&&Math.abs(c)>5;u&&(c=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+c,Object.assign({programmatic:!1},d?{lerp:u?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(clearTimeout(this.__resetVelocityTimeout),delete this.__resetVelocityTimeout,this.__preventNextNativeScrollEvent)delete this.__preventNextNativeScrollEvent;else if(!1===this.isScrolling||"native"===this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-t,this.direction=Math.sign(this.animatedScroll-t),this.isScrolling="native",this.emit(),0!==this.velocity&&(this.__resetVelocityTimeout=setTimeout((()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()}),400))}},window.lenisVersion="1.1.9",t&&t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:i,wheelEventsTarget:e,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:i,autoResize:g}),this.updateClassName(),this.userData={},this.time=0,this.velocity=this.lastVelocity=0,this.isLocked=!1,this.isStopped=!1,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.options.wrapper.addEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.options.wrapper.removeEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName()}on(t,i){return this.emitter.on(t,i)}off(t,i){return this.emitter.off(t,i)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const i=t-(this.time||t);this.time=t,this.animate.advance(.001*i)}scrollTo(t,{offset:i=0,immediate:e=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:l=this.options.lerp,onStart:r,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if("string"==typeof t&&["top","left","start"].includes(t))t=0;else if("string"==typeof t&&["bottom","right","end"].includes(t))t=this.limit;else{let e;if("string"==typeof t?e=document.querySelector(t):t instanceof HTMLElement&&(null==t?void 0:t.nodeType)&&(e=t),e){if(this.options.wrapper!==window){const t=this.rootElement.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=e.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t&&(t+=i,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),t!==this.targetScroll)){if(this.userData=d,e)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),null==h||h(this),void(this.userData={});c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:l,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==r||r(this)},onUpdate:(t,i)=>{this.isScrolling="smooth",this.lastVelocity=this.velocity,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),i||this.emit(),i&&(this.reset(),this.emit(),null==h||h(this),this.userData={},this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this.__preventNextNativeScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextNativeScrollEvent}))}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?function modulo(t,i){return(t%i+i)%i}(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.updateClassName())}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.updateClassName())}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.updateClassName())}get isSmooth(){return"smooth"===this.isScrolling}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),"smooth"===this.isScrolling&&(t+=" lenis-smooth"),t}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\w+)?/g,"").trim()}}}));
2 | //# sourceMappingURL=lenis.min.js.map
--------------------------------------------------------------------------------
/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.1 });
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 | 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 | // Exporting utility functions for use in other modules.
15 | export {
16 | preloadImages
17 | };
--------------------------------------------------------------------------------