├── .gitattributes
├── LICENSE
├── README.md
├── css
└── base.css
├── favicon.ico
├── img
├── 1.jpg
├── 10.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
├── 8.jpg
└── 9.jpg
├── index.html
├── index2.html
├── index3.html
├── index4.html
├── index5.html
├── index6.html
└── js
├── demo1
├── index.js
└── overlay.js
├── demo2
├── index.js
└── overlay.js
├── demo3
├── index.js
└── overlay.js
├── demo4
├── index.js
└── overlay.js
├── demo5
├── index.js
└── overlay.js
├── demo6
├── index.js
└── overlay.js
└── utils.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2009 - 2023 [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 | # Pixel Transition Effects
2 |
3 | Ideas for pixel page transitions based on an [animation](https://twitter.com/niccolomiranda/status/1628359949972819968) by [Niccolò Miranda](https://www.instagram.com/niccolomiranda/).
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=71437)
8 |
9 | [Demo](http://tympanus.net/Development/PixelTransition/)
10 |
11 |
12 | ## Installation
13 |
14 | 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).
15 |
16 | ## Credits
17 |
18 | - Images from [Pexels](https://www.pexels.com/)
19 |
20 | ## Misc
21 |
22 | 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/)
23 |
24 | ## License
25 | [MIT](LICENSE)
26 |
27 | Made with :blue_heart: by [Codrops](http://www.codrops.com)
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/css/base.css:
--------------------------------------------------------------------------------
1 | *,
2 | *::after,
3 | *::before {
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | font-size: 12px;
9 | }
10 |
11 | body {
12 | margin: 0;
13 | overflow: hidden;
14 | --color-text: #fff;
15 | --color-gr-1: #4cfa68;
16 | --color-gr-2: #1b35ea;
17 | --color-bg: #272f2e;
18 | --color-link: #6d91c9;
19 | --color-link-hover: #60c18d;
20 | --padding-ver: 1.5rem;
21 | --padding-hor: 1.5rem;
22 | --color-bg-overlay: #000;
23 | --color-back: #6d91c9;
24 | --color-back-hover: #60c18d;
25 | color: var(--color-text);
26 | background-color: var(--color-bg);
27 | font-family: area-normal, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
28 | -webkit-font-smoothing: antialiased;
29 | -moz-osx-font-smoothing: grayscale;
30 | }
31 |
32 | .demo-2 {
33 | --color-text: #000;
34 | --color-gr-1: #81e2c6;
35 | --color-gr-2: #e7613c;
36 | --color-bg: #f9f9f9;
37 | --color-link: #d23636;
38 | --color-link-hover: #df6b47;
39 | --color-back: #d23636;
40 | --color-back-hover: #df6b47;
41 | --color-bg-overlay: rgb(37, 116, 66);
42 | }
43 |
44 | .demo-3 {
45 | --color-text: #fff;
46 | --color-gr-1: #81e2c6;
47 | --color-gr-2: #e7613c;
48 | --color-bg: #000;
49 | --color-link: #ba9978;
50 | --color-link-hover: #df6b47;
51 | --color-back: #d23636;
52 | --color-back-hover: #df6b47;
53 | --color-bg-overlay: rgb(223, 107, 71);
54 | }
55 |
56 | .demo-4 {
57 | --color-text: #000;
58 | --color-gr-1: #97d6c5;
59 | --color-gr-2: #308c2c;
60 | --color-bg: #4b7872;
61 | --color-link: #1cf191;
62 | --color-link-hover: #97d6c5;
63 | --color-back: #1cf191;
64 | --color-back-hover: #97d6c5;
65 | }
66 |
67 | .demo-5 {
68 | --color-text: #000;
69 | --color-gr-1: #c4b478;
70 | --color-gr-2: #815615;
71 | --color-bg: #394235;
72 | --color-link: #c4b478;
73 | --color-link-hover: #957235;
74 | --color-back: #c4b478;
75 | --color-back-hover: #957235;
76 | --color-bg-overlay: rgb(20 21 19);
77 | }
78 |
79 | .demo-6 {
80 | --color-text: #000;
81 | --color-gr-1: #000;
82 | --color-gr-2: #000;
83 | --color-bg: #7f837f;
84 | --color-link: #c0c8c2;
85 | --color-link-hover: #000;
86 | --color-back: #c0c8c2;
87 | --color-back-hover: #000;
88 | --color-bg-overlay: rgb(84 87 84);
89 | }
90 |
91 | /* Page Loader */
92 | .js .loading::before,
93 | .js .loading::after {
94 | content: '';
95 | position: fixed;
96 | z-index: 1000;
97 | }
98 |
99 | .js .loading::before {
100 | top: 0;
101 | left: 0;
102 | width: 100%;
103 | height: 100%;
104 | background: var(--color-bg);
105 | }
106 |
107 | .js .loading::after {
108 | top: 50%;
109 | left: 50%;
110 | width: 100px;
111 | height: 100px;
112 | margin: -50px 0 0 -50px;
113 | border-radius: 50%;
114 | border: 2px solid var(--color-gr-2);
115 | animation: loaderAnim 0.7s linear infinite alternate forwards;
116 |
117 | }
118 |
119 | @keyframes loaderAnim {
120 | to {
121 | opacity: 1;
122 | transform: scale3d(0.5,0.5,1);
123 | }
124 | }
125 |
126 | a {
127 | text-decoration: none;
128 | color: var(--color-link);
129 | outline: none;
130 | }
131 |
132 | a:hover {
133 | color: var(--color-link-hover);
134 | outline: none;
135 | }
136 |
137 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
138 | a:focus {
139 | /* Provide a fallback style for browsers
140 | that don't support :focus-visible */
141 | outline: none;
142 | background: lightgrey;
143 | }
144 |
145 | a:focus:not(:focus-visible) {
146 | /* Remove the focus indicator on mouse-focus for browsers
147 | that do support :focus-visible */
148 | background: transparent;
149 | }
150 |
151 | a:focus-visible {
152 | /* Draw a very noticeable focus style for
153 | keyboard-focus on browsers that do support
154 | :focus-visible */
155 | outline: 2px solid red;
156 | background: transparent;
157 | }
158 |
159 | .hover-line,
160 | a.cda-sponsor-link {
161 | white-space: nowrap;
162 | overflow: hidden;
163 | position: relative;
164 | }
165 |
166 | .hover-line::before,
167 | .cda-sponsor-link::before {
168 | content: '';
169 | height: 1px;
170 | width: 100%;
171 | background: currentColor;
172 | position: absolute;
173 | top: 92%;
174 | transition: transform 0.3s;
175 | transform-origin: 0% 50%;
176 | }
177 |
178 | .hover-line:hover::before,
179 | .cda-sponsor-link:hover::before {
180 | transform: scaleX(0);
181 | transform-origin: 100% 50%;
182 | }
183 |
184 | .unbutton {
185 | background: none;
186 | border: 0;
187 | padding: 0;
188 | margin: 0;
189 | font: inherit;
190 | cursor: pointer;
191 | }
192 |
193 | .unbutton:focus {
194 | outline: none;
195 | }
196 |
197 | .hidden {
198 | opacity: 0;
199 | pointer-events: none;
200 | position: absolute;
201 | }
202 |
203 | main {
204 | display: grid;
205 | height: 100vh;
206 | padding: 0;
207 | position: relative;
208 | }
209 |
210 | .frame {
211 | grid-area: 1 / 1 / 2 / 2;
212 | text-align: center;
213 | display: flex;
214 | padding: var(--padding-hor) calc(var(--padding-ver) + 0.6vw);
215 | flex-wrap: wrap;
216 | align-self: start;
217 | position: relative;
218 | z-index: 100;
219 | grid-column-gap: 5vw;
220 | grid-row-gap: 1rem;
221 | font-weight: 600;
222 | background: linear-gradient(to bottom, var(--color-bg), transparent);
223 | }
224 |
225 | .frame__title {
226 | font-size: inherit;
227 | margin: 0;
228 | font-weight: inherit;
229 | }
230 |
231 | .frame__links {
232 | display: flex;
233 | gap: 1rem;
234 | }
235 |
236 | .frame__demos {
237 | display: flex;
238 | gap: 1rem;
239 | }
240 |
241 | .intro,
242 | .content-wrap {
243 | position: relative;
244 | grid-area: 1 / 1 / 2 / 2;
245 | }
246 |
247 | .intro {
248 | flex: 1;
249 | max-height: 80vmax;
250 | margin: auto 0;
251 | padding: 0 var(--padding-ver);
252 | font-size: 9vw;
253 | line-height: 1;
254 | text-transform: uppercase;
255 | display: flex;
256 | flex-wrap: wrap;
257 | column-gap: 2vw;
258 | row-gap: 1vw;
259 | white-space: nowrap;
260 | font-family: "stinger-variable", sans-serif;
261 | font-variation-settings: "wdth" 120, "wght" 300;
262 | background-color: var(--color-text);
263 | background-image: linear-gradient(45deg, var(--color-gr-1), var(--color-gr-2));
264 | background-size: 100%;
265 | background-repeat: repeat;
266 | -webkit-background-clip: text;
267 | -webkit-text-fill-color: transparent;
268 | -moz-background-clip: text;
269 | -moz-text-fill-color: transparent;
270 | will-change: transform, opacity;
271 | }
272 |
273 | .intro--closed {
274 | opacity: 0;
275 | pointer-events: none;
276 | }
277 |
278 | .font-1 {
279 | font-variation-settings: "wdth" 75, "wght" 100;
280 | }
281 |
282 | .font-2 {
283 | font-variation-settings: "wdth" 120, "wght" 800;
284 | }
285 |
286 | .font-3 {
287 | font-variation-settings: "wdth" 120, "wght" 400;
288 | }
289 |
290 | .intro__text {
291 | line-height: 0.6;
292 | padding-top: 2vw;
293 | }
294 |
295 | .intro__image {
296 | flex: 1;
297 | position: relative;
298 | cursor: pointer;
299 | will-change: transform;
300 | background-size: cover;
301 | background-position: 50% 30%;
302 | border-radius: 5vw;
303 | min-width: 50px;
304 | max-width: 100px;
305 | transition: opacity 0.3s;
306 | }
307 |
308 | .intro__image:hover {
309 | opacity: 0.8;
310 | }
311 |
312 | .content-wrap {
313 | align-self: stretch;
314 | display: grid;
315 | pointer-events: none;
316 | }
317 |
318 | .content {
319 | opacity: 0;
320 | pointer-events: none;
321 | grid-area: 1 / 1 / -1 / -1;
322 | display: grid;
323 | grid-template-columns: 100%;
324 | height: 100%;
325 | grid-template-rows: 70% 1fr;
326 | gap: 5vh;
327 | padding: 8rem var(--padding-ver) 2rem;
328 | }
329 |
330 | .content--open {
331 | opacity: 1;
332 | pointer-events: auto;
333 | }
334 |
335 | .content__img {
336 | position: relative;
337 | overflow: hidden;
338 | border-radius: 1.85rem;
339 | display: grid;
340 | will-change: transform, opacity;
341 | }
342 |
343 | .content__img-inner {
344 | background-size: cover;
345 | background-position: 50% 20%;
346 | }
347 |
348 | .content__text {
349 | display: grid;
350 | grid-template-areas:
351 | 'back number title'
352 | '... ... title'
353 | 'meta meta meta';
354 | grid-column-gap: 2rem;
355 | grid-template-columns: auto 1fr auto;
356 | grid-template-rows: auto 1fr auto;
357 | }
358 |
359 | .content__title {
360 | font-variation-settings: "wdth" 120, "wght" 100;
361 | grid-area: title;
362 | margin: 0;
363 | font-family: stinger-variable, sans-serif;
364 | font-size: clamp(2rem, 6vw, 5rem);
365 | background-color: var(--color-text);
366 | background-image: linear-gradient(45deg, var(--color-gr-1), var(--color-gr-2));
367 | background-size: 100%;
368 | background-repeat: repeat;
369 | -webkit-background-clip: text;
370 | -webkit-text-fill-color: transparent;
371 | -moz-background-clip: text;
372 | -moz-text-fill-color: transparent;
373 | line-height: 1;
374 | max-width: 15ch;
375 | text-align: right;
376 | }
377 |
378 | .content__number {
379 | grid-area: number;
380 | line-height: 1;
381 | margin-top: -1vw;
382 | align-self: start;
383 | font-size: clamp(3rem, 6vw, 10rem);
384 | background-color: var(--color-text);
385 | background-image: linear-gradient(45deg, var(--color-gr-1), var(--color-gr-2));
386 | background-size: 100%;
387 | background-repeat: repeat;
388 | -webkit-background-clip: text;
389 | -webkit-text-fill-color: transparent;
390 | -moz-background-clip: text;
391 | -moz-text-fill-color: transparent;
392 | position: relative;
393 | }
394 |
395 | .content__back {
396 | grid-area: back;
397 | overflow: hidden;
398 | align-self: center;
399 | }
400 |
401 | .content__back svg {
402 | width: 4vw;
403 | height: 4.85vw;
404 | fill: var(--color-back);
405 | transition: fill 0.2s;
406 | }
407 |
408 | .content__back:hover svg {
409 | fill: var(--color-back-hover);
410 | }
411 |
412 | .content__meta {
413 | grid-area: meta;
414 | text-transform: uppercase;
415 | display: flex;
416 | justify-content: space-between;
417 | font-size: clamp(0.75rem, 3vw, 1.5rem);
418 | line-height: 1;
419 | }
420 |
421 | .overlay {
422 | grid-area: 1 / 1 / -1 / -1;
423 | display: grid;
424 | position: relative;
425 | z-index: 1000;
426 | pointer-events: none;
427 | opacity: 0;
428 | --columns: 20;
429 | grid-template-columns: repeat(var(--columns),1fr);
430 | }
431 |
432 | .overlay div {
433 | background: var(--color-bg-overlay);
434 | }
435 |
436 | @media screen and (min-width: 53em) {
437 | .intro__image {
438 | min-width: 200px;
439 | max-width: 30%;
440 | }
441 | .content {
442 | padding-top: 5rem;
443 | }
444 | }
445 |
446 |
447 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/favicon.ico
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/1.jpg
--------------------------------------------------------------------------------
/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/10.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/2.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/3.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/4.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/5.jpg
--------------------------------------------------------------------------------
/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/6.jpg
--------------------------------------------------------------------------------
/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/7.jpg
--------------------------------------------------------------------------------
/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/8.jpg
--------------------------------------------------------------------------------
/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/PixelTransition/2651c9d5dc53d895cb7b3d721ddb9bdb1669f9ba/img/9.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 1 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 2 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/index3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 3 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/index4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 2 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/index5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 5 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/index6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Pixel Transition | Demo 6 | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
Pixel Transition
26 |
30 |
39 |
40 |
41 |
Rather
42 |
43 |
than
44 |
45 |
love
46 |
47 |
than
48 |
49 |
money
50 |
51 |
than
52 |
53 |
fame
54 |
55 |
give
56 |
me
57 |
58 |
truth
59 |
60 |
61 |
62 |
63 |
66 |
67 |
Guard your time and attention.
68 |
M36
69 |
74 |
75 | Frank Luck
76 | 1982
77 | Ground Day
78 |
79 |
80 |
81 |
82 |
85 |
86 |
Seek simplicity and nature.
87 |
B13
88 |
93 |
94 | Lora Black
95 | 1985
96 | Lost in Love
97 |
98 |
99 |
100 |
101 |
104 |
105 |
Avoid accumulating needless things.
106 |
G98
107 |
112 |
113 | Lady B.
114 | 1989
115 | Club Byna
116 |
117 |
118 |
119 |
120 |
123 |
124 |
Be conscious of the stories you tell.
125 |
K06
126 |
131 |
132 | Harry D. Walters
133 | 2023
134 | Mad Wanderer
135 |
136 |
137 |
138 |
139 |
142 |
143 |
Rest, reflect, and play.
144 |
W02
145 |
150 |
151 | Cathy Brown
152 | 1992
153 | Free Ride
154 |
155 |
156 |
157 |
158 |
161 |
162 |
Your actions have consequences.
163 |
T67
164 |
169 |
170 | Sarah Zola
171 | 1996
172 | Roundhouse
173 |
174 |
175 |
176 |
177 |
180 |
181 |
Don't compromise your integrity.
182 |
X49
183 |
188 |
189 | Dana Belucci
190 | 2000
191 | Rising Star
192 |
193 |
194 |
195 |
196 |
199 |
200 |
Seek greater wisdom and compassion.
201 |
G05
202 |
207 |
208 | Gerry Ronald
209 | 2001
210 | Messy Luck
211 |
212 |
213 |
214 |
215 |
218 |
219 |
Value experiences over material possessions.
220 |
K16
221 |
226 |
227 | Diana Cohen
228 | 2002
229 | Simple Thing
230 |
231 |
232 |
233 |
234 |
237 |
238 |
Live a life of purpose.
239 |
Z09
240 |
245 |
246 | Mario T. Foy
247 | 2006
248 | The End of all
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/js/demo1/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 8,
19 | columns: 14
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 0.8,
34 | ease: 'power3.inOut',
35 | yPercent: 15,
36 | opacity: 0
37 | });
38 |
39 | overlay.show({
40 | // Specify the cell's transform origin
41 | transformOrigin: '50% 0%',
42 | // Duration for each cell animation
43 | duration: 0.4,
44 | // Ease for each cell animation
45 | ease: 'power3.inOut',
46 | // Stagger function
47 | stagger: index => 0.03 * (overlay.cells.flat()[index].row + gsap.utils.random(0,5))
48 | })
49 | .then(() => {
50 | // show content
51 | intro.classList.add('intro--closed');
52 | contentElements[position].classList.add('content--open');
53 |
54 | // Now hide the overlay
55 | overlay.hide({
56 | // Specify the cell's transform origin
57 | transformOrigin: '50% 100%',
58 | // Duration for each cell animation
59 | duration: 0.4,
60 | // Ease for each cell animation
61 | ease: 'power2',
62 | // Stagger function
63 | stagger: index => 0.03 * (overlay.cells.flat()[index].row + gsap.utils.random(0,5))
64 | }).then(() => isAnimating = false);
65 |
66 | // Animate content image
67 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
68 | yPercent: -25,
69 | opacity: 0
70 | }, {
71 | duration: 0.8,
72 | ease: 'power3',
73 | yPercent: 0,
74 | opacity: 1
75 | });
76 | })
77 |
78 | });
79 | });
80 |
81 | // Attach click event listeners to each content back button
82 | contentElements.forEach((content, position) => {
83 | content.querySelector('.content__back').addEventListener('click', () => {
84 | if ( isAnimating ) return;
85 | isAnimating = true;
86 |
87 | // Animate content image
88 | gsap.to(content.querySelector('.content__img'), {
89 | duration: 0.8,
90 | ease: 'power3.inOut',
91 | yPercent: -15,
92 | opacity: 0
93 | });
94 |
95 | overlay.show({
96 | // Specify the cell's transform origin
97 | transformOrigin: '50% 100%',
98 | // Duration for each cell animation
99 | duration: 0.4,
100 | // Ease for each cell animation
101 | ease: 'power3.inOut',
102 | // Stagger function
103 | stagger: (index, _, array) => 0.03 * (overlay.cells.flat()[array.length-index-1].row + gsap.utils.random(0,5))
104 | })
105 | .then(() => {
106 | // hide content
107 | intro.classList.remove('intro--closed');
108 | content.classList.remove('content--open');
109 | // Now hide the overlay
110 | overlay.hide({
111 | // Specify the cell's transform origin
112 | transformOrigin: '50% 0%',
113 | // Duration for each cell animation
114 | duration: 0.4,
115 | // Ease for each cell animation
116 | ease: 'power2',
117 | // Stagger function
118 | stagger: (index, _, array) => 0.03 * (overlay.cells.flat()[array.length-index-1].row + gsap.utils.random(0,5))
119 | }).then(() => isAnimating = false);
120 |
121 | // Animate intro section
122 | gsap.to(intro, {
123 | duration: 0.8,
124 | ease: 'power3',
125 | yPercent: 0,
126 | opacity: 1
127 | });
128 | })
129 |
130 | });
131 | });
132 |
133 | // Preload images and fonts and remove loader
134 | Promise.all([
135 | preloadImages('.intro__image, .content__img-inner'),
136 | preloadFonts('ctp6pec')
137 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo1/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scale: 0,
83 | opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scale: 1.01,
89 | opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scale: 0,
121 | opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/demo2/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 9,
19 | columns: 17
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 1,
34 | ease: 'power3.inOut',
35 | scaleX: 1.8,
36 | opacity: 0
37 | });
38 |
39 | overlay.show({
40 | // Duration for each cell animation
41 | duration: 0.25,
42 | // Ease for each cell animation
43 | ease: 'power1.in',
44 | // Stagger object
45 | stagger: {
46 | grid: [overlay.options.rows, overlay.options.columns],
47 | from: 'center',
48 | each: 0.025
49 | }
50 | })
51 | .then(() => {
52 | // show content
53 | intro.classList.add('intro--closed');
54 | contentElements[position].classList.add('content--open');
55 |
56 | // Now hide the overlay
57 | overlay.hide({
58 | // Duration for each cell animation
59 | duration: 0.25,
60 | // Ease for each cell animation
61 | ease: 'power1',
62 | // Stagger object
63 | stagger: {
64 | grid: [overlay.options.rows, overlay.options.columns],
65 | from: 'center',
66 | each: 0.025
67 | }
68 | }).then(() => isAnimating = false);
69 |
70 | // Animate content image
71 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
72 | scaleX: 0.5,
73 | opacity: 0
74 | }, {
75 | duration: 0.8,
76 | ease: 'power3',
77 | scaleX: 1,
78 | opacity: 1
79 | });
80 | })
81 |
82 | });
83 | });
84 |
85 | // Attach click event listeners to each content back button
86 | contentElements.forEach((content) => {
87 | content.querySelector('.content__back').addEventListener('click', () => {
88 | if ( isAnimating ) return;
89 | isAnimating = true;
90 |
91 | // Animate content image
92 | gsap.to(content.querySelector('.content__img'), {
93 | duration: 0.7,
94 | ease: 'power2.in',
95 | scaleX: 0.75,
96 | opacity: 0
97 | });
98 |
99 | overlay.show({
100 | // Duration for each cell animation
101 | duration: 0.25,
102 | // Ease for each cell animation
103 | ease: 'power1.in',
104 | // Stagger object
105 | stagger: {
106 | grid: [overlay.options.rows, overlay.options.columns],
107 | from: 'edges',
108 | each: 0.025
109 | }
110 | })
111 | .then(() => {
112 | // hide content here
113 | intro.classList.remove('intro--closed');
114 | content.classList.remove('content--open');
115 |
116 | // Now hide the overlay
117 | overlay.hide({
118 | // Duration for each cell animation
119 | duration: 0.25,
120 | // Ease for each cell animation
121 | ease: 'power1',
122 | // Stagger object
123 | stagger: {
124 | grid: [overlay.options.rows, overlay.options.columns],
125 | from: 'edges',
126 | each: 0.025
127 | }
128 | }).then(() => isAnimating = false);
129 |
130 | // Animate intro section
131 | gsap.to(intro, {
132 | duration: 0.8,
133 | ease: 'expo',
134 | scaleX: 1,
135 | opacity: 1
136 | });
137 | })
138 |
139 | });
140 | });
141 |
142 | // Preload images and fonts and remove loader
143 | Promise.all([
144 | preloadImages('.intro__image, .content__img-inner'),
145 | preloadFonts('ctp6pec')
146 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo2/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scale: 0,
83 | opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scale: 1.03,
89 | opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scale: 0,
121 | opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/demo3/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 7,
19 | columns: 13
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 0.7,
34 | ease: 'power2.in',
35 | scale: 0.75
36 | });
37 |
38 | overlay.show({
39 | // Duration for each cell animation
40 | duration: 0.3,
41 | // Ease for each cell animation
42 | ease: 'power1.inOut',
43 | // Stagger object
44 | stagger: {
45 | grid: [overlay.options.rows, overlay.options.columns],
46 | from: 'end',
47 | each: 0.035
48 | }
49 | })
50 | .then(() => {
51 | // show content
52 | intro.classList.add('intro--closed');
53 | contentElements[position].classList.add('content--open');
54 |
55 | // Now hide the overlay
56 | overlay.hide({
57 | // Duration for each cell animation
58 | duration: 0.3,
59 | // Ease for each cell animation
60 | ease: 'power3',
61 | // Stagger object
62 | stagger: {
63 | grid: [overlay.options.rows, overlay.options.columns],
64 | from: 'end',
65 | each: 0.035
66 | }
67 | }).then(() => isAnimating = false);
68 |
69 | // Animate content image
70 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
71 | scale: 1.2
72 | }, {
73 | duration: 0.9,
74 | ease: 'expo',
75 | scale: 1
76 | });
77 | })
78 |
79 | });
80 | });
81 |
82 | // Attach click event listeners to each content back button
83 | contentElements.forEach((content) => {
84 | content.querySelector('.content__back').addEventListener('click', () => {
85 | if ( isAnimating ) return;
86 | isAnimating = true;
87 |
88 | // Animate content image
89 | gsap.to(content.querySelector('.content__img'), {
90 | duration: 0.7,
91 | ease: 'power2.in',
92 | scale: 1.2
93 | });
94 |
95 | overlay.show({
96 | // Duration for each cell animation
97 | duration: 0.3,
98 | // Ease for each cell animation
99 | ease: 'power1.inOut',
100 | // Stagger object
101 | stagger: {
102 | grid: [overlay.options.rows, overlay.options.columns],
103 | from: 'start',
104 | each: 0.035
105 | }
106 | })
107 | .then(() => {
108 | // hide content here
109 | intro.classList.remove('intro--closed');
110 | content.classList.remove('content--open');
111 |
112 | // Now hide the overlay
113 | overlay.hide({
114 | // Duration for each cell animation
115 | duration: 0.3,
116 | // Ease for each cell animation
117 | ease: 'power3',
118 | // Stagger object
119 | stagger: {
120 | grid: [overlay.options.rows, overlay.options.columns],
121 | from: 'start',
122 | each: 0.035
123 | }
124 | }).then(() => isAnimating = false);
125 |
126 | // Animate intro section
127 | gsap.to(intro, {
128 | duration: 0.9,
129 | ease: 'expo',
130 | scale: 1
131 | });
132 | })
133 |
134 | });
135 | });
136 |
137 | // Preload images and fonts and remove loader
138 | Promise.all([
139 | preloadImages('.intro__image, .content__img-inner'),
140 | preloadFonts('ctp6pec')
141 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo3/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scale: 0,
83 | opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scale: 1.01,
89 | opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scale: 0,
121 | opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/demo4/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 9,
19 | columns: 17
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 0.7,
34 | ease: 'power2.in',
35 | scale: 0.75,
36 | opacity: 0
37 | });
38 |
39 | overlay.show({
40 | // Duration for each cell animation
41 | duration: 0.25,
42 | // Ease for each cell animation
43 | ease: 'power1.in',
44 | // Stagger object
45 | stagger: {
46 | grid: [overlay.options.rows, overlay.options.columns],
47 | from: 'edges',
48 | each: 0.025
49 | }
50 | })
51 | .then(() => {
52 | // show content
53 | intro.classList.add('intro--closed');
54 | contentElements[position].classList.add('content--open');
55 |
56 | // Now hide the overlay
57 | overlay.hide({
58 | // Duration for each cell animation
59 | duration: 0.25,
60 | // Ease for each cell animation
61 | ease: 'power1',
62 | // Stagger object
63 | stagger: {
64 | grid: [overlay.options.rows, overlay.options.columns],
65 | from: 'center',
66 | each: 0.025
67 | }
68 | }).then(() => isAnimating = false);
69 |
70 | // Animate content image
71 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
72 | scale: 0.5,
73 | opacity: 0
74 | }, {
75 | duration: 0.8,
76 | ease: 'power4',
77 | scale: 1,
78 | opacity: 1
79 | });
80 | })
81 |
82 | });
83 | });
84 |
85 | // Attach click event listeners to each content back button
86 | contentElements.forEach((content) => {
87 | content.querySelector('.content__back').addEventListener('click', () => {
88 | if ( isAnimating ) return;
89 | isAnimating = true;
90 |
91 | // Animate content image
92 | gsap.to(content.querySelector('.content__img'), {
93 | duration: 0.7,
94 | ease: 'power2.in',
95 | scale: 0.75,
96 | opacity: 0
97 | });
98 |
99 | overlay.show({
100 | // Duration for each cell animation
101 | duration: 0.25,
102 | // Ease for each cell animation
103 | ease: 'power1.in',
104 | // Stagger object
105 | stagger: {
106 | grid: [overlay.options.rows, overlay.options.columns],
107 | from: 'edges',
108 | each: 0.025
109 | }
110 | })
111 | .then(() => {
112 | // hide content here
113 | intro.classList.remove('intro--closed');
114 | content.classList.remove('content--open');
115 |
116 | // Now hide the overlay
117 | overlay.hide({
118 | // Duration for each cell animation
119 | duration: 0.25,
120 | // Ease for each cell animation
121 | ease: 'power1',
122 | // Stagger object
123 | stagger: {
124 | grid: [overlay.options.rows, overlay.options.columns],
125 | from: 'center',
126 | each: 0.025
127 | }
128 | }).then(() => isAnimating = false);
129 |
130 | // Animate intro section
131 | gsap.to(intro, {
132 | duration: 0.8,
133 | ease: 'power4',
134 | scale: 1,
135 | opacity: 1
136 | });
137 | })
138 |
139 | });
140 | });
141 |
142 | // Preload images and fonts and remove loader
143 | Promise.all([
144 | preloadImages('.intro__image, .content__img-inner'),
145 | preloadFonts('ctp6pec')
146 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo4/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scale: 0,
83 | opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scale: 1.03,
89 | opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scale: 0,
121 | opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/demo5/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 20,
19 | columns: 4
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 0.7,
34 | ease: 'power2.in',
35 | startAt: {filter: 'brightness(100%) saturate(100%)'},
36 | filter: 'brightness(800%) saturate(600%)',
37 | });
38 |
39 | overlay.show({
40 | // Specify the cell's transform origin
41 | transformOrigin: '50% 100%',
42 | // Duration for each cell animation
43 | duration: 0.3,
44 | // Ease for each cell animation
45 | ease: 'power1.in',
46 | // Stagger object
47 | stagger: {
48 | grid: [overlay.options.rows, overlay.options.columns],
49 | from: 'start',
50 | each: 0.02
51 | }
52 | })
53 | .then(() => {
54 | // show content
55 | intro.classList.add('intro--closed');
56 | contentElements[position].classList.add('content--open');
57 |
58 | // Now hide the overlay
59 | overlay.hide({
60 | // Specify the cell's transform origin
61 | transformOrigin: '50% 0%',
62 | // Duration for each cell animation
63 | duration: 0.3,
64 | // Ease for each cell animation
65 | ease: 'power3',
66 | // Stagger object
67 | stagger: {
68 | grid: [overlay.options.rows, overlay.options.columns],
69 | from: 'start',
70 | each: 0.02
71 | }
72 | }).then(() => isAnimating = false);
73 |
74 | // Animate content image
75 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
76 | filter: 'brightness(800%) saturate(600%)'
77 | }, {
78 | duration: 0.8,
79 | ease: 'power4',
80 | filter: 'brightness(100%) saturate(100%)'
81 | });
82 | })
83 |
84 | });
85 | });
86 |
87 | // Attach click event listeners to each content back button
88 | contentElements.forEach((content) => {
89 | content.querySelector('.content__back').addEventListener('click', () => {
90 | if ( isAnimating ) return;
91 | isAnimating = true;
92 |
93 | // Animate content image
94 | gsap.to(content.querySelector('.content__img'), {
95 | duration: 0.7,
96 | ease: 'power2.in',
97 | filter: 'brightness(800%) saturate(600%)',
98 | });
99 |
100 | overlay.show({
101 | // Specify the cell's transform origin
102 | transformOrigin: '50% 0%',
103 | // Duration for each cell animation
104 | duration: 0.3,
105 | // Ease for each cell animation
106 | ease: 'power1.in',
107 | // Stagger object
108 | stagger: {
109 | grid: [overlay.options.rows, overlay.options.columns],
110 | from: 'end',
111 | each: 0.02
112 | }
113 | })
114 | .then(() => {
115 | // hide content here
116 | intro.classList.remove('intro--closed');
117 | content.classList.remove('content--open');
118 |
119 | // Now hide the overlay
120 | overlay.hide({
121 | // Specify the cell's transform origin
122 | transformOrigin: '50% 100%',
123 | // Duration for each cell animation
124 | duration: 0.3,
125 | // Ease for each cell animation
126 | ease: 'power3',
127 | // Stagger object
128 | stagger: {
129 | grid: [overlay.options.rows, overlay.options.columns],
130 | from: 'end',
131 | each: 0.02
132 | }
133 | }).then(() => isAnimating = false);
134 |
135 | // Animate intro section
136 | gsap.to(intro, {
137 | duration: 0.8,
138 | ease: 'power4',
139 | filter: 'brightness(100%) saturate(100%)'
140 | });
141 | })
142 |
143 | });
144 | });
145 |
146 | // Preload images and fonts and remove loader
147 | Promise.all([
148 | preloadImages('.intro__image, .content__img-inner'),
149 | preloadFonts('ctp6pec')
150 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo5/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scaleY: 0,
83 | opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scaleY: 1.03,
89 | opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scaleY: 0,
121 | opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/demo6/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages, preloadFonts } from '../utils.js';
2 | import { Overlay } from './overlay.js';
3 |
4 | // Select the overlay element from the DOM
5 | const overlayEl = document.querySelector('.overlay');
6 |
7 | // Intro
8 | const intro = document.querySelector('.intro');
9 |
10 | // Intro images
11 | const images = [...intro.querySelectorAll('.intro__image')];
12 |
13 | // Content elements
14 | const contentElements = [...document.querySelectorAll('.content-wrap > .content')];
15 |
16 | // Instantiate an Overlay object using the selected overlay element
17 | const overlay = new Overlay(overlayEl, {
18 | rows: 6,
19 | columns: 11
20 | });
21 |
22 | let isAnimating = false;
23 |
24 | // Attach click event listeners to each intro image
25 | images.forEach((image, position) => {
26 | // Show the overlay when an intro image is clicked
27 | image.addEventListener('click', () => {
28 | if ( isAnimating ) return;
29 | isAnimating = true;
30 |
31 | // Animate intro section
32 | gsap.to(intro, {
33 | duration: 1.1,
34 | ease: 'power3.inOut',
35 | xPercent: 5,
36 | opacity: 0
37 | });
38 |
39 | overlay.show({
40 | // Specify the cell's transform origin
41 | transformOrigin: '0% 50%',
42 | // Duration for each cell animation
43 | duration: 0.3,
44 | // Ease for each cell animation
45 | ease: 'power4.in',
46 | // Stagger object
47 | stagger: {
48 | grid: [overlay.options.rows, overlay.options.columns],
49 | from: 'start',
50 | each: 0.04
51 | }
52 | })
53 | .then(() => {
54 | // show content
55 | intro.classList.add('intro--closed');
56 | contentElements[position].classList.add('content--open');
57 |
58 | // Now hide the overlay
59 | overlay.hide({
60 | // Specify the cell's transform origin
61 | transformOrigin: '100% 50%',
62 | // Duration for each cell animation
63 | duration: 0.5,
64 | // Ease for each cell animation
65 | ease: 'power4',
66 | // Stagger function
67 | stagger: {
68 | grid: [overlay.options.rows, overlay.options.columns],
69 | from: 'start',
70 | each: 0.04
71 | }
72 | }).then(() => isAnimating = false);
73 |
74 | // Animate content image
75 | gsap.fromTo(contentElements[position].querySelector('.content__img'), {
76 | xPercent: -10,
77 | opacity: 0
78 | }, {
79 | duration: 0.9,
80 | ease: 'power4',
81 | xPercent: 0,
82 | opacity: 1
83 | });
84 | })
85 |
86 | });
87 | });
88 |
89 | // Attach click event listeners to each content back button
90 | contentElements.forEach((content, position) => {
91 | content.querySelector('.content__back').addEventListener('click', () => {
92 | if ( isAnimating ) return;
93 | isAnimating = true;
94 |
95 | // Animate content image
96 | gsap.to(content.querySelector('.content__img'), {
97 | duration: 1.1,
98 | ease: 'power3.inOut',
99 | xPercent: -5,
100 | opacity: 0
101 | });
102 |
103 | overlay.show({
104 | // Specify the cell's transform origin
105 | transformOrigin: '100% 50%',
106 | // Duration for each cell animation
107 | duration: 0.3,
108 | // Ease for each cell animation
109 | ease: 'power4.in',
110 | // Stagger function
111 | stagger: {
112 | grid: [overlay.options.rows, overlay.options.columns],
113 | from: 'end',
114 | each: 0.04
115 | }
116 | })
117 | .then(() => {
118 | // hide content
119 | intro.classList.remove('intro--closed');
120 | content.classList.remove('content--open');
121 | // Now hide the overlay
122 | overlay.hide({
123 | // Specify the cell's transform origin
124 | transformOrigin: '0% 50%',
125 | // Duration for each cell animation
126 | duration: 0.5,
127 | // Ease for each cell animation
128 | ease: 'power4',
129 | // Stagger function
130 | stagger: {
131 | grid: [overlay.options.rows, overlay.options.columns],
132 | from: 'end',
133 | each: 0.04
134 | }
135 | }).then(() => isAnimating = false);
136 |
137 | // Animate intro section
138 | gsap.fromTo(intro, {
139 | xPercent: 10,
140 | }, {
141 | duration: 0.9,
142 | ease: 'power4',
143 | xPercent: 0,
144 | opacity: 1
145 | });
146 | })
147 |
148 | });
149 | });
150 |
151 | // Preload images and fonts and remove loader
152 | Promise.all([
153 | preloadImages('.intro__image, .content__img-inner'),
154 | preloadFonts('ctp6pec')
155 | ]).then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/js/demo6/overlay.js:
--------------------------------------------------------------------------------
1 |
2 | // Cell class definition
3 | class Cell {
4 | DOM = {
5 | el: null
6 | };
7 | row;
8 | column;
9 |
10 | constructor(row, column) {
11 | this.DOM.el = document.createElement('div');
12 | gsap.set(this.DOM.el, {willChange: 'opacity, transform'});
13 | this.row = row;
14 | this.column = column;
15 | }
16 | }
17 |
18 | // Overlay class definition
19 | export class Overlay {
20 | DOM = {
21 | el: null
22 | };
23 | // cells array
24 | cells = [];
25 | // options
26 | options = {
27 | // Number of cell rows
28 | rows: 10,
29 | // Number of cell columns
30 | columns: 10,
31 | };
32 |
33 | // Constructor accepts a DOM element representing the overlay
34 | constructor(DOM_el, customOptions) {
35 | this.DOM.el = DOM_el;
36 |
37 | // Merge default options with provided options
38 | this.options = Object.assign({}, this.options, customOptions);
39 |
40 | // Set the value of the CSS variable
41 | this.DOM.el.style.setProperty('--columns', this.options.columns);
42 |
43 | // Create an array of all cells
44 | this.cells = new Array(this.options.rows);
45 | for (let i = 0; i < this.options.rows; ++i) {
46 | this.cells[i] = new Array(this.options.columns);
47 | }
48 |
49 | // Fill the array with values
50 | for (let i = 0; i < this.options.rows; ++i) {
51 | for (let j = 0; j < this.options.columns; ++j) {
52 | const cell = new Cell(i,j);
53 | this.cells[i][j] = cell;
54 | this.DOM.el.appendChild(cell.DOM.el);
55 | }
56 | }
57 | }
58 |
59 | // Show the overlay and animate the cells in
60 | show(customConfig = {}) {
61 | return new Promise((resolve) => {
62 | // Default animation configuration
63 | const defaultConfig = {
64 | // Specify the cell's transform origin
65 | transformOrigin: '50% 50%',
66 | // Duration for each cell animation
67 | duration: 0.5,
68 | // Ease for each cell animation
69 | ease: 'none',
70 | // Stagger object
71 | stagger: {
72 | grid: [this.options.rows, this.options.columns],
73 | from: 0,
74 | each: 0.05,
75 | ease: 'none'
76 | }
77 | };
78 | const config = Object.assign({}, defaultConfig, customConfig);
79 |
80 | gsap.set(this.DOM.el, {opacity: 1});
81 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
82 | scaleX: 0,
83 | //opacity: 0,
84 | transformOrigin: config.transformOrigin
85 | }, {
86 | duration: config.duration,
87 | ease: config.ease,
88 | scale: 1.01,
89 | //opacity: 1,
90 | stagger: config.stagger,
91 | onComplete: resolve
92 | });
93 | });
94 | }
95 | // Hide the overlay and animate the cells out
96 | hide(customConfig = {}) {
97 | return new Promise((resolve) => {
98 | // Default animation configuration
99 | const defaultConfig = {
100 | transformOrigin: '50% 50%',
101 | // Duration for each cell animation
102 | duration: 0.5,
103 | // Ease for each cell animation
104 | ease: 'none',
105 | // Stagger object
106 | stagger: {
107 | grid: [this.options.rows, this.options.columns],
108 | from: 0,
109 | each: 0.05,
110 | ease: 'none'
111 | }
112 | };
113 | const config = Object.assign({}, defaultConfig, customConfig);
114 |
115 | gsap.fromTo(this.cells.flat().map(cell => cell.DOM.el), {
116 | transformOrigin: config.transformOrigin
117 | }, {
118 | duration: config.duration,
119 | ease: config.ease,
120 | scaleX: 0,
121 | //opacity: 0,
122 | stagger: config.stagger,
123 | onComplete: resolve
124 | });
125 | });
126 | }
127 | }
--------------------------------------------------------------------------------
/js/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Preload fonts
3 | * @param {String} id
4 | */
5 | const preloadFonts = id => {
6 | return new Promise((resolve) => {
7 | WebFont.load({
8 | typekit: {
9 | id: id
10 | },
11 | active: resolve
12 | });
13 | });
14 | };
15 |
16 | /**
17 | * Preload images
18 | * @param {String} selector - Selector/scope from where images need to be preloaded. Default is 'img'
19 | */
20 | const preloadImages = (selector = 'img') => {
21 | return new Promise((resolve) => {
22 | imagesLoaded(document.querySelectorAll(selector), {background: true}, resolve);
23 | });
24 | };
25 |
26 | export {
27 | preloadFonts,
28 | preloadImages
29 | };
--------------------------------------------------------------------------------