├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── css
└── base.css
├── favicon.ico
├── img
├── 1.jpg
├── 10.jpg
├── 11.jpg
├── 12.jpg
├── 13.jpg
├── 14.jpg
├── 15.jpg
├── 16.jpg
├── 17.jpg
├── 18.jpg
├── 19.jpg
├── 2.jpg
├── 20.jpg
├── 21.jpg
├── 22.jpg
├── 23.jpg
├── 24.jpg
├── 25.jpg
├── 26.jpg
├── 27.jpg
├── 28.jpg
├── 29.jpg
├── 3.jpg
├── 30.jpg
├── 31.jpg
├── 32.jpg
├── 33.jpg
├── 34.jpg
├── 35.jpg
├── 36.jpg
├── 37.jpg
├── 38.jpg
├── 39.jpg
├── 4.jpg
├── 40.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
├── 8.jpg
└── 9.jpg
├── index.html
├── index10.html
├── index2.html
├── index3.html
├── index4.html
├── index5.html
├── index6.html
├── index7.html
├── index8.html
├── index9.html
└── js
├── ScrollTrigger.min.js
├── gsap.min.js
├── imagesloaded.pkgd.min.js
├── index.js
├── index10.js
├── index2.js
├── index3.js
├── index4.js
├── index5.js
├── index6.js
├── index7.js
├── index8.js
├── index9.js
├── lenis.min.js
└── utils.js
/.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 - 2022 [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 | # On-Scroll Column & Row Animations
2 |
3 | Scroll-driven animations for columns and rows powered by GSAP.
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=73182)
8 |
9 | [Demo](https://tympanus.net/Development/OnScrollColumnsRows/)
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: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/)
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: 18px;
9 | --color-text: #fff;
10 | --color-bg: #000;
11 | --color-link: #fff;
12 | --color-link-hover: #a2a2a2;
13 | --perspective: 0px;
14 | --grid-item-translate: 0px;
15 | --grid-item-ratio: 0.75;
16 | --grid-item-radius: 7px;
17 | --grid-gap: 4vw;
18 | --grid-columns: 3;
19 | --grid-width: 100%;
20 | --grid-max-width: 1200px;
21 | }
22 |
23 | .demo-1 {
24 | --grid-item-translate: 30px;
25 | --grid-gap: 2vw;
26 | }
27 |
28 | .demo-2 {
29 | --grid-item-ratio: 1;
30 | --grid-item-radius: 20px;
31 | --grid-gap: 1vw;
32 | }
33 |
34 | .demo-3 {
35 | --grid-item-radius: 10px;
36 | --grid-gap: 10px;
37 | --grid-columns: 4;
38 | }
39 |
40 | .demo-4 {
41 | --grid-item-ratio: 0.7;
42 | --grid-item-radius: 0;
43 | --grid-gap: 1.5vw;
44 | --grid-columns: 7;
45 | }
46 |
47 | .demo-5 {
48 | --grid-item-ratio: 0.7;
49 | --grid-item-radius: 0px;
50 | --grid-gap: 10px;
51 | --grid-columns: 4;
52 | --grid-max-width: 900px;
53 | }
54 |
55 | .demo-6 {
56 | --grid-item-ratio: 0.7;
57 | --grid-item-radius: 6px;
58 | --grid-gap: 2vw;
59 | --grid-columns: 6;
60 | --grid-max-width: 1100px;
61 | }
62 |
63 | .demo-7 {
64 | --grid-item-ratio: 0.75;
65 | --grid-item-radius: 0px;
66 | --grid-gap: 2vw;
67 | --grid-columns: 5;
68 | --grid-width: 140%;
69 | --grid-max-width: none;
70 | }
71 |
72 | .demo-8 {
73 | --grid-item-ratio: 0.75;
74 | --grid-item-radius: 0px;
75 | --grid-gap: 2vw;
76 | --grid-columns: 4;
77 | }
78 |
79 | .demo-10 {
80 | --grid-item-ratio: 0.6;
81 | --grid-item-radius: 0px;
82 | --grid-gap: 2vw;
83 | }
84 |
85 | body {
86 | margin: 0;
87 | color: var(--color-text);
88 | background-color: var(--color-bg);
89 | font-family: "marlide-display-variable", sans-serif;
90 | font-variation-settings: "wght" 300;
91 | -webkit-font-smoothing: antialiased;
92 | -moz-osx-font-smoothing: grayscale;
93 | overflow-x: hidden;
94 | }
95 |
96 | main {
97 | display: grid;
98 | place-items: center;
99 | width: 100%;
100 | position: relative;
101 | }
102 |
103 | .outro {
104 | display: grid;
105 | place-items: center;
106 | margin: 40vh 0;
107 | }
108 |
109 | .outro__title {
110 | font-weight: 300;
111 | font-size: clamp(1.5rem,10vw,2rem);
112 | }
113 |
114 | .card-wrap {
115 | margin-top: 5vh;
116 | display: grid;
117 | grid-gap: 2rem;
118 | grid-auto-flow: row;
119 | grid-template-columns: 250px;
120 | text-align: center;
121 | }
122 |
123 | .card__image {
124 | display: block;
125 | border-radius: 7px;
126 | background-size: cover;
127 | background-position: 50% 50%;
128 | width: 100%;
129 | height: auto;
130 | aspect-ratio: 4 / 3;
131 | filter: contrast(0.8);
132 | }
133 |
134 | .card__title {
135 | font-weight: 300;
136 | }
137 |
138 | .credits {
139 | font-size: 1.5rem;
140 | text-align: center;
141 | margin: 50vh auto 0;
142 | padding-bottom: 50vh;
143 | }
144 |
145 | /* Page Loader */
146 | .js .loading::before,
147 | .js .loading::after {
148 | content: '';
149 | position: fixed;
150 | z-index: 4000;
151 | }
152 |
153 | .js .loading::before {
154 | top: 0;
155 | left: 0;
156 | width: 100%;
157 | height: 100%;
158 | background: var(--color-bg);
159 | }
160 |
161 | .js .loading::after {
162 | top: 50%;
163 | left: 50%;
164 | width: 60px;
165 | height: 60px;
166 | margin: -30px 0 0 -30px;
167 | border-radius: 50%;
168 | opacity: 0.4;
169 | background: var(--color-link);
170 | animation: loaderAnim 0.7s linear infinite alternate forwards;
171 |
172 | }
173 |
174 | @keyframes loaderAnim {
175 | to {
176 | opacity: 1;
177 | transform: scale3d(0.5,0.5,1);
178 | }
179 | }
180 |
181 | a {
182 | text-decoration: none;
183 | color: var(--color-link);
184 | outline: none;
185 | cursor: pointer;
186 | }
187 |
188 | a:hover {
189 | color: var(--color-link-hover);
190 | outline: none;
191 | }
192 |
193 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
194 | a:not(.card__image):focus {
195 | /* Provide a fallback style for browsers
196 | that don't support :focus-visible */
197 | outline: none;
198 | background: lightgrey;
199 | }
200 |
201 | a:not(.card__image):focus:not(:focus-visible) {
202 | /* Remove the focus indicator on mouse-focus for browsers
203 | that do support :focus-visible */
204 | background: transparent;
205 | }
206 |
207 | a:not(.card__image):focus-visible {
208 | /* Draw a very noticeable focus style for
209 | keyboard-focus on browsers that do support
210 | :focus-visible */
211 | outline: 2px solid red;
212 | background: transparent;
213 | }
214 |
215 | .unbutton {
216 | background: none;
217 | border: 0;
218 | padding: 0;
219 | margin: 0;
220 | font: inherit;
221 | cursor: pointer;
222 | }
223 |
224 | .unbutton:focus {
225 | outline: none;
226 | }
227 |
228 | .frame {
229 | z-index: 1000;
230 | position: relative;
231 | padding: 1.5rem;
232 | display: grid;
233 | min-height: 400px;
234 | width: 100%;
235 | grid-template-columns: auto auto 1fr 1fr;
236 | grid-template-areas: 'prev back ... sponsor' 'title title title title' 'demos demos demos demos' ;
237 | grid-gap: 1rem;
238 | pointer-events: none;
239 | justify-items: start;
240 | }
241 |
242 | .frame a {
243 | pointer-events: auto;
244 | }
245 |
246 | .frame__title {
247 | grid-area: title;
248 | font-size: clamp(1.5rem, 10vw,5rem);
249 | margin: 0;
250 | font-weight: inherit;
251 | }
252 |
253 | .frame__back {
254 | grid-area: back;
255 | justify-self: start;
256 | }
257 |
258 | .frame__prev {
259 | grid-area: prev;
260 | justify-self: start;
261 | }
262 |
263 | .frame__demos {
264 | grid-area: demos;
265 | display: flex;
266 | align-items: center;
267 | gap: 0.5rem;
268 | align-self: start;
269 | flex-wrap: wrap;
270 | }
271 |
272 | .frame__demos-item:not(:first-child) {
273 | width: 2rem;
274 | display: block;
275 | flex: none;
276 | border-radius: 10px;
277 | aspect-ratio: 1;
278 | border: 1px solid var(--color-link-hover);
279 | display: grid;
280 | place-items: center;
281 | }
282 |
283 | span.frame__demos-item:not(:first-child) {
284 | border-color: #fff;
285 | }
286 |
287 | .columns {
288 | width: var(--grid-width);
289 | max-width: var(--grid-max-width);
290 | position: relative;
291 | padding: 20vh 0;
292 | display: grid;
293 | place-items: center;
294 | grid-template-columns: repeat(var(--grid-columns),1fr);
295 | gap: var(--grid-gap);
296 | }
297 |
298 | .column {
299 | width: 100%;
300 | position: relative;
301 | display: grid;
302 | gap: var(--grid-gap);
303 | grid-template-columns: 100%;
304 | will-change: transform;
305 | }
306 |
307 | .column__item {
308 | margin: 0;
309 | position: relative;
310 | z-index: 1;
311 | }
312 |
313 | .column__item-imgwrap {
314 | width: 100%;
315 | aspect-ratio: var(--grid-item-ratio);
316 | height: auto;
317 | position: relative;
318 | overflow: hidden;
319 | border-radius: var(--grid-item-radius);
320 | }
321 |
322 | .column__item-img {
323 | position: absolute;
324 | top: calc(-1 * var(--grid-item-translate));
325 | left: calc(-1 * var(--grid-item-translate));
326 | height: calc(100% + var(--grid-item-translate) * 2);
327 | width: calc(100% + var(--grid-item-translate) * 2);
328 | background-size: cover;
329 | background-position: 50% 20%;
330 | backface-visibility: hidden;
331 | }
332 |
333 | @media screen and (min-width: 53em) {
334 | .frame {
335 | text-align: center;
336 | justify-items: center;
337 | }
338 | .card-wrap {
339 | grid-template-columns: repeat(2,300px);
340 | }
341 |
342 | }
343 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/favicon.ico
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/1.jpg
--------------------------------------------------------------------------------
/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/10.jpg
--------------------------------------------------------------------------------
/img/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/11.jpg
--------------------------------------------------------------------------------
/img/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/12.jpg
--------------------------------------------------------------------------------
/img/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/13.jpg
--------------------------------------------------------------------------------
/img/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/14.jpg
--------------------------------------------------------------------------------
/img/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/15.jpg
--------------------------------------------------------------------------------
/img/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/16.jpg
--------------------------------------------------------------------------------
/img/17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/17.jpg
--------------------------------------------------------------------------------
/img/18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/18.jpg
--------------------------------------------------------------------------------
/img/19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/19.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/2.jpg
--------------------------------------------------------------------------------
/img/20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/20.jpg
--------------------------------------------------------------------------------
/img/21.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/21.jpg
--------------------------------------------------------------------------------
/img/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/22.jpg
--------------------------------------------------------------------------------
/img/23.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/23.jpg
--------------------------------------------------------------------------------
/img/24.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/24.jpg
--------------------------------------------------------------------------------
/img/25.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/25.jpg
--------------------------------------------------------------------------------
/img/26.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/26.jpg
--------------------------------------------------------------------------------
/img/27.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/27.jpg
--------------------------------------------------------------------------------
/img/28.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/28.jpg
--------------------------------------------------------------------------------
/img/29.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/29.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/3.jpg
--------------------------------------------------------------------------------
/img/30.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/30.jpg
--------------------------------------------------------------------------------
/img/31.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/31.jpg
--------------------------------------------------------------------------------
/img/32.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/32.jpg
--------------------------------------------------------------------------------
/img/33.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/33.jpg
--------------------------------------------------------------------------------
/img/34.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/34.jpg
--------------------------------------------------------------------------------
/img/35.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/35.jpg
--------------------------------------------------------------------------------
/img/36.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/36.jpg
--------------------------------------------------------------------------------
/img/37.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/37.jpg
--------------------------------------------------------------------------------
/img/38.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/38.jpg
--------------------------------------------------------------------------------
/img/39.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/39.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/4.jpg
--------------------------------------------------------------------------------
/img/40.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/40.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/5.jpg
--------------------------------------------------------------------------------
/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/6.jpg
--------------------------------------------------------------------------------
/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/7.jpg
--------------------------------------------------------------------------------
/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/8.jpg
--------------------------------------------------------------------------------
/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/OnScrollColumnsRows/bc0587f488eaed94905e544dfb05c3de8425012c/img/9.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 | More you might like
166 |
176 |
177 | Made by @codrops
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/index10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 | More you might like
166 |
176 |
177 | Made by @codrops
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 | More you might like
166 |
176 |
177 | Made by @codrops
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/index3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 | More you might like
208 |
218 |
219 | Made by @codrops
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
--------------------------------------------------------------------------------
/index4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 |
210 |
211 |
212 |
215 |
216 |
217 |
220 |
221 |
222 |
225 |
226 |
227 |
230 |
231 |
232 |
235 |
236 |
237 |
240 |
241 |
242 |
245 |
246 |
247 |
248 |
249 |
252 |
253 |
254 |
257 |
258 |
259 |
262 |
263 |
264 |
267 |
268 |
269 |
272 |
273 |
274 |
277 |
278 |
279 |
282 |
283 |
284 |
287 |
288 |
289 |
290 |
291 |
294 |
295 |
296 |
299 |
300 |
301 |
304 |
305 |
306 |
309 |
310 |
311 |
314 |
315 |
316 |
319 |
320 |
321 |
324 |
325 |
326 |
329 |
330 |
331 |
332 |
333 | More you might like
334 |
344 |
345 | Made by @codrops
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
--------------------------------------------------------------------------------
/index5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 | More you might like
208 |
218 |
219 | Made by @codrops
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
--------------------------------------------------------------------------------
/index6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 |
210 |
211 |
212 |
215 |
216 |
217 |
220 |
221 |
222 |
225 |
226 |
227 |
230 |
231 |
232 |
235 |
236 |
237 |
240 |
241 |
242 |
245 |
246 |
247 |
248 |
249 |
252 |
253 |
254 |
257 |
258 |
259 |
262 |
263 |
264 |
267 |
268 |
269 |
272 |
273 |
274 |
277 |
278 |
279 |
282 |
283 |
284 |
287 |
288 |
289 |
290 |
291 | More you might like
292 |
302 |
303 | Made by @codrops
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
--------------------------------------------------------------------------------
/index7.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 |
210 |
211 |
212 |
215 |
216 |
217 |
220 |
221 |
222 |
225 |
226 |
227 |
230 |
231 |
232 |
235 |
236 |
237 |
240 |
241 |
242 |
245 |
246 |
247 |
248 |
249 | More you might like
250 |
260 |
261 | Made by @codrops
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
--------------------------------------------------------------------------------
/index8.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
168 |
169 |
170 |
173 |
174 |
175 |
178 |
179 |
180 |
183 |
184 |
185 |
188 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
200 |
203 |
204 |
205 |
206 |
207 | More you might like
208 |
218 |
219 | Made by @codrops
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
--------------------------------------------------------------------------------
/index9.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Column & Row Animations | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
On-Scroll Column & Row Animations
20 |
Article
21 |
Previous demo
22 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
100 |
101 |
104 |
105 |
106 |
109 |
110 |
111 |
114 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
131 |
132 |
133 |
136 |
137 |
138 |
141 |
142 |
143 |
146 |
147 |
148 |
151 |
152 |
153 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 | More you might like
166 |
176 |
177 | Made by @codrops
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/js/imagesloaded.pkgd.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * imagesLoaded PACKAGED v5.0.0
3 | * JavaScript is all like "You images are done yet or what?"
4 | * MIT License
5 | */
6 | !function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})),
7 | /*!
8 | * imagesLoaded v5.0.0
9 | * JavaScript is all like "You images are done yet or what?"
10 | * MIT License
11 | */
12 | function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{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 the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | // Columns animations
45 | columns.forEach((column, pos) => {
46 | gsap.to(column, {
47 | ease: 'none',
48 | yPercent: -1*pos*10,
49 | scrollTrigger: {
50 | trigger: grid,
51 | start: 'clamp(top bottom)',
52 | end: 'clamp(bottom top)',
53 | scrub: true
54 | }
55 | })
56 | });
57 |
58 | // Items animations
59 | mergedItems.forEach(item => {
60 | gsap
61 | .fromTo(item.image, {
62 | y: 30
63 | }, {
64 | ease: 'none',
65 | scrollTrigger: {
66 | trigger: item.element,
67 | start: 'clamp(top bottom)',
68 | end: 'clamp(bottom top)',
69 | scrub: true
70 | },
71 | y: -30
72 | });
73 | });
74 | }
75 |
76 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
77 | preloadImages('.column__item-img').then(() => {
78 | initSmoothScrolling();
79 | scroll();
80 | document.body.classList.remove('loading');
81 | });
--------------------------------------------------------------------------------
/js/index10.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | mergedItems.forEach(item => {
45 | let xPercentValue, scaleXValue, scaleYValue, transformOrigin, filterValue;
46 |
47 | switch (item.column) {
48 | case 0:
49 | xPercentValue = -400;
50 | transformOrigin = '0% 50%';
51 | scaleXValue = 6;
52 | scaleYValue = 0.3;
53 | filterValue = 'blur(10px)';
54 | break;
55 | case 1:
56 | xPercentValue = 0;
57 | transformOrigin = '50% 50%';
58 | scaleXValue = 0.7;
59 | scaleYValue = 0.7;
60 | filterValue = 'blur(5px)';
61 | break;
62 | case 2:
63 | xPercentValue = 400;
64 | transformOrigin = '100% 50%';
65 | scaleXValue = 6;
66 | scaleYValue = 0.3;
67 | filterValue = 'blur(10px)';
68 | break;
69 | };
70 |
71 | gsap.fromTo(item.wrapper, {
72 | willChange: 'filter',
73 | xPercent: xPercentValue,
74 | opacity: 0,
75 | scaleX: scaleXValue,
76 | scaleY: scaleYValue,
77 | filter: filterValue
78 | }, {
79 | startAt: {transformOrigin: transformOrigin},
80 | scrollTrigger: {
81 | trigger: item.element,
82 | start: 'clamp(top bottom)',
83 | end: 'clamp(bottom top)',
84 | scrub: true
85 | },
86 | xPercent: 0,
87 | opacity: 1,
88 | scaleX: 1,
89 | scaleY: 1,
90 | filter: 'blur(0px)'
91 | }, 0);
92 | });
93 | }
94 |
95 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
96 | preloadImages('.column__item-img').then(() => {
97 | initSmoothScrolling();
98 | scroll();
99 | document.body.classList.remove('loading');
100 | });
--------------------------------------------------------------------------------
/js/index2.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | gsap.to(columns[1], {
45 | ease: 'none',
46 | scrollTrigger: {
47 | trigger: grid,
48 | start: 'clamp(top bottom)',
49 | end: 'clamp(bottom top)',
50 | scrub: true
51 | },
52 | yPercent: -20
53 | });
54 |
55 | mergedItems.forEach(item => {
56 | if ( item.column === 1 ) return;
57 |
58 | gsap.to(item.wrapper, {
59 | ease: 'none',
60 | startAt: {transformOrigin: item.column === 0 ? '0% 100%' : '100% 100%'},
61 | scrollTrigger: {
62 | trigger: item.element,
63 | start: 'clamp(top bottom)',
64 | end: 'clamp(bottom top)',
65 | scrub: true
66 | },
67 | rotation: item.column === 0 ? -6 : 6,
68 | xPercent: item.column === 0 ? -10 : 10
69 | });
70 | });
71 | }
72 |
73 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
74 | preloadImages('.column__item-img').then(() => {
75 | initSmoothScrolling();
76 | scroll();
77 | document.body.classList.remove('loading');
78 | });
--------------------------------------------------------------------------------
/js/index3.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | mergedItems.forEach(item => {
45 | gsap.to(item.wrapper, {
46 | ease: 'none',
47 | startAt: {transformOrigin: `${1.5*(window.innerWidth-item.element.getBoundingClientRect()['left'])}px 0%`},
48 | scrollTrigger: {
49 | trigger: item.element,
50 | start: 'clamp(top bottom)',
51 | end: 'clamp(bottom top)',
52 | scrub: true
53 | },
54 | rotation: (item.column+1)*2,
55 | xPercent: (item.column+1)*14,
56 | yPercent: (item.column)*-5
57 | });
58 | });
59 | }
60 |
61 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
62 | preloadImages('.column__item-img').then(() => {
63 | initSmoothScrolling();
64 | scroll();
65 | document.body.classList.remove('loading');
66 | });
--------------------------------------------------------------------------------
/js/index4.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | let maxColumns = columns.length;
45 | let middleColumn = Math.floor(maxColumns / 2);
46 | let xIncrement = (maxColumns > 1) ? 400 / (maxColumns - 1) : 0;
47 |
48 | mergedItems.forEach(item => {
49 | gsap.set(item.element, {
50 | perspective: 1500
51 | });
52 |
53 | let xPercentValue = 0;
54 | let rotationXValue = 0;
55 | let zValue = 0;
56 |
57 | if (item.column === 0) {
58 | xPercentValue = -200;
59 | } else if (item.column === middleColumn) {
60 | xPercentValue = 0;
61 | } else if (item.column === maxColumns - 1) {
62 | xPercentValue = 200;
63 | } else {
64 | xPercentValue = -200 + (item.column * xIncrement);
65 | }
66 |
67 | rotationXValue = -25*(item.column+1);
68 | zValue = 30*(item.column+1);
69 |
70 | gsap
71 | .timeline({
72 | defaults: {
73 | ease: 'power2'
74 | },
75 | scrollTrigger: {
76 | trigger: item.element,
77 | start: 'top bottom',
78 | end: 'clamp(center top)',
79 | scrub: true
80 | }
81 | })
82 | .fromTo(item.wrapper, {
83 | rotationX: rotationXValue,
84 | z: zValue,
85 | yPercent: 30,
86 | xPercent: xPercentValue
87 | }, {
88 | startAt: {transformOrigin: '50% 100%'},
89 | rotationX: 0,
90 | z: 0,
91 | yPercent: 0,
92 | xPercent: 0
93 | }, 0)
94 | .fromTo(item.image, {
95 | filter: 'hue-rotate(90deg)',
96 | scale: 3
97 | }, {
98 | filter: 'hue-rotate(0deg)',
99 | scale: 1
100 | }, 0);
101 | });
102 | }
103 |
104 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
105 | preloadImages('.column__item-img').then(() => {
106 | initSmoothScrolling();
107 | scroll();
108 | document.body.classList.remove('loading');
109 | });
--------------------------------------------------------------------------------
/js/index5.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages, getGrid } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.2, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | const gridObj = getGrid(mergedItems.map(item => item.element));
45 |
46 | const rowMapping = {
47 | even: {
48 | skewX: 10,
49 | xPercent: 2, // hardcoding here what seems to be the perfect value for the effect...
50 | transformOrigin: '0% 50%'
51 | },
52 | odd: {
53 | skewX: -10,
54 | xPercent: -2,
55 | transformOrigin: '100% 50%'
56 | }
57 | };
58 |
59 | ['even', 'odd'].forEach(type => {
60 | gridObj.rows(type).flat().forEach(row => {
61 | gsap
62 | .timeline({
63 | defaults: {ease: 'none'},
64 | scrollTrigger: {
65 | trigger: row,
66 | start: 'top bottom',
67 | end: 'clamp(bottom top)',
68 | scrub: true
69 | }
70 | })
71 | .fromTo(row.querySelector('.column__item-imgwrap'), {
72 | transformOrigin: rowMapping[type].transformOrigin,
73 | opacity: 0.1,
74 | xPercent: rowMapping[type].xPercent,
75 | skewX: rowMapping[type].skewX
76 | }, {
77 | opacity: 1,
78 | xPercent: 0,
79 | skewX: 0
80 | }, 0)
81 | .fromTo(row.querySelector('.column__item-img'), {
82 | scaleY: 1.2
83 | }, {
84 | scaleY: 1
85 | }, 0)
86 | });
87 | });
88 | }
89 |
90 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
91 | preloadImages('.column__item-img').then(() => {
92 | initSmoothScrolling();
93 | scroll();
94 | document.body.classList.remove('loading');
95 | });
--------------------------------------------------------------------------------
/js/index6.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages, getGrid } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | const gridObj = getGrid(mergedItems.map(item => item.element));
45 |
46 | const rowMapping = {
47 | even: {
48 | skewX: -30,
49 | xPercent: 50, // hardcoding here what seems to be the perfect value for the effect...
50 | transformOrigin: '100% -10%'
51 | },
52 | odd: {
53 | skewX: 30,
54 | xPercent: -50, // hardcoding here what seems to be the perfect value for the effect...
55 | transformOrigin: '0% -10%'
56 | }
57 | };
58 |
59 | ['even', 'odd'].forEach(type => {
60 | gridObj.rows(type).flat().forEach(row => {
61 | gsap
62 | .timeline({
63 | defaults: { ease: 'back.out(1.5)' },
64 | scrollTrigger: {
65 | trigger: row,
66 | start: 'top bottom',
67 | end: 'clamp(bottom top)',
68 | scrub: true
69 | },
70 | })
71 | .fromTo(row.querySelector('.column__item-imgwrap'), {
72 | xPercent: rowMapping[type].xPercent,
73 | skewX: rowMapping[type].skewX,
74 | }, {
75 | startAt: {transformOrigin: rowMapping[type].transformOrigin},
76 | xPercent: 0,
77 | skewX: 0
78 | }, 0)
79 | .fromTo(row.querySelector('.column__item-img'), {
80 | scale: 1.2
81 | }, {
82 | scale: 1
83 | }, 0)
84 |
85 | });
86 | });
87 | }
88 |
89 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
90 | preloadImages('.column__item-img').then(() => {
91 | initSmoothScrolling();
92 | scroll();
93 | document.body.classList.remove('loading');
94 | });
--------------------------------------------------------------------------------
/js/index7.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages, getGrid } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | const gridObj = getGrid(mergedItems.map(item => item.element));
45 |
46 | const rowMapping = {
47 | even: {
48 | skewX: 2,
49 | xPercent: -50,
50 | transformOrigin: '0% 50%'
51 | },
52 | odd: {
53 | skewX: -2,
54 | xPercent: 50,
55 | transformOrigin: '100% 50%'
56 | }
57 | };
58 |
59 | ['even', 'odd'].forEach(type => {
60 | gridObj.rows(type).flat().forEach(row => {
61 | gsap
62 | .timeline({
63 | defaults: { ease: 'none' },
64 | scrollTrigger: {
65 | trigger: row,
66 | start: 'top bottom',
67 | end: 'bottom top',
68 | scrub: true
69 | }
70 | })
71 | .to(row.querySelector('.column__item-imgwrap'), {
72 | xPercent: rowMapping[type].xPercent,
73 | skewX: rowMapping[type].skewX
74 | }, 0)
75 | .to(row.querySelector('.column__item-img'), {
76 | ease: 'power1.in',
77 | startAt: {transformOrigin: rowMapping[type].transformOrigin},
78 | scaleX: 1.4
79 | }, 0)
80 |
81 | });
82 | });
83 | }
84 |
85 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
86 | preloadImages('.column__item-img').then(() => {
87 | initSmoothScrolling();
88 | scroll();
89 | document.body.classList.remove('loading');
90 | });
--------------------------------------------------------------------------------
/js/index8.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages, getGrid } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | // Set perspective
45 | gsap.set([grid, mergedItems.map(item => item.element)], {
46 | perspective: 600
47 | });
48 |
49 | // Define GSAP timeline with ScrollTrigger
50 | gsap.timeline({
51 | defaults: { ease: 'power2' },
52 | scrollTrigger: {
53 | trigger: grid,
54 | start: 'clamp(top bottom)',
55 | end: 'clamp(bottom top)',
56 | scrub: true
57 | }
58 | })
59 | .to(columns[0], {
60 | startAt: {transformOrigin: '100% 50%'},
61 | rotationY: 8,
62 | z: 20
63 | }, 0)
64 | .to(columns[1], {
65 | startAt: {transformOrigin: '100% 50%'},
66 | rotationY: 4
67 | }, 0)
68 | .to(columns[2], {
69 | startAt: {transformOrigin: '0% 50%'},
70 | rotationY: -3
71 | }, 0)
72 | .to(columns[3], {
73 | startAt: {transformOrigin: '0% 50%'},
74 | rotationY: -6,
75 | z: 20
76 | }, 0)
77 |
78 | mergedItems.forEach(item => {
79 | gsap.fromTo(item.wrapper, {
80 | opacity: 0,
81 | rotationX: -90,
82 | transformOrigin: '50% 0%'
83 | }, {
84 | scrollTrigger: {
85 | trigger: item.element,
86 | start: 'top bottom',
87 | end: 'clamp(center center-=25%)',
88 | scrub: true
89 | },
90 | opacity: 1,
91 | rotationX: 0
92 | });
93 | });
94 | }
95 |
96 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
97 | preloadImages('.column__item-img').then(() => {
98 | initSmoothScrolling();
99 | scroll();
100 | document.body.classList.remove('loading');
101 | });
--------------------------------------------------------------------------------
/js/index9.js:
--------------------------------------------------------------------------------
1 | // Import the necessary function for preloading images
2 | import { preloadImages } from './utils.js';
3 |
4 | // Define a variable that will store the Lenis smooth scrolling object
5 | let lenis;
6 |
7 | // Element with class .columns
8 | const grid = document.querySelector('.columns');
9 | // All the columns class .column
10 | const columns = [...grid.querySelectorAll('.column')];
11 | // Map each column to its array of items and keep a reference of the image, its wrapper and the column
12 | const items = columns.map((column, pos) => {
13 | return [...column.querySelectorAll('.column__item')].map(item => ({
14 | element: item,
15 | column: pos,
16 | wrapper: item.querySelector('.column__item-imgwrap'),
17 | image: item.querySelector('.column__item-img')
18 | }));
19 | });
20 | // All itemms
21 | const mergedItems = items.flat();
22 |
23 | // Function to initialize Lenis for smooth scrolling
24 | const initSmoothScrolling = () => {
25 | // Instantiate the Lenis object with specified properties
26 | lenis = new Lenis({
27 | lerp: 0.15, // Lower values create a smoother scroll effect
28 | smoothWheel: true // Enables smooth scrolling for mouse wheel events
29 | });
30 |
31 | // Update ScrollTrigger each time the user scrolls
32 | lenis.on('scroll', () => ScrollTrigger.update());
33 |
34 | // Define a function to run at each animation frame
35 | const scrollFn = (time) => {
36 | lenis.raf(time); // Run Lenis' requestAnimationFrame method
37 | requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame
38 | };
39 | // Start the animation frame loop
40 | requestAnimationFrame(scrollFn);
41 | };
42 |
43 | const scroll = () => {
44 | mergedItems.forEach(item => {
45 | gsap
46 | .timeline({
47 | defaults: { ease: 'none' },
48 | scrollTrigger: {
49 | trigger: item.element,
50 | start: 'clamp(top bottom)',
51 | end: 'clamp(bottom top)',
52 | scrub: true
53 | }
54 | })
55 | .fromTo(item.wrapper, {
56 | skewX: () => {
57 | if ( item.column === 0 ) {
58 | return 5;
59 | }
60 | else if ( item.column === 2 ) {
61 | return -5;
62 | }
63 | else return 0;
64 | },
65 | }, {
66 | scale: 0.7,
67 | xPercent: () => {
68 | if ( item.column === 0 ) {
69 | return -30;
70 | }
71 | else if ( item.column === 2 ) {
72 | return 30;
73 | }
74 | },
75 | skewX: 0,
76 | opacity: 0.5
77 | }, 0)
78 | .to(item.image, {
79 | scale: 1.6
80 | }, 0);
81 | });
82 | }
83 |
84 | // Preload images, initialize smooth scrolling, apply scroll-triggered animations, and remove loading class from body
85 | preloadImages('.column__item-img').then(() => {
86 | initSmoothScrolling();
87 | scroll();
88 | document.body.classList.remove('loading');
89 | });
--------------------------------------------------------------------------------
/js/lenis.min.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;i=1)?1:this.easing(s);this.value=this.from+(this.to-this.from)*r}null==(e=this.onUpdate)||e.call(this,this.value,{completed:n}),n&&this.stop()}},e.stop=function(){this.isRunning=!1},e.fromTo=function(t,e,i){var o=i.lerp,n=void 0===o?.1:o,s=i.duration,r=void 0===s?1:s,l=i.easing,h=void 0===l?function(t){return t}:l,a=i.onUpdate;this.from=this.value=t,this.to=e,this.lerp=n,this.duration=r,this.easing=h,this.currentTime=0,this.isRunning=!0,this.onUpdate=a},t}();function s(t,e){var i;return function(){var o=arguments,n=this;clearTimeout(i),i=setTimeout(function(){t.apply(n,o)},e)}}var r=/*#__PURE__*/function(){function t(t,e){var i=this;this.onWindowResize=function(){i.width=window.innerWidth,i.height=window.innerHeight},this.onWrapperResize=function(){i.width=i.wrapper.clientWidth,i.height=i.wrapper.clientHeight},this.onContentResize=function(){var t=i.wrapper===window?document.documentElement:i.wrapper;i.scrollHeight=t.scrollHeight,i.scrollWidth=t.scrollWidth},this.wrapper=t,this.content=e,this.wrapper===window?(window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize()):(this.wrapperResizeObserver=new ResizeObserver(s(this.onWrapperResize,100)),this.wrapperResizeObserver.observe(this.wrapper),this.onWrapperResize()),this.contentResizeObserver=new ResizeObserver(s(this.onContentResize,100)),this.contentResizeObserver.observe(this.content),this.onContentResize()}return t.prototype.destroy=function(){var t,e;window.removeEventListener("resize",this.onWindowResize,!1),null==(t=this.wrapperResizeObserver)||t.disconnect(),null==(e=this.contentResizeObserver)||e.disconnect()},e(t,[{key:"limit",get:function(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}]),t}(),l=/*#__PURE__*/function(){function t(t,e){var i=this,n=e.wheelMultiplier,s=void 0===n?1:n,r=e.touchMultiplier,l=void 0===r?2:r,h=e.normalizeWheel,a=void 0!==h&&h;this.onTouchStart=function(t){var e=t.targetTouches?t.targetTouches[0]:t,o=e.clientY;i.touchStart.x=e.clientX,i.touchStart.y=o,i.lastDelta={x:0,y:0}},this.onTouchMove=function(t){var e=t.targetTouches?t.targetTouches[0]:t,o=e.clientX,n=e.clientY,s=-(o-i.touchStart.x)*i.touchMultiplier,r=-(n-i.touchStart.y)*i.touchMultiplier;i.touchStart.x=o,i.touchStart.y=n,i.lastDelta={x:s,y:r},i.emitter.emit("scroll",{type:"touch",deltaX:s,deltaY:r,event:t})},this.onTouchEnd=function(t){i.emitter.emit("scroll",{type:"touch",inertia:!0,deltaX:i.lastDelta.x,deltaY:i.lastDelta.y,event:t})},this.onWheel=function(t){var e=t.deltaX,n=t.deltaY;i.normalizeWheel&&(e=o(-100,e,100),n=o(-100,n,100)),i.emitter.emit("scroll",{type:"wheel",deltaX:e*=i.wheelMultiplier,deltaY:n*=i.wheelMultiplier,event:t})},this.element=t,this.wheelMultiplier=s,this.touchMultiplier=l,this.normalizeWheel=a,this.touchStart={x:null,y:null},this.emitter={events:{},emit:function(t){for(var e=this.events[t]||[],i=0,o=e.length;iMath.abs(s)?r:s:"horizontal"===e.options.gestureOrientation&&(c=s);var u=h&&e.options.syncTouch,p=h&&n&&Math.abs(c)>1;p&&(c=e.velocity*e.options.touchInertiaMultiplier),e.scrollTo(e.targetScroll+c,i({programmatic:!1},u&&{lerp:p?e.syncTouchLerp:.4}))}}},this.onScroll=function(){if(!e.isScrolling){var t=e.animatedScroll;e.animatedScroll=e.targetScroll=e.actualScroll,e.velocity=0,e.direction=Math.sign(e.animatedScroll-t),e.emit()}},s&&console.warn("Lenis: `direction` option is deprecated, use `orientation` instead"),h&&console.warn("Lenis: `gestureDirection` option is deprecated, use `gestureOrientation` instead"),a&&console.warn("Lenis: `mouseMultiplier` option is deprecated, use `wheelMultiplier` instead"),c&&console.warn("Lenis: `smooth` option is deprecated, use `smoothWheel` instead"),window.lenisVersion="1.0.11",p!==document.documentElement&&p!==document.body||(p=window),this.options={wrapper:p,content:v,wheelEventsTarget:f,smoothWheel:w,smoothTouch:y,syncTouch:b,syncTouchLerp:M,touchInertiaMultiplier:L,duration:W,easing:O,lerp:k,infinite:H,gestureOrientation:Y,orientation:D,touchMultiplier:P,wheelMultiplier:A,normalizeWheel:V},this.dimensions=new r(p,v),this.rootElement.classList.add("lenis"),this.velocity=0,this.isStopped=!1,this.isSmooth=w||y,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.animate=new n,this.emitter={events:{},emit:function(t){for(var e=this.events[t]||[],i=0,o=e.length;i0&&e<0||t<0&&e>0)&&(e+=t),e):this.animatedScroll;var t,e}},{key:"progress",get:function(){return 0===this.limit?1:this.scroll/this.limit}},{key:"isSmooth",get:function(){return this.__isSmooth},set:function(t){this.__isSmooth!==t&&(this.rootElement.classList.toggle("lenis-smooth",t),this.__isSmooth=t)}},{key:"isScrolling",get:function(){return this.__isScrolling},set:function(t){this.__isScrolling!==t&&(this.rootElement.classList.toggle("lenis-scrolling",t),this.__isScrolling=t)}},{key:"isStopped",get:function(){return this.__isStopped},set:function(t){this.__isStopped!==t&&(this.rootElement.classList.toggle("lenis-stopped",t),this.__isStopped=t)}}]),t}();return h});
--------------------------------------------------------------------------------
/js/utils.js:
--------------------------------------------------------------------------------
1 | // Preload images
2 | const preloadImages = (selector = 'img') => {
3 | return new Promise((resolve) => {
4 | imagesLoaded(document.querySelectorAll(selector), {background: true}, resolve);
5 | });
6 | };
7 |
8 | // Helper function that lets you dynamically figure out a grid's rows/columns as well as further refine those with "odd" or "even" ones
9 | // https://greensock.com/forums/topic/34808-how-can-i-animate-the-odd-and-even-columns-rows-of-a-grid-with-gsapto/?do=findComment&comment=174346
10 | const getGrid = selector => {
11 | let elements = gsap.utils.toArray(selector),
12 | bounds,
13 | getSubset = (axis, dimension, alternating, merge) => {
14 | let a = [],
15 | subsets = {},
16 | onlyEven = alternating === "even",
17 | p;
18 | bounds.forEach((b, i) => {
19 | let position = Math.round(b[axis] + b[dimension] / 2),
20 | subset = subsets[position];
21 | subset || (subsets[position] = subset = []);
22 | subset.push(elements[i]);
23 | });
24 | for (p in subsets) {
25 | a.push(subsets[p]);
26 | }
27 | if (onlyEven || alternating === "odd") {
28 | a = a.filter((el, i) => !(i % 2) === onlyEven);
29 | }
30 | if (merge) {
31 | let a2 = [];
32 | a.forEach(subset => a2.push(...subset));
33 | return a2;
34 | }
35 | return a;
36 | };
37 | elements.refresh = () => bounds = elements.map(el => el.getBoundingClientRect());
38 | elements.columns = (alternating, merge) => getSubset("left", "width", alternating, merge);
39 | elements.rows = (alternating, merge) => getSubset("top", "height", alternating, merge);
40 | elements.refresh();
41 |
42 | return elements;
43 | }
44 |
45 | export {
46 | preloadImages,
47 | getGrid,
48 | };
--------------------------------------------------------------------------------