├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── css
└── base.css
├── favicon.ico
├── img
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
└── 6.jpg
├── index.html
└── js
├── ScrollTrigger.min.js
├── content.js
├── gsap.min.js
├── imagesloaded.pkgd.min.js
├── index.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 Pixelated Image Loading Effect
2 |
3 | A recreation of the on-scroll pixelated image loading effect seen on [Felicity Ingram](https://www.felicityingram.com/)'s website.
4 |
5 | 
6 |
7 | [Article on Codrops](https://tympanus.net/codrops/?p=)
8 |
9 | [Demo](http://tympanus.net/Development/ImagePixelLoading/)
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: 14px;
9 | --color-text: #fff;
10 | --color-bg: #a98b9a;
11 | --color-link: #fff;
12 | --color-link-hover: #fff;
13 | --padding-page: 2rem;
14 | }
15 |
16 | body {
17 | margin: 0;
18 | color: var(--color-text);
19 | background-color: var(--color-bg);
20 | font-family: "forma-djr-micro",-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
21 | -webkit-font-smoothing: antialiased;
22 | -moz-osx-font-smoothing: grayscale;
23 | text-transform: uppercase;
24 | overflow-x: hidden;
25 | }
26 |
27 | /* Page Loader */
28 | .js .loading::before,
29 | .js .loading::after {
30 | content: '';
31 | position: fixed;
32 | z-index: 1000;
33 | }
34 |
35 | .js .loading::before {
36 | top: 0;
37 | left: 0;
38 | width: 100%;
39 | height: 100%;
40 | background: var(--color-bg);
41 | }
42 |
43 | .js .loading::after {
44 | top: 50%;
45 | left: 50%;
46 | width: 60px;
47 | height: 60px;
48 | margin: -30px 0 0 -30px;
49 | opacity: 0.4;
50 | background: var(--color-link);
51 | animation: loaderAnim 0.7s linear infinite alternate forwards;
52 |
53 | }
54 |
55 | @keyframes loaderAnim {
56 | to {
57 | opacity: 1;
58 | transform: scale3d(0.5,0.5,1);
59 | }
60 | }
61 |
62 | a {
63 | text-decoration: none;
64 | color: var(--color-link);
65 | outline: none;
66 | cursor: pointer;
67 | }
68 |
69 | a:hover {
70 | color: var(--color-link-hover);
71 | outline: none;
72 | }
73 |
74 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
75 | a:focus {
76 | /* Provide a fallback style for browsers
77 | that don't support :focus-visible */
78 | outline: none;
79 | background: lightgrey;
80 | }
81 |
82 | a:focus:not(:focus-visible) {
83 | /* Remove the focus indicator on mouse-focus for browsers
84 | that do support :focus-visible */
85 | background: transparent;
86 | }
87 |
88 | a:focus-visible {
89 | /* Draw a very noticeable focus style for
90 | keyboard-focus on browsers that do support
91 | :focus-visible */
92 | outline: 2px solid red;
93 | background: transparent;
94 | }
95 |
96 | .unbutton {
97 | background: none;
98 | border: 0;
99 | padding: 0;
100 | margin: 0;
101 | font: inherit;
102 | cursor: pointer;
103 | }
104 |
105 | .unbutton:focus {
106 | outline: none;
107 | }
108 |
109 | .frame {
110 | z-index: 1000;
111 | position: fixed;
112 | width: 100%;
113 | padding: var(--padding-page);
114 | display: grid;
115 | grid-template-columns: 100%;
116 | grid-template-areas: 'title' 'prev' 'sponsor';
117 | grid-gap: 0.5rem;
118 | justify-items: start;
119 | align-self: start;
120 | justify-self: start;
121 | pointer-events: none;
122 | align-items: center;
123 | }
124 |
125 | .loading .frame {
126 | opacity: 0;
127 | }
128 |
129 | body #cdawrap {
130 | justify-self: start;
131 | }
132 |
133 | .frame a {
134 | pointer-events: auto;
135 | }
136 |
137 | .frame a:not(.frame__title-back) {
138 | white-space: nowrap;
139 | overflow: hidden;
140 | position: relative;
141 | }
142 |
143 | .frame a:not(.frame__title-back)::before {
144 | content: '';
145 | height: 1px;
146 | width: 100%;
147 | background: currentColor;
148 | position: absolute;
149 | top: 90%;
150 | transition: transform 0.3s;
151 | transform-origin: 0% 50%;
152 | }
153 |
154 | .frame a:not(.frame__title-back):hover::before {
155 | transform: scaleX(0);
156 | transform-origin: 100% 50%;
157 | }
158 |
159 | .frame__title {
160 | grid-area: title;
161 | display: flex;
162 | }
163 |
164 | .frame__title-main {
165 | font-size: inherit;
166 | margin: 0;
167 | font-weight: inherit;
168 | }
169 |
170 | .frame__title-back {
171 | position: relative;
172 | display: flex;
173 | align-items: flex-end;
174 | margin-bottom: 0.15rem;
175 | }
176 |
177 | .frame__title-back span {
178 | display: none;
179 | }
180 |
181 | .frame__title-back svg {
182 | fill: currentColor;
183 | }
184 |
185 | .frame__prev {
186 | grid-area: prev;
187 | }
188 |
189 | .deco {
190 | position: fixed;
191 | stroke: #fff;
192 | stroke-width: 1px;
193 | top: var(--padding-page);
194 | right: var(--padding-page);
195 | z-index: 900;
196 | pointer-events: none;
197 | fill: none;
198 | height: 150px;
199 | width: 150px;
200 | }
201 |
202 | .content {
203 | display: grid;
204 | grid-template-rows: 100vh 1fr auto;
205 | grid-template-columns: 100%;
206 | width: 100vw;
207 | --imgRatio: 1344 / 896;
208 | height: calc(var(--imgRatio) * 100vw);
209 | padding: 0 var(--padding-page);
210 | position: relative;
211 | }
212 |
213 | .canvas-wrap {
214 | position: absolute;
215 | top: 0;
216 | left: 0;
217 | height: 100%;
218 | width: 100%;
219 | background-position: 50% 50%;
220 | background-size: cover;
221 | opacity: 0;
222 | }
223 |
224 | .no-js .canvas-wrap {
225 | opacity: 1;
226 | }
227 |
228 | .content__inner {
229 | position: relative;
230 | justify-self: end;
231 | align-self: end;
232 | padding-bottom: var(--padding-page);
233 | }
234 |
235 | h2 {
236 | position: relative;
237 | font-size: 10vw;
238 | font-weight: 400;
239 | text-align: right;
240 | margin: 0;
241 | line-height: 0.8;
242 | }
243 |
244 | p {
245 | position: relative;
246 | grid-area: content;
247 | margin: 1rem 0 0 auto;
248 | text-align: right;
249 | max-width: 400px;
250 | justify-self: end;
251 | }
252 |
253 | h2 span:nth-child(even) {
254 | font-size: 10.5vw;
255 | font-family: "lores-9-plus-wide", sans-serif;
256 | }
257 |
258 | @media screen and (min-width: 53em) {
259 | .frame {
260 | height: 100vh;
261 | grid-template-columns: auto auto 1fr;
262 | grid-template-rows: auto auto;
263 | grid-template-areas: 'title prev ...' 'sponsor sponsor ...';
264 | align-content: space-between;
265 | justify-items: start;
266 | grid-gap: 2rem;
267 | }
268 | .frame__demos {
269 | justify-self: end;
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/favicon.ico
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/1.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/2.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/3.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/4.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/5.jpg
--------------------------------------------------------------------------------
/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codrops/ImagePixelLoading/672443ebbb4f784150b15e40088b1bf96d110aac/img/6.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | On-Scroll Pixelated Image Loading Effect | Codrops
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 |
32 |
33 |
34 | D A A K O
35 | N i x i e
36 |
37 |
Introducing the ethereal masterpiece, an epitome of sartorial splendor and avant-garde elegance. Behold, the breathtaking embodiment of haute couture opulence that transcends time and space. As your fingertips caress the luxurious fabric, a symphony of tactile delight unfolds, weaving dreams into reality.
38 |
39 |
40 |
41 |
42 |
43 |
44 | R o z e n
45 | N o v u s
46 |
47 |
Draped in cascades of exquisite chiffon, this visionary creation embraces the essence of celestial allure. A celestial tapestry of celestial bodies unfolds, merging delicate sequins and celestial threads with celestial silk, encapsulating the whimsy of stardust captured in every stitch.
48 |
49 |
50 |
51 |
52 |
53 |
54 | J a d e l
55 | A r d e n
56 |
57 |
The silhouette, a celestial dance between the divine and the divine, celebrates the human form, sculpting curves with an otherworldly grace. Each contour, meticulously tailored to accentuate the wearer's individuality, whispers tales of celestial grace and unspoken desires.
58 |
59 |
60 |
61 |
62 |
63 |
64 | A z u r a
65 | E x u l t
66 |
67 |
Emanating an aura of refined enchantment, the color palette transcends earthly confines. Radiant hues, reminiscent of an artist's palette, collide in harmonious symphony. From celestial blues that evoke the tranquil depths of the cosmic ocean to the celestial purples that mirror the twilight hues of distant galaxies, every shade resonates with the very essence of ethereal beauty.
68 |
69 |
70 |
71 |
72 |
73 |
74 | Q u i v o
75 | F o l i a
76 |
77 |
Merging haute couture craftsmanship with the spirit of celestial poetry, this divine creation is an ode to individuality and audacity. A testament to the symbiosis between imagination and technique, it beckons the wearer to embrace their inner divinity and embrace the celestial magnificence that resides within.
78 |
79 |
80 |
81 |
82 |
83 |
84 | N o v u s
85 | O r i e l
86 |
87 |
Prepare to embark on a celestial journey of self-expression, where boundaries fade, and possibilities unfold. This haute couture masterpiece is a celestial hymn, an invitation to transcend the ordinary and embrace the extraordinary. Allow it to adorn your being, and experience the transcendence that only haute couture can bestow upon the soul.
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/js/ScrollTrigger.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * ScrollTrigger 3.11.5
3 | * https://greensock.com
4 | *
5 | * @license Copyright 2023, GreenSock. All rights reserved.
6 | * Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
7 | * @author: Jack Doyle, jack@greensock.com
8 | */
9 |
10 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).window=e.window||{})}(this,function(e){"use strict";function _defineProperties(e,t){for(var r=0;r=Math.abs(r)?t:r}function O(){(De=Me.core.globals().ScrollTrigger)&&De.core&&function _integrate(){var e=De.core,r=e.bridge||{},t=e._scrollers,n=e._proxies;t.push.apply(t,Ie),n.push.apply(n,qe),Ie=t,qe=n,i=function _bridge(e,t){return r[e](t)}}()}function P(e){return(Me=e||r())&&"undefined"!=typeof document&&document.body&&(ke=window,Pe=(Ee=document).documentElement,Oe=Ee.body,t=[ke,Ee,Pe,Oe],Me.utils.clamp,ze=Me.core.context||function(){},Be="onpointerenter"in Oe?"pointer":"mouse",Ae=k.isTouch=ke.matchMedia&&ke.matchMedia("(hover: none), (pointer: coarse)").matches?1:"ontouchstart"in ke||0=o,n=Math.abs(t)>=o;T&&(r||n)&&T(se,e,t,be,me),r&&(m&&0Math.abs(t)?"x":"y",ie=!0),"y"!==ae&&(be[2]+=e,se._vx.update(e,!0)),"x"!==ae&&(me[2]+=t,se._vy.update(t,!0)),n?ee=ee||requestAnimationFrame(Ve):Ve()}function Ye(e){if(!Te(e,1)){var t=(e=M(e,s)).clientX,r=e.clientY,n=t-se.x,o=r-se.y,i=se.isDragging;se.x=t,se.y=r,(i||Math.abs(se.startX-t)>=a||Math.abs(se.startY-r)>=a)&&(h&&(re=!0),i||(se.isDragging=!0),Xe(n,o),i||d&&d(se))}}function _e(e){return e.touches&&1=e)return a[n];return a[n-1]}for(n=a.length,e+=r;n--;)if(a[n]<=e)return a[n];return a[0]}:function(e,t,r){void 0===r&&(r=.001);var n=i(e);return!t||Math.abs(n-e)r&&(n*=t/100),e=e.substr(0,r-1)),e=n+(e in R?R[e]*t:~e.indexOf("%")?parseFloat(e)*t/100:parseFloat(e)||0)}return e}function wb(e,t,r,n,o,i,a,s){var l=o.startColor,c=o.endColor,u=o.fontSize,f=o.indent,p=o.fontWeight,d=Ge.createElement("div"),g=Fa(r)||"fixed"===z(r,"pinType"),h=-1!==e.indexOf("scroller"),v=g?Qe:r,b=-1!==e.indexOf("start"),m=b?l:c,y="border-color:"+m+";font-size:"+u+";color:"+m+";font-weight:"+p+";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;";return y+="position:"+((h||s)&&g?"fixed;":"absolute;"),!h&&!s&&g||(y+=(n===je?S:T)+":"+(i+parseFloat(f))+"px;"),a&&(y+="box-sizing:border-box;text-align:left;width:"+a.offsetWidth+"px;"),d._isStart=b,d.setAttribute("class","gsap-marker-"+e+(t?" marker-"+t:"")),d.style.cssText=y,d.innerText=t||0===t?e+"-"+t:e,v.children[0]?v.insertBefore(d,v.children[0]):v.appendChild(d),d._offset=d["offset"+n.op.d2],X(d,0,n,b),d}function Bb(){return 34Qe.clientWidth)||(Ie.cache++,v?w=w||requestAnimationFrame(W):W(),dt||q("scrollStart"),dt=pt())}function Db(){y=Ke.innerWidth,m=Ke.innerHeight}function Eb(){Ie.cache++,tt||h||Ge.fullscreenElement||Ge.webkitFullscreenElement||b&&y===Ke.innerWidth&&!(Math.abs(Ke.innerHeight-m)>.25*Ke.innerHeight)||c.restart(!0)}function Hb(){return qb($,"scrollEnd",Hb)||Bt(!0)}function Kb(e){for(var t=0;t=A})},Se.update=function(e,t,r){if(!pe||r||e){var n,o,i,a,s,l,c,u=!0===lt?Z:Se.scroll(),f=e?0:(u-O)/F,p=f<0?0:1=Ja(be,he),fe)if(e||!n&&!l)fc(ie,q);else{var g=Ct(ie,!0),h=u-O;fc(ie,Qe,g.top+(he===je?h:0)+Mt,g.left+(he===je?0:h)+Mt)}Rt(n||l?Y:I),j&&p<1&&n||b(V+(1!==p||l?0:H))}}else b(Ca(V+H*p));!ue||k.tween||tt||ft||U.restart(!0),ee&&(s||ce&&p&&(p<1||!st))&&Ze(ee.targets).forEach(function(e){return e.classList[n||ce?"add":"remove"](ee.className)}),!T||ve||e||T(Se),a&&!tt?(ve&&(c&&("complete"===i?C.pause().totalProgress(1):"reset"===i?C.restart(!0).pause():"restart"===i?C.restart(!0):C[i]()),T&&T(Se)),!s&&st||(te&&s&&Qa(Se,te),xe[o]&&Qa(Se,xe[o]),ce&&(1===p?Se.kill(!1,1):xe[o]=0),s||xe[o=1===p?1:3]&&Qa(Se,xe[o])),de&&!n&&Math.abs(Se.getVelocity())>(Na(de)?de:2500)&&(Pa(Se.callbackAnimation),G?G.progress(1):Pa(C,"reverse"===i?1:!p,1))):ve&&T&&!tt&&T(Se)}if(x){var v=pe?u/pe.duration()*(pe._caScrollDist||0):u;y(v+(R._isFlipped?1:0)),x(v)}S&&S(-u/pe.duration()*(pe._caScrollDist||0))}},Se.enable=function(e,t){Se.enabled||(Se.enabled=!0,pb(be,"resize",Eb),pb(me?Ge:be,"scroll",Cb),Te&&pb(ScrollTrigger,"refreshInit",Te),!1!==e&&(Se.progress=Q=0,E=P=ke=Pe()),!1!==t&&Se.refresh())},Se.getTween=function(e){return e&&k?k.tween:G},Se.setPositions=function(e,t){ie&&(V+=e-O,H+=t-e-F,ae===_t&&Se.adjustPinSpacing(t-e-F)),Se.start=O=e,Se.end=A=t,F=t-e,Se.update()},Se.adjustPinSpacing=function(e){if(W&&e){var t=W.indexOf(he.d)+1;W[t]=parseFloat(W[t])+e+Mt,W[1]=parseFloat(W[1])+e+Mt,Rt(W)}},Se.disable=function(e,t){if(Se.enabled&&(!1!==e&&Se.revert(!0,!0),Se.enabled=Se.isActive=!1,t||G&&G.pause(),Z=0,n&&(n.uncache=1),Te&&qb(ScrollTrigger,"refreshInit",Te),U&&(U.pause(),k.tween&&k.tween.kill()&&(k.tween=0)),!me)){for(var r=Pt.length;r--;)if(Pt[r].scroller===be&&Pt[r]!==Se)return;qb(be,"resize",Eb),qb(be,"scroll",Cb)}},Se.kill=function(e,t){Se.disable(e,t),G&&!t&&G.kill(),a&&delete Ot[a];var r=Pt.indexOf(Se);0<=r&&Pt.splice(r,1),r===nt&&0i&&(b()>i?a.progress(1)&&b(i):a.resetTo("scrollY",i))}Oa(e)||(e={}),e.preventDefault=e.isNormalizer=e.allowClicks=!0,e.type||(e.type="wheel,touch"),e.debounce=!!e.debounce,e.id=e.id||"normalizer";var n,i,l,o,a,c,u,s,f=e.normalizeScrollX,t=e.momentum,r=e.allowNestedScroll,p=e.onRelease,d=J(e.target)||Ue,g=Je.core.globals().ScrollSmoother,h=g&&g.get(),v=E&&(e.content&&J(e.content)||h&&!1!==e.content&&!h.smooth()&&h.content()),b=K(d,je),m=K(d,He),y=1,x=(k.isTouch&&Ke.visualViewport?Ke.visualViewport.scale*Ke.visualViewport.width:Ke.outerWidth)/Ke.innerWidth,w=0,_=Ma(t)?function(){return t(n)}:function(){return t||2.8},S=nc(d,e.type,!0,r),T=Ba,M=Ba;return v&&Je.set(v,{y:"+=0"}),e.ignoreCheck=function(e){return E&&"touchmove"===e.type&&function ignoreDrag(){if(o){requestAnimationFrame(Np);var e=Ca(n.deltaY/2),t=M(b.v-e);if(v&&t!==b.v+b.offset){b.offset=t-b.v;var r=Ca((parseFloat(v&&v._gsap.y)||0)-b.offset);v.style.transform="matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, "+r+", 0, 1)",v._gsap.y=r+"px",b.cacheID=Ie.cache,W()}return!0}b.offset&&Rp(),o=!0}()||1.05=i||i-1<=r)&&Je.to({},{onUpdate:Xp,duration:o})}else s.restart(!0);p&&p(e)},e.onWheel=function(){a._ts&&a.pause(),1e3 {
54 | const imgWidth = this.img.width;
55 | const imgHeight = this.img.height;
56 | this.imgRatio = imgWidth / imgHeight;
57 | this.setCanvasSize();
58 | this.render();
59 | // Set up event listeners and triggers
60 | this.initEvents();
61 | };
62 | }
63 |
64 | /**
65 | * Sets up event listeners and the GSAP scroll triggers.
66 | * Handles resize events and triggers the pixelation
67 | * effect when the image enters the viewport.
68 | */
69 | initEvents() {
70 | // Resize event handler
71 | window.addEventListener('resize', () => {
72 | this.setCanvasSize();
73 | this.render();
74 | });
75 |
76 | // Trigger pixelation effect when reaching the
77 | // specific starting point:
78 | ScrollTrigger.create({
79 | trigger: this.DOM.el,
80 | start: 'top+=20% bottom',
81 | onEnter: () => {
82 | this.animatePixels();
83 | },
84 | once: true
85 | });
86 |
87 | // Add parallax effect to titles
88 | gsap.timeline({
89 | scrollTrigger: {
90 | trigger: this.DOM.el,
91 | start: 'top bottom',
92 | end: 'bottom top',
93 | scrub: true
94 | }
95 | })
96 | .to(this.DOM.inner, {
97 | ease: 'none',
98 | yPercent: -100
99 | });
100 |
101 | // show canvasWrap when the element enters the viewport
102 | ScrollTrigger.create({
103 | trigger: this.DOM.el,
104 | start: 'top bottom',
105 | onEnter: () => {
106 | gsap.set(this.DOM.canvasWrap, {
107 | opacity: 1
108 | })
109 | },
110 | once: true
111 | });
112 | }
113 |
114 | /**
115 | * Sets the canvas size based on the dimensions
116 | * of the canvasWrap element.
117 | */
118 | setCanvasSize() {
119 | this.DOM.canvas.width = this.DOM.canvasWrap.offsetWidth;
120 | this.DOM.canvas.height = this.DOM.canvasWrap.offsetHeight;
121 | }
122 |
123 | /**
124 | * Renders the image on the canvas.
125 | * Applies the pixelation effect based on the pixel factor.
126 | */
127 | render() {
128 | const offsetWidth = this.DOM.canvasWrap.offsetWidth;
129 | const offsetHeight = this.DOM.canvasWrap.offsetHeight;
130 | // increase a bit to not have a gap in the end of the image
131 | // when we have big pizel sizes
132 | const w = offsetWidth + offsetWidth * 0.05;
133 | const h = offsetHeight + offsetHeight * 0.05;
134 |
135 | // Calculate the dimensions and position for rendering the image
136 | // within the canvas based on the image aspect ratio.
137 | let newWidth = w;
138 | let newHeight = h;
139 | let newX = 0;
140 | let newY = 0;
141 |
142 | // Adjust the dimensions and position if the image
143 | // aspect ratio is different from the canvas aspect ratio
144 | if (newWidth / newHeight > this.imgRatio) {
145 | newHeight = Math.round(w / this.imgRatio);
146 | // let's keep Y at 0 because we want the pixels to not
147 | // be cut off at the top. Uncomment if you want the
148 | // image to be centered.
149 | // newY = (h - newHeight) / 2;
150 | } else {
151 | newWidth = Math.round(h * this.imgRatio);
152 | newX = (w - newWidth) / 2;
153 | }
154 |
155 | // Get the pixel factor based on the current index
156 | let pxFactor = this.pxFactorValues[this.pxIndex];
157 | const size = pxFactor * 0.01;
158 |
159 | // Turn off image smoothing to achieve the pixelated effect
160 | this.ctx.mozImageSmoothingEnabled = size === 1 ? true : false;
161 | this.ctx.webkitImageSmoothingEnabled = size === 1 ? true : false;
162 | this.ctx.imageSmoothingEnabled = size === 1 ? true : false;
163 |
164 | // Clear the canvas
165 | this.ctx.clearRect(0, 0, this.DOM.canvas.width, this.DOM.canvas.height);
166 |
167 | // Draw the original image at a fraction of the final size
168 | this.ctx.drawImage(this.img, 0, 0, w * size, h * size);
169 |
170 | // Enlarge the minimized image to full size
171 | this.ctx.drawImage(
172 | this.DOM.canvas,
173 | 0,
174 | 0,
175 | w * size,
176 | h * size,
177 | newX,
178 | newY,
179 | newWidth,
180 | newHeight
181 | );
182 | }
183 |
184 | /**
185 | * Animates the pixelation effect.
186 | * Renders the image with increasing pixelation factor at each step.
187 | */
188 | animatePixels() {
189 | if (this.pxIndex < this.pxFactorValues.length) {
190 | // Increase the pixelation factor and continue animating
191 | setTimeout(() => {
192 | // Render the image with the current pixelation factor
193 | this.render();
194 | this.pxIndex++;
195 | this.animatePixels();
196 | }, this.pxIndex === 0 ? 300 : 80); // The first time should be the longest.
197 | }
198 | else {
199 | this.pxIndex = this.pxFactorValues.length - 1;
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/js/gsap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * GSAP 3.11.5
3 | * https://greensock.com
4 | *
5 | * @license Copyright 2023, GreenSock. All rights reserved.
6 | * Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
7 | * @author: Jack Doyle, jack@greensock.com
8 | */
9 |
10 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).window=t.window||{})}(this,function(e){"use strict";function _inheritsLoose(t,e){t.prototype=Object.create(e.prototype),(t.prototype.constructor=t).__proto__=e}function _assertThisInitialized(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function r(t){return"string"==typeof t}function s(t){return"function"==typeof t}function t(t){return"number"==typeof t}function u(t){return void 0===t}function v(t){return"object"==typeof t}function w(t){return!1!==t}function x(){return"undefined"!=typeof window}function y(t){return s(t)||r(t)}function P(t){return(i=yt(t,ot))&&Pe}function Q(t,e){return console.warn("Invalid property",t,"set to",e,"Missing plugin? gsap.registerPlugin()")}function R(t,e){return!e&&console.warn(t)}function S(t,e){return t&&(ot[t]=e)&&i&&(i[t]=e)||ot}function T(){return 0}function ea(t){var e,r,i=t[0];if(v(i)||s(i)||(t=[t]),!(e=(i._gsap||{}).harness)){for(r=gt.length;r--&&!gt[r].targetTest(i););e=gt[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new qt(t[r],e)))||t.splice(r,1);return t}function fa(t){return t._gsap||ea(Mt(t))[0]._gsap}function ga(t,e,r){return(r=t[e])&&s(r)?t[e]():u(r)&&t.getAttribute&&t.getAttribute(e)||r}function ha(t,e){return(t=t.split(",")).forEach(e)||t}function ia(t){return Math.round(1e5*t)/1e5||0}function ja(t){return Math.round(1e7*t)/1e7||0}function ka(t,e){var r=e.charAt(0),i=parseFloat(e.substr(2));return t=parseFloat(t),"+"===r?t+i:"-"===r?t-i:"*"===r?t*i:t/i}function la(t,e){for(var r=e.length,i=0;t.indexOf(e[i])<0&&++ia;)s=s._prev;return s?(e._next=s._next,s._next=e):(e._next=t[r],t[r]=e),e._next?e._next._prev=e:t[i]=e,e._prev=s,e.parent=e._dp=t,e}function ya(t,e,r,i){void 0===r&&(r="_first"),void 0===i&&(i="_last");var n=e._prev,a=e._next;n?n._next=a:t[r]===e&&(t[r]=a),a?a._prev=n:t[i]===e&&(t[i]=n),e._next=e._prev=e.parent=null}function za(t,e){!t.parent||e&&!t.parent.autoRemoveChildren||t.parent.remove(t),t._act=0}function Aa(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var r=t;r;)r._dirty=1,r=r.parent;return t}function Ca(t,e,r,i){return t._startAt&&(B?t._startAt.revert(ht):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,i))}function Ea(t){return t._repeat?Tt(t._tTime,t=t.duration()+t._rDelay)*t:0}function Ga(t,e){return(t-e._start)*e._ts+(0<=e._ts?0:e._dirty?e.totalDuration():e._tDur)}function Ha(t){return t._end=ja(t._start+(t._tDur/Math.abs(t._ts||t._rts||X)||0))}function Ia(t,e){var r=t._dp;return r&&r.smoothChildTiming&&t._ts&&(t._start=ja(r._time-(0X)&&e.render(r,!0)),Aa(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur(n=Math.abs(n))&&(a=i,o=n);return a}function tb(t){return za(t),t.scrollTrigger&&t.scrollTrigger.kill(!!B),t.progress()<1&&St(t,"onInterrupt"),t}function wb(t){if(x()){var e=(t=!t.name&&t.default||t).name,r=s(t),i=e&&!r&&t.init?function(){this._props=[]}:t,n={init:T,render:fe,add:Qt,kill:_e,modifier:pe,rawVars:0},a={targetTest:0,get:0,getSetter:re,aliases:{},register:0};if(Ft(),t!==i){if(pt[e])return;qa(i,qa(ua(t,n),a)),yt(i.prototype,yt(n,ua(t,a))),pt[i.prop=e]=i,t.targetTest&&(gt.push(i),ft[e]=1),e=("css"===e?"CSS":e.charAt(0).toUpperCase()+e.substr(1))+"Plugin"}S(e,i),t.register&&t.register(Pe,i,ge)}else Ct.push(t)}function zb(t,e,r){return(6*(t+=t<0?1:1>16,e>>8&Pt,e&Pt]:0:Dt.black;if(!p){if(","===e.substr(-1)&&(e=e.substr(0,e.length-1)),Dt[e])p=Dt[e];else if("#"===e.charAt(0)){if(e.length<6&&(e="#"+(n=e.charAt(1))+n+(a=e.charAt(2))+a+(s=e.charAt(3))+s+(5===e.length?e.charAt(4)+e.charAt(4):"")),9===e.length)return[(p=parseInt(e.substr(1,6),16))>>16,p>>8&Pt,p&Pt,parseInt(e.substr(7),16)/255];p=[(e=parseInt(e.substr(1),16))>>16,e>>8&Pt,e&Pt]}else if("hsl"===e.substr(0,3))if(p=d=e.match(tt),r){if(~e.indexOf("="))return p=e.match(et),i&&p.length<4&&(p[3]=1),p}else o=+p[0]%360/360,u=p[1]/100,n=2*(h=p[2]/100)-(a=h<=.5?h*(u+1):h+u-h*u),3=U?u.endTime(!1):t._dur;return r(e)&&(isNaN(e)||e in o)?(a=e.charAt(0),s="%"===e.substr(-1),n=e.indexOf("="),"<"===a||">"===a?(0<=n&&(e=e.replace(/=/,"")),("<"===a?u._start:u.endTime(0<=u._repeat))+(parseFloat(e.substr(1))||0)*(s?(n<0?u:i).totalDuration()/100:1)):n<0?(e in o||(o[e]=h),o[e]):(a=parseFloat(e.charAt(n-1)+e.substr(n+1)),s&&i&&(a=a/100*(Z(i)?i[0]:i).totalDuration()),1=r&&te)return i;i=i._next}else for(i=t._last;i&&i._start>=r;){if("isPause"===i.data&&i._start=n._start)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0=this.totalDuration()||!v&&_)&&(f!==this._start&&Math.abs(l)===Math.abs(this._ts)||this._lock||(!t&&g||!(v===m&&0=i&&(a instanceof Jt?e&&n.push(a):(r&&n.push(a),t&&n.push.apply(n,a.getChildren(!0,e,r)))),a=a._next;return n},e.getById=function getById(t){for(var e=this.getChildren(1,1,1),r=e.length;r--;)if(e[r].vars.id===t)return e[r]},e.remove=function remove(t){return r(t)?this.removeLabel(t):s(t)?this.killTweensOf(t):(ya(this,t),t===this._recent&&(this._recent=this._last),Aa(this))},e.totalTime=function totalTime(t,e){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=ja(Rt.time-(0r:!r||s.isActive())&&n.push(s):(i=s.getTweensOf(a,r)).length&&n.push.apply(n,i),s=s._next;return n},e.tweenTo=function tweenTo(t,e){e=e||{};var r,i=this,n=xt(i,t),a=e.startAt,s=e.onStart,o=e.onStartParams,u=e.immediateRender,h=Jt.to(i,qa({ease:e.ease||"none",lazy:!1,immediateRender:!1,time:n,overwrite:"auto",duration:e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale())||X,onStart:function onStart(){if(i.pause(),!r){var t=e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale());h._dur!==t&&Ra(h,t,0,1).render(h._time,!0,!0),r=1}s&&s.apply(h,o||[])}},e));return u?h.render(0):h},e.tweenFromTo=function tweenFromTo(t,e,r){return this.tweenTo(e,qa({startAt:{time:xt(this,t)}},r))},e.recent=function recent(){return this._recent},e.nextLabel=function nextLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t))},e.previousLabel=function previousLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t),1)},e.currentLabel=function currentLabel(t){return arguments.length?this.seek(t,!0):this.previousLabel(this._time+X)},e.shiftChildren=function shiftChildren(t,e,r){void 0===r&&(r=0);for(var i,n=this._first,a=this.labels;n;)n._start>=r&&(n._start+=t,n._end+=t),n=n._next;if(e)for(i in a)a[i]>=r&&(a[i]+=t);return Aa(this)},e.invalidate=function invalidate(t){var e=this._first;for(this._lock=0;e;)e.invalidate(t),e=e._next;return i.prototype.invalidate.call(this,t)},e.clear=function clear(t){void 0===t&&(t=!0);for(var e,r=this._first;r;)e=r._next,this.remove(r),r=e;return this._dp&&(this._time=this._tTime=this._pTime=0),t&&(this.labels={}),Aa(this)},e.totalDuration=function totalDuration(t){var e,r,i,n=0,a=this,s=a._last,o=U;if(arguments.length)return a.timeScale((a._repeat<0?a.duration():a.totalDuration())/(a.reversed()?-t:t));if(a._dirty){for(i=a.parent;s;)e=s._prev,s._dirty&&s.totalDuration(),o<(r=s._start)&&a._sort&&s._ts&&!a._lock?(a._lock=1,Ka(a,s,r-s._delay,1)._lock=0):o=r,r<0&&s._ts&&(n-=r,(!i&&!a._dp||i&&i.smoothChildTiming)&&(a._start+=r/a._ts,a._time-=r,a._tTime-=r),a.shiftChildren(-r,!1,-Infinity),o=0),s._end>n&&s._ts&&(n=s._end),s=e;Ra(a,a===L&&a._time>n?a._time:n,1,1),a._dirty=0}return a._tDur},Timeline.updateRoot=function updateRoot(t){if(L._ts&&(na(L,Ga(t,L)),f=Rt.frame),Rt.frame>=mt){mt+=V.autoSleep||120;var e=L._first;if((!e||!e._ts)&&V.autoSleep&&Rt._listeners.length<2){for(;e&&!e._ts;)e=e._next;e||Rt.sleep()}}},Timeline}(Ut);qa(Xt.prototype,{_lock:0,_hasPause:0,_forcing:0});function ac(t,e,i,n,a,o){var u,h,l,f;if(pt[t]&&!1!==(u=new pt[t]).init(a,u.rawVars?e[t]:function _processVars(t,e,i,n,a){if(s(t)&&(t=Gt(t,a,e,i,n)),!v(t)||t.style&&t.nodeType||Z(t)||J(t))return r(t)?Gt(t,a,e,i,n):t;var o,u={};for(o in t)u[o]=Gt(t[o],a,e,i,n);return u}(e[t],n,a,o,i),i,n,o)&&(i._pt=h=new ge(i._pt,a,t,0,1,u.render,u,0,u.priority),i!==c))for(l=i._ptLookup[i._targets.indexOf(a)],f=u._props.length;f--;)l[u._props[f]]=h;return u}function gc(t,r,e,i){var n,a,s=r.ease||i||"power1.inOut";if(Z(r))a=e[t]||(e[t]=[]),r.forEach(function(t,e){return a.push({t:e/(r.length-1)*100,v:t,e:s})});else for(n in r)a=e[n]||(e[n]=[]),"ease"===n||a.push({t:parseFloat(t),v:r[n],e:s})}var Nt,Wt,Qt=function _addPropTween(t,e,i,n,a,o,u,h,l,f){s(n)&&(n=n(a||0,t,o));var c,d=t[e],p="get"!==i?i:s(d)?l?t[e.indexOf("set")||!s(t["get"+e.substr(3)])?e:"get"+e.substr(3)](l):t[e]():d,_=s(d)?l?ee:te:Zt;if(r(n)&&(~n.indexOf("random(")&&(n=ob(n)),"="===n.charAt(1)&&(!(c=ka(p,n)+(Ya(p)||0))&&0!==c||(n=c))),!f||p!==n||Wt)return isNaN(p*n)||""===n?(d||e in t||Q(e,n),function _addComplexStringPropTween(t,e,r,i,n,a,s){var o,u,h,l,f,c,d,p,_=new ge(this._pt,t,e,0,1,le,null,n),m=0,g=0;for(_.b=r,_.e=i,r+="",(d=~(i+="").indexOf("random("))&&(i=ob(i)),a&&(a(p=[r,i],t,e),r=p[0],i=p[1]),u=r.match(it)||[];o=it.exec(i);)l=o[0],f=i.substring(m,o.index),h?h=(h+1)%5:"rgba("===f.substr(-5)&&(h=1),l!==u[g++]&&(c=parseFloat(u[g-1])||0,_._pt={_next:_._pt,p:f||1===g?f:",",s:c,c:"="===l.charAt(1)?ka(c,l)-c:parseFloat(l)-c,m:h&&h<4?Math.round:0},m=it.lastIndex);return _.c=m")}),s.duration();else{for(l in u={},x)"ease"===l||"easeEach"===l||gc(l,x[l],u,x.easeEach);for(l in u)for(C=u[l].sort(function(t,e){return t.t-e.t}),o=E=0;o=t._tDur||e<0)&&t.ratio===u&&(u&&za(t,1),r||B||(St(t,u?"onComplete":"onReverseComplete",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)}(this,t,e,r);return this},e.targets=function targets(){return this._targets},e.invalidate=function invalidate(t){return t&&this.vars.runBackwards||(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(t),z.prototype.invalidate.call(this,t)},e.resetTo=function resetTo(t,e,r,i){d||Rt.wake(),this._ts||this.play();var n,a=Math.min(this._dur,(this._dp._time-this._start)*this._ts);return this._initted||Kt(this,a),n=this._ease(a/this._dur),function _updatePropTweens(t,e,r,i,n,a,s){var o,u,h,l,f=(t._pt&&t._ptCache||(t._ptCache={}))[e];if(!f)for(f=t._ptCache[e]=[],h=t._ptLookup,l=t._targets.length;l--;){if((o=h[l][e])&&o.d&&o.d._pt)for(o=o.d._pt;o&&o.p!==e&&o.fp!==e;)o=o._next;if(!o)return Wt=1,t.vars[e]="+=0",Kt(t,s),Wt=0,1;f.push(o)}for(l=f.length;l--;)(o=(u=f[l])._pt||u).s=!i&&0!==i||n?o.s+(i||0)+a*o.c:i,o.c=r-o.s,u.e&&(u.e=ia(r)+Ya(u.e)),u.b&&(u.b=o.s+Ya(u.b))}(this,t,e,r,i,n,a)?this.resetTo(t,e,r,i):(Ia(this,0),this.parent||xa(this._dp,this,"_first","_last",this._dp._sort?"_start":0),this.render(0))},e.kill=function kill(t,e){if(void 0===e&&(e="all"),!(t||e&&"all"!==e))return this._lazy=this._pt=0,this.parent?tb(this):this;if(this.timeline){var i=this.timeline.totalDuration();return this.timeline.killTweensOf(t,e,Nt&&!0!==Nt.vars.overwrite)._first||tb(this),this.parent&&i!==this.timeline.totalDuration()&&Ra(this,this._dur*this.timeline._tDur/i,0,1),this}var n,a,s,o,u,h,l,f=this._targets,c=t?Mt(t):f,d=this._ptLookup,p=this._pt;if((!e||"all"===e)&&function _arraysMatch(t,e){for(var r=t.length,i=r===e.length;i&&r--&&t[r]===e[r];);return r<0}(f,c))return"all"===e&&(this._pt=0),tb(this);for(n=this._op=this._op||[],"all"!==e&&(r(e)&&(u={},ha(e,function(t){return u[t]=1}),e=u),e=function _addAliasesToVars(t,e){var r,i,n,a,s=t[0]?fa(t[0]).harness:0,o=s&&s.aliases;if(!o)return e;for(i in r=yt({},e),o)if(i in r)for(n=(a=o[i].split(",")).length;n--;)r[a[n]]=r[i];return r}(f,e)),l=f.length;l--;)if(~c.indexOf(f[l]))for(u in a=d[l],"all"===e?(n[l]=e,o=a,s={}):(s=n[l]=n[l]||{},o=e),o)(h=a&&a[u])&&("kill"in h.d&&!0!==h.d.kill(u)||ya(this,h,"_pt"),delete a[u]),"all"!==s&&(s[u]=1);return this._initted&&!this._pt&&p&&tb(this),this},Tween.to=function to(t,e,r){return new Tween(t,e,r)},Tween.from=function from(t,e){return Va(1,arguments)},Tween.delayedCall=function delayedCall(t,e,r,i){return new Tween(e,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:t,onComplete:e,onReverseComplete:e,onCompleteParams:r,onReverseCompleteParams:r,callbackScope:i})},Tween.fromTo=function fromTo(t,e,r){return Va(2,arguments)},Tween.set=function set(t,e){return e.duration=0,e.repeatDelay||(e.repeat=0),new Tween(t,e)},Tween.killTweensOf=function killTweensOf(t,e,r){return L.killTweensOf(t,e,r)},Tween}(Ut);qa(Jt.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0}),ha("staggerTo,staggerFrom,staggerFromTo",function(r){Jt[r]=function(){var t=new Xt,e=kt.call(arguments,0);return e.splice("staggerFromTo"===r?5:4,0,0),t[r].apply(t,e)}});function oc(t,e,r){return t.setAttribute(e,r)}function wc(t,e,r,i){i.mSet(t,e,i.m.call(i.tween,r,i.mt),i)}var Zt=function _setterPlain(t,e,r){return t[e]=r},te=function _setterFunc(t,e,r){return t[e](r)},ee=function _setterFuncWithParam(t,e,r,i){return t[e](i.fp,r)},re=function _getSetter(t,e){return s(t[e])?te:u(t[e])&&t.setAttribute?oc:Zt},se=function _renderPlain(t,e){return e.set(e.t,e.p,Math.round(1e6*(e.s+e.c*t))/1e6,e)},oe=function _renderBoolean(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},le=function _renderComplexString(t,e){var r=e._pt,i="";if(!t&&e.b)i=e.b;else if(1===t&&e.e)i=e.e;else{for(;r;)i=r.p+(r.m?r.m(r.s+r.c*t):Math.round(1e4*(r.s+r.c*t))/1e4)+i,r=r._next;i+=e.c}e.set(e.t,e.p,i,e)},fe=function _renderPropTweens(t,e){for(var r=e._pt;r;)r.r(t,r.d),r=r._next},pe=function _addPluginModifier(t,e,r,i){for(var n,a=this._pt;a;)n=a._next,a.p===i&&a.modifier(t,e,r),a=n},_e=function _killPropTweensOf(t){for(var e,r,i=this._pt;i;)r=i._next,i.p===t&&!i.op||i.op===t?ya(this,i,"_pt"):i.dep||(e=1),i=r;return!e},me=function _sortPropTweensByPriority(t){for(var e,r,i,n,a=t._pt;a;){for(e=a._next,r=i;r&&r.pr>a.pr;)r=r._next;(a._prev=r?r._prev:n)?a._prev._next=a:i=a,(a._next=r)?r._prev=a:n=a,a=e}t._pt=i},ge=(PropTween.prototype.modifier=function modifier(t,e,r){this.mSet=this.mSet||this.set,this.set=wc,this.m=t,this.mt=r,this.tween=e},PropTween);function PropTween(t,e,r,i,n,a,s,o,u){this.t=e,this.s=i,this.c=n,this.p=r,this.r=a||se,this.d=s||this,this.set=o||Zt,this.pr=u||0,(this._next=t)&&(t._prev=this)}ha(vt+"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger",function(t){return ft[t]=1}),ot.TweenMax=ot.TweenLite=Jt,ot.TimelineLite=ot.TimelineMax=Xt,L=new Xt({sortChildren:!1,defaults:q,autoRemoveChildren:!0,id:"root",smoothChildTiming:!0}),V.stringFilter=Fb;function Dc(t){return(be[t]||xe).map(function(t){return t()})}function Ec(){var t=Date.now(),o=[];2{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));
--------------------------------------------------------------------------------
/js/index.js:
--------------------------------------------------------------------------------
1 | import { preloadImages } from './utils.js';
2 | import { Content } from './content.js';
3 |
4 | // Smooth scrolling.
5 | let lenis;
6 | const initSmoothScrolling = () => {
7 | // Smooth scrolling initialization (using Lenis https://github.com/studio-freight/lenis)
8 | lenis = new Lenis({
9 | lerp: 0.1,
10 | smoothWheel: true,
11 | orientation: 'vertical',
12 | });
13 |
14 | lenis.on('scroll', () => ScrollTrigger.update());
15 |
16 | const scrollFn = () => {
17 | lenis.raf();
18 | requestAnimationFrame(scrollFn);
19 | };
20 | requestAnimationFrame(scrollFn);
21 | };
22 |
23 | // .content elements
24 | const contentElems = [...document.querySelectorAll('.content')];
25 | contentElems.forEach(el => new Content(el));
26 |
27 | // smooth scrolling with Lenis
28 | initSmoothScrolling();
29 |
30 | // Preload images then remove loader (loading class) from body
31 | preloadImages('.canvas-wrap').then(() => document.body.classList.remove('loading'));
--------------------------------------------------------------------------------
/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 | export {
9 | preloadImages,
10 | };
--------------------------------------------------------------------------------