@widelab-nc/widehue 1.0.44 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -4
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
- package/src/index.js +478 -150
package/src/index.js
CHANGED
|
@@ -7,12 +7,9 @@ import { CustomEase } from "gsap/CustomEase";
|
|
|
7
7
|
import { SplitText } from 'gsap/SplitText';
|
|
8
8
|
import Splide from '@splidejs/splide';
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
// GSAP plugins register and custom easing
|
|
12
11
|
gsap.registerPlugin(ScrollTrigger, ScrollToPlugin, CustomEase, SplitText);
|
|
13
12
|
|
|
14
|
-
console.log('SplitText:', typeof SplitText);
|
|
15
|
-
console.log('Registered plugins:', gsap.plugins);
|
|
16
13
|
|
|
17
14
|
function customGsapEasing() {
|
|
18
15
|
CustomEase.create('loader', '0.83, 0, 0.17, 1');
|
|
@@ -27,7 +24,6 @@ let contactFormOpen;
|
|
|
27
24
|
|
|
28
25
|
function refreshScrollTriggersAfterLoad() {
|
|
29
26
|
window.addEventListener('load', () => {
|
|
30
|
-
console.log('[ScrollTrigger] Page fully loaded — refreshing all triggers');
|
|
31
27
|
setTimeout(() => {
|
|
32
28
|
ScrollTrigger.refresh();
|
|
33
29
|
}, 100); // bufor na przypadkowe opóźnienia, możesz zwiększyć
|
|
@@ -66,9 +62,6 @@ function contactFormOpenAnimation() {
|
|
|
66
62
|
|
|
67
63
|
if (checkboxElement) {
|
|
68
64
|
checkboxElement.click(); // Click on the checkbox element
|
|
69
|
-
console.log(`Clicked on checkbox for ${projectCategoryValue}`);
|
|
70
|
-
} else {
|
|
71
|
-
console.log(`No checkbox found for ${projectCategoryValue}`);
|
|
72
65
|
}
|
|
73
66
|
});
|
|
74
67
|
});
|
|
@@ -91,6 +84,19 @@ const lenis = new Lenis({
|
|
|
91
84
|
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
|
92
85
|
});
|
|
93
86
|
function lenisScroll() {
|
|
87
|
+
// Configure ScrollTrigger to use Lenis as the scroller
|
|
88
|
+
ScrollTrigger.scrollerProxy(window, {
|
|
89
|
+
scrollTop(value) {
|
|
90
|
+
if (arguments.length) {
|
|
91
|
+
lenis.scrollTo(value, { immediate: true });
|
|
92
|
+
}
|
|
93
|
+
return lenis.scroll || lenis.actualScroll || window.pageYOffset || 0;
|
|
94
|
+
},
|
|
95
|
+
getBoundingClientRect() {
|
|
96
|
+
return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
94
100
|
lenis.on('scroll', ScrollTrigger.update);
|
|
95
101
|
gsap.ticker.add((time)=>{
|
|
96
102
|
lenis.raf(time * 1000)
|
|
@@ -180,7 +186,6 @@ function revealFooter() {
|
|
|
180
186
|
function checkElementExists(selector) {
|
|
181
187
|
const element = document.querySelector(selector);
|
|
182
188
|
if (!element) {
|
|
183
|
-
console.warn(`Element ${selector} not found - skipping animation`);
|
|
184
189
|
return false;
|
|
185
190
|
}
|
|
186
191
|
return true;
|
|
@@ -188,14 +193,12 @@ function checkElementExists(selector) {
|
|
|
188
193
|
|
|
189
194
|
// Fallback function when loader elements don't exist
|
|
190
195
|
function initBasicAnimations() {
|
|
191
|
-
console.log('Initializing basic animations without loader');
|
|
192
196
|
|
|
193
197
|
if (typeof lenis !== 'undefined') {
|
|
194
198
|
try {
|
|
195
199
|
lenis.scrollTo(0, { immediate: true });
|
|
196
200
|
lenis.start();
|
|
197
201
|
} catch (e) {
|
|
198
|
-
console.warn('Lenis initialization failed:', e);
|
|
199
202
|
window.scrollTo(0, 0);
|
|
200
203
|
}
|
|
201
204
|
} else {
|
|
@@ -204,7 +207,6 @@ function initBasicAnimations() {
|
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
function pageLoadAnimation() {
|
|
207
|
-
console.log('pageLoadAnimation function called');
|
|
208
210
|
|
|
209
211
|
// Check if all required loader elements exist
|
|
210
212
|
const requiredElements = [
|
|
@@ -222,11 +224,9 @@ function pageLoadAnimation() {
|
|
|
222
224
|
}
|
|
223
225
|
|
|
224
226
|
const loaderAnimationIn = gsap.timeline({});
|
|
225
|
-
console.log('GSAP timeline created');
|
|
226
227
|
|
|
227
228
|
loaderAnimationIn
|
|
228
229
|
.add(function() {
|
|
229
|
-
console.log('First animation step triggered: scrollRestoration and scrollTo');
|
|
230
230
|
history.scrollRestoration = 'manual';
|
|
231
231
|
|
|
232
232
|
// Safari-safe scroll to top
|
|
@@ -234,7 +234,6 @@ function pageLoadAnimation() {
|
|
|
234
234
|
try {
|
|
235
235
|
lenis.scrollTo(0, { immediate: true });
|
|
236
236
|
} catch (e) {
|
|
237
|
-
console.warn('Lenis scrollTo failed, using fallback:', e);
|
|
238
237
|
window.scrollTo(0, 0);
|
|
239
238
|
}
|
|
240
239
|
} else {
|
|
@@ -261,7 +260,6 @@ function pageLoadAnimation() {
|
|
|
261
260
|
'<'
|
|
262
261
|
)
|
|
263
262
|
.add(function() {
|
|
264
|
-
console.log('lenis started');
|
|
265
263
|
if (typeof lenis !== 'undefined' && lenis.start) {
|
|
266
264
|
lenis.start();
|
|
267
265
|
}
|
|
@@ -270,26 +268,20 @@ function pageLoadAnimation() {
|
|
|
270
268
|
display: 'none',
|
|
271
269
|
duration: 0.1,
|
|
272
270
|
onComplete: function() {
|
|
273
|
-
console.log('.loader_wrapper set to display:none');
|
|
274
271
|
}
|
|
275
272
|
}, '>');
|
|
276
273
|
|
|
277
|
-
console.log('Animation timeline defined');
|
|
278
274
|
|
|
279
275
|
// Update on screen resize - with element existence check
|
|
280
276
|
window.addEventListener('resize', function () {
|
|
281
|
-
console.log('Window resize event triggered');
|
|
282
277
|
setTimeout(function () {
|
|
283
278
|
if (document.querySelector('.loader_wrapper')) {
|
|
284
|
-
console.log('Set .loader_wrapper to display:none on resize');
|
|
285
279
|
gsap.set('.loader_wrapper', { display: 'none' });
|
|
286
280
|
} else {
|
|
287
|
-
console.warn('Loader wrapper not found on resize');
|
|
288
281
|
}
|
|
289
282
|
}, 50);
|
|
290
283
|
});
|
|
291
284
|
|
|
292
|
-
console.log('Resize event listener added');
|
|
293
285
|
}
|
|
294
286
|
|
|
295
287
|
|
|
@@ -431,22 +423,10 @@ window.standardHeaderScrollAnimation = function() {
|
|
|
431
423
|
const leaveBackTimeline = gsap.timeline({ paused: true });
|
|
432
424
|
|
|
433
425
|
enterTimeline
|
|
434
|
-
.to('.navbar_brand.scale', { scale: 0.25, duration: 1 })
|
|
435
|
-
.to('.wideletter', {
|
|
436
|
-
y: '-150%',
|
|
437
|
-
duration: 1,
|
|
438
|
-
ease: 'loader2',
|
|
439
|
-
stagger: 0.1,
|
|
440
|
-
}, 0); // 0 to start simultaneously with the previous animation
|
|
426
|
+
.to('.navbar_brand.scale', { scale: 0.25, duration: 1 });
|
|
441
427
|
|
|
442
428
|
leaveBackTimeline
|
|
443
|
-
.to('.navbar_brand.scale', { scale: 1, duration: 1 })
|
|
444
|
-
.to('.wideletter', {
|
|
445
|
-
y: '0%',
|
|
446
|
-
duration: 1,
|
|
447
|
-
ease: 'loader2',
|
|
448
|
-
stagger: 0.1,
|
|
449
|
-
}, 0);
|
|
429
|
+
.to('.navbar_brand.scale', { scale: 1, duration: 1 });
|
|
450
430
|
|
|
451
431
|
ScrollTrigger.create({
|
|
452
432
|
start: 'top+=100 top', // Triggers when the user has scrolled 100px
|
|
@@ -493,134 +473,177 @@ window.customCursorText = function(e) {
|
|
|
493
473
|
|
|
494
474
|
|
|
495
475
|
window.heroAnimationOnLoad = function(e) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const hasPlayedAnimation = window.name.includes('heroPlayed');
|
|
476
|
+
const video = document.getElementById('herovideo');
|
|
499
477
|
|
|
500
478
|
gsap.set('.wideletter', { y: '-150%', scale: 1 });
|
|
501
479
|
|
|
502
480
|
if (typeof lenis !== 'undefined') {
|
|
503
|
-
|
|
504
|
-
setTimeout(() => {
|
|
505
|
-
lenis.scrollTo(0, { duration: 0, easing: (t) => t });
|
|
506
|
-
console.log('Lenis scrollTo action called after delay');
|
|
507
|
-
}, 100);
|
|
508
|
-
} else {
|
|
509
|
-
console.log('Lenis instance not found');
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const videoMask = e.querySelector('.hero_headline_ract-mask');
|
|
513
|
-
const video = e.querySelector('video.lazyload');
|
|
514
|
-
const heroAnimation = gsap.timeline({});
|
|
515
|
-
const homeHeroHeading = new SplitText('#heroHeading', {
|
|
516
|
-
type: 'lines',
|
|
517
|
-
linesClass: 'hero-line',
|
|
518
|
-
});
|
|
519
|
-
const homeHeroHeadingMask = new SplitText('#heroHeading', {
|
|
520
|
-
type: 'lines',
|
|
521
|
-
linesClass: 'hero-line-mask',
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
const heroLines = document.querySelectorAll('.hero-line');
|
|
525
|
-
if (heroLines.length === 0) {
|
|
526
|
-
console.error('GSAP target .hero-line not found.');
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
function updateVideoSources() {
|
|
531
|
-
const isMobile = window.innerWidth < 992;
|
|
532
|
-
const mobileMp4 = video.getAttribute('mobile-mp4');
|
|
533
|
-
const mobileWebm = video.getAttribute('mobile-webm');
|
|
534
|
-
const mp4Source = video.querySelector('source[type="video/mp4"]');
|
|
535
|
-
const webmSource = video.querySelector('source[type="video/webm"]');
|
|
536
|
-
|
|
537
|
-
if (isMobile) {
|
|
538
|
-
if (mobileMp4) mp4Source.setAttribute('data-src', mobileMp4);
|
|
539
|
-
if (mobileWebm) webmSource.setAttribute('data-src', mobileWebm);
|
|
540
|
-
} else {
|
|
541
|
-
mp4Source.setAttribute('data-src', mp4Source.getAttribute('data-src').replace('mobile-', ''));
|
|
542
|
-
webmSource.setAttribute('data-src', webmSource.getAttribute('data-src').replace('mobile-', ''));
|
|
543
|
-
}
|
|
481
|
+
setTimeout(() => lenis.scrollTo(0, { duration: 0, easing: (t) => t }), 100);
|
|
544
482
|
}
|
|
545
483
|
|
|
546
|
-
|
|
547
|
-
window.addEventListener('resize', updateVideoSources);
|
|
548
|
-
|
|
484
|
+
let videoPlayListener = null;
|
|
549
485
|
if (video) {
|
|
486
|
+
video.pause();
|
|
487
|
+
video.currentTime = 0;
|
|
488
|
+
function updateVideoSources() {
|
|
489
|
+
const isMobile = window.innerWidth < 992;
|
|
490
|
+
const mobileMp4 = video.getAttribute('mobile-mp4');
|
|
491
|
+
const mobileWebm = video.getAttribute('mobile-webm');
|
|
492
|
+
const mp4Source = video.querySelector('source[type="video/mp4"]');
|
|
493
|
+
const webmSource = video.querySelector('source[type="video/webm"]');
|
|
494
|
+
if (mobileMp4 && mp4Source) mp4Source.setAttribute('data-src', mobileMp4);
|
|
495
|
+
if (mobileWebm && webmSource) webmSource.setAttribute('data-src', mobileWebm);
|
|
496
|
+
if (!isMobile && mp4Source) mp4Source.setAttribute('data-src', mp4Source.getAttribute('data-src')?.replace('mobile-', '') || '');
|
|
497
|
+
if (!isMobile && webmSource) webmSource.setAttribute('data-src', webmSource.getAttribute('data-src')?.replace('mobile-', '') || '');
|
|
498
|
+
}
|
|
499
|
+
updateVideoSources();
|
|
500
|
+
window.addEventListener('resize', updateVideoSources);
|
|
550
501
|
video.setAttribute('data-no-autoplay', 'true');
|
|
551
502
|
video.addEventListener('loadeddata', () => {
|
|
552
503
|
if (video.hasAttribute('data-no-autoplay')) {
|
|
553
504
|
video.pause();
|
|
505
|
+
video.currentTime = 0;
|
|
554
506
|
}
|
|
555
507
|
});
|
|
508
|
+
videoPlayListener = () => {
|
|
509
|
+
console.log('[heroAnimationOnLoad] Video play event! currentTime:', video.currentTime);
|
|
510
|
+
if (video.hasAttribute('data-no-autoplay')) {
|
|
511
|
+
console.log('[heroAnimationOnLoad] Video has data-no-autoplay, forcing pause');
|
|
512
|
+
video.pause();
|
|
513
|
+
video.currentTime = 0;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
video.addEventListener('play', videoPlayListener);
|
|
517
|
+
} else {
|
|
556
518
|
}
|
|
557
519
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
520
|
+
function run() {
|
|
521
|
+
const introBrand = document.querySelector('.preloader [intro-brand]');
|
|
522
|
+
const preloader = introBrand ? introBrand.closest('.preloader') : document.querySelector('.preloader');
|
|
523
|
+
const wrapIt = document.querySelector('.wrap-it') || preloader?.closest('.wrap-it') || preloader;
|
|
524
|
+
const introSubtitle = preloader ? preloader.querySelector('[intro-subtitle]') : null;
|
|
525
|
+
const widelettersIntro = introBrand ? introBrand.querySelectorAll('.wideletter-intro') : [];
|
|
526
|
+
|
|
527
|
+
let savedScrollY = 0;
|
|
528
|
+
const preventScroll = (e) => e.preventDefault();
|
|
529
|
+
|
|
530
|
+
function lockScroll() {
|
|
531
|
+
savedScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
532
|
+
document.body.style.position = 'fixed';
|
|
533
|
+
document.body.style.top = `-${savedScrollY}px`;
|
|
534
|
+
document.body.style.left = '0';
|
|
535
|
+
document.body.style.right = '0';
|
|
536
|
+
document.body.style.width = '100%';
|
|
537
|
+
document.body.style.overflow = 'hidden';
|
|
538
|
+
document.documentElement.style.overflow = 'hidden';
|
|
539
|
+
history.scrollRestoration = 'manual';
|
|
540
|
+
if (typeof lenis !== 'undefined' && lenis.stop) lenis.stop();
|
|
541
|
+
document.addEventListener('wheel', preventScroll, { passive: false });
|
|
542
|
+
document.addEventListener('touchmove', preventScroll, { passive: false });
|
|
543
|
+
}
|
|
564
544
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
545
|
+
// Lock scroll IMMEDIATELY at the start - before any animation
|
|
546
|
+
lockScroll();
|
|
547
|
+
|
|
548
|
+
function unlockScroll() {
|
|
549
|
+
document.body.style.position = '';
|
|
550
|
+
document.body.style.top = '';
|
|
551
|
+
document.body.style.left = '';
|
|
552
|
+
document.body.style.right = '';
|
|
553
|
+
document.body.style.width = '';
|
|
554
|
+
document.body.style.overflow = '';
|
|
555
|
+
document.documentElement.style.overflow = '';
|
|
556
|
+
document.removeEventListener('wheel', preventScroll);
|
|
557
|
+
document.removeEventListener('touchmove', preventScroll);
|
|
558
|
+
window.scrollTo(0, savedScrollY);
|
|
559
|
+
if (typeof lenis !== 'undefined' && lenis.start) lenis.start();
|
|
560
|
+
}
|
|
572
561
|
|
|
573
|
-
heroAnimation.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
562
|
+
const heroAnimation = gsap.timeline({});
|
|
563
|
+
|
|
564
|
+
if (preloader && introBrand && introSubtitle && widelettersIntro.length > 0) {
|
|
565
|
+
gsap.set(widelettersIntro, { y: '-150%' });
|
|
566
|
+
|
|
567
|
+
heroAnimation.to({}, { duration: 0.1 });
|
|
568
|
+
heroAnimation.set('.grab', { opacity: 1 });
|
|
569
|
+
heroAnimation.set(introBrand, { opacity: 1 });
|
|
570
|
+
heroAnimation.to(widelettersIntro, { y: '0%', duration: 1, ease: 'loader2', stagger: 0.1 });
|
|
571
|
+
heroAnimation.to({}, { duration: 1 });
|
|
572
|
+
heroAnimation.to(widelettersIntro, { y: '-150%', opacity: 0, duration: 0.6, ease: 'power2.in', stagger: 0.03 });
|
|
573
|
+
heroAnimation.fromTo(introSubtitle, { y: '50%', opacity: 0 }, { y: '0%', opacity: 1, duration: 0.6, ease: 'power2.out' });
|
|
574
|
+
heroAnimation.to({}, { duration: 2 });
|
|
575
|
+
// 5. .wrap-it: height 100vh → 0vh (2s). Video play na START animacji height.
|
|
576
|
+
// Set position: absolute before height animation to prevent body height change
|
|
577
|
+
// NOTE: lockScroll() is already called at the start of run() function
|
|
578
|
+
heroAnimation.set(wrapIt, { position: 'absolute', top: 0, left: 0, width: '100%', height: '100vh', overflow: 'hidden', zIndex: 9999 });
|
|
579
|
+
heroAnimation.to(wrapIt, {
|
|
580
|
+
height: '0vh',
|
|
581
|
+
duration: 2,
|
|
582
|
+
ease: 'power2.out',
|
|
583
|
+
onStart: () => {
|
|
584
|
+
if (video) {
|
|
585
|
+
video.currentTime = 0;
|
|
586
|
+
// Remove attribute and play listener before playing to prevent conflicts
|
|
587
|
+
video.removeAttribute('data-no-autoplay');
|
|
588
|
+
if (videoPlayListener) {
|
|
589
|
+
video.removeEventListener('play', videoPlayListener);
|
|
590
|
+
}
|
|
591
|
+
video.play().then(() => {
|
|
592
|
+
}).catch(err => {
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
onComplete: () => {
|
|
597
|
+
unlockScroll();
|
|
598
|
+
gsap.set(wrapIt, { visibility: 'hidden', pointerEvents: 'none' });
|
|
599
|
+
// Refresh ScrollTrigger after height animation completes to recalculate positions
|
|
600
|
+
ScrollTrigger.refresh();
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
} else if (wrapIt) {
|
|
604
|
+
// NOTE: lockScroll() is already called at the start of run() function
|
|
605
|
+
heroAnimation.set(wrapIt, { position: 'absolute', top: 0, left: 0, width: '100%', height: '100vh', overflow: 'hidden', zIndex: 9999 });
|
|
606
|
+
heroAnimation.to(wrapIt, {
|
|
607
|
+
height: '0vh',
|
|
608
|
+
duration: 2,
|
|
609
|
+
ease: 'power2.out',
|
|
610
|
+
onStart: () => {
|
|
611
|
+
if (video) {
|
|
612
|
+
video.currentTime = 0;
|
|
613
|
+
video.removeAttribute('data-no-autoplay');
|
|
614
|
+
if (videoPlayListener) {
|
|
615
|
+
video.removeEventListener('play', videoPlayListener);
|
|
616
|
+
}
|
|
617
|
+
video.play();
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
onComplete: () => {
|
|
621
|
+
unlockScroll();
|
|
622
|
+
gsap.set(wrapIt, { visibility: 'hidden', pointerEvents: 'none' });
|
|
623
|
+
// Refresh ScrollTrigger after height animation completes to recalculate positions
|
|
624
|
+
ScrollTrigger.refresh();
|
|
625
|
+
},
|
|
626
|
+
});
|
|
627
|
+
}
|
|
578
628
|
|
|
579
|
-
heroAnimation.
|
|
580
|
-
y: '100%'
|
|
581
|
-
}, {
|
|
582
|
-
duration: 0.75,
|
|
583
|
-
y: '0%',
|
|
584
|
-
stagger: 0.2,
|
|
585
|
-
ease: 'loader2',
|
|
586
|
-
}, '<');
|
|
629
|
+
heroAnimation.from('#heroBottomWrapper', { opacity: 0, duration: 1, ease: 'loader2' }, '>-0.4');
|
|
587
630
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
631
|
+
// Literki IN as last step in timeline (initial state)
|
|
632
|
+
const wideletters = document.querySelectorAll('.wideletter');
|
|
633
|
+
if (wideletters.length > 0) {
|
|
634
|
+
heroAnimation.fromTo(wideletters,
|
|
635
|
+
{ y: '-150%', opacity: 0 },
|
|
636
|
+
{ y: '0%', opacity: 1, duration: 1, ease: 'loader2', stagger: 0.1 },
|
|
637
|
+
'>-0.6'
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
593
641
|
|
|
594
|
-
|
|
642
|
+
if (document.readyState === 'complete') {
|
|
643
|
+
run();
|
|
595
644
|
} else {
|
|
596
|
-
|
|
645
|
+
window.addEventListener('load', run);
|
|
597
646
|
}
|
|
598
|
-
|
|
599
|
-
heroAnimation.to('.preloader', {
|
|
600
|
-
scaleY: 0,
|
|
601
|
-
display: "none",
|
|
602
|
-
duration: 1,
|
|
603
|
-
ease: 'loader',
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
heroAnimation.fromTo('.wideletter',
|
|
607
|
-
{ y: '-150%', scale: 1 },
|
|
608
|
-
{ y: '0%', duration: 1, ease: 'loader2', stagger: 0.1 },
|
|
609
|
-
'-=0.5')
|
|
610
|
-
.call(() => {
|
|
611
|
-
if (video) {
|
|
612
|
-
video.removeAttribute('data-no-autoplay');
|
|
613
|
-
video.play();
|
|
614
|
-
}
|
|
615
|
-
}, null, '<');
|
|
616
|
-
|
|
617
|
-
heroAnimation.from('#heroBottomWrapper', {
|
|
618
|
-
opacity: 0,
|
|
619
|
-
duration: 1,
|
|
620
|
-
ease: 'loader2',
|
|
621
|
-
}, '>-0.4');
|
|
622
|
-
|
|
623
|
-
console.log('Animation timeline setup completed');
|
|
624
647
|
};
|
|
625
648
|
|
|
626
649
|
|
|
@@ -745,7 +768,6 @@ window.textScroll = function(e) {
|
|
|
745
768
|
// Ensure .hero-line elements are created
|
|
746
769
|
const heroLines = document.querySelectorAll('.hero-line');
|
|
747
770
|
if (heroLines.length === 0) {
|
|
748
|
-
console.error('GSAP target .hero-line not found.');
|
|
749
771
|
return;
|
|
750
772
|
}
|
|
751
773
|
|
|
@@ -1479,16 +1501,33 @@ window.animationTest4 = function(root) {
|
|
|
1479
1501
|
|
|
1480
1502
|
|
|
1481
1503
|
window.pricingInteraction = function(e) {
|
|
1504
|
+
|
|
1482
1505
|
// Check if the screen width is 992px or wider
|
|
1483
1506
|
if (window.innerWidth >= 992) {
|
|
1507
|
+
|
|
1508
|
+
const tabsContent = document.querySelector('.tabs-content');
|
|
1509
|
+
const tabsMenu = document.querySelector('.tabs-menu');
|
|
1510
|
+
|
|
1511
|
+
console.log('[pricingInteraction] .tabs-content found:', tabsContent);
|
|
1512
|
+
console.log('[pricingInteraction] .tabs-menu found:', tabsMenu);
|
|
1513
|
+
|
|
1514
|
+
if (!tabsContent || !tabsMenu) {
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// Debug computed styles
|
|
1519
|
+
const tabsContentStyles = window.getComputedStyle(tabsContent);
|
|
1520
|
+
const tabsMenuStyles = window.getComputedStyle(tabsMenu);
|
|
1521
|
+
|
|
1484
1522
|
// Create the pinning effect
|
|
1485
|
-
ScrollTrigger.create({
|
|
1523
|
+
const trigger = ScrollTrigger.create({
|
|
1486
1524
|
trigger: ".tabs-content",
|
|
1487
|
-
start: "top-=48px top",
|
|
1488
|
-
end: "bottom bottom",
|
|
1489
|
-
pin: ".tabs-menu",
|
|
1490
|
-
|
|
1525
|
+
start: "top-=48px top",
|
|
1526
|
+
end: "bottom bottom",
|
|
1527
|
+
pin: ".tabs-menu",
|
|
1528
|
+
|
|
1491
1529
|
});
|
|
1530
|
+
|
|
1492
1531
|
}
|
|
1493
1532
|
};
|
|
1494
1533
|
|
|
@@ -1503,7 +1542,6 @@ window.caseStudyInteraction = function(e) {
|
|
|
1503
1542
|
// Video mask animation
|
|
1504
1543
|
const mask = e.querySelector('.portfolio_item_image-mask');
|
|
1505
1544
|
if (!mask) {
|
|
1506
|
-
console.error('Mask element not found in:', e);
|
|
1507
1545
|
return;
|
|
1508
1546
|
}
|
|
1509
1547
|
|
|
@@ -1526,7 +1564,6 @@ window.caseStudyInteraction = function(e) {
|
|
|
1526
1564
|
if (window.innerWidth > 992) {
|
|
1527
1565
|
videoElements.forEach(videoElement => {
|
|
1528
1566
|
if (!videoElement) {
|
|
1529
|
-
console.error('No video element found in:', e);
|
|
1530
1567
|
return;
|
|
1531
1568
|
}
|
|
1532
1569
|
|
|
@@ -2290,7 +2327,6 @@ window.heroSliders = function(e) {
|
|
|
2290
2327
|
},
|
|
2291
2328
|
};
|
|
2292
2329
|
const slider = new Splide(e, config).mount();
|
|
2293
|
-
console.log("Splide instance:", slider);
|
|
2294
2330
|
|
|
2295
2331
|
if (window.innerWidth > 992) {
|
|
2296
2332
|
slider.on('click', function () {
|
|
@@ -2527,6 +2563,42 @@ window.formSubmitAnimation = function(e) {
|
|
|
2527
2563
|
observeDisplayChanges();
|
|
2528
2564
|
}
|
|
2529
2565
|
|
|
2566
|
+
// Scrubbed timeline: progress tied to scroll progress
|
|
2567
|
+
window.initBentoRevealScrub = function (container) {
|
|
2568
|
+
// Respect reduced motion
|
|
2569
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
2570
|
+
container.querySelectorAll(':scope > *').forEach(el => {
|
|
2571
|
+
el.style.opacity = 1;
|
|
2572
|
+
el.style.transform = 'none';
|
|
2573
|
+
});
|
|
2574
|
+
return;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
const items = Array.from(container.children); // direct children only
|
|
2578
|
+
|
|
2579
|
+
// Important: define from state in timeline for scrub to interpolate smoothly
|
|
2580
|
+
const tl = gsap.timeline({
|
|
2581
|
+
scrollTrigger: {
|
|
2582
|
+
trigger: container,
|
|
2583
|
+
start: 'top 90%', // start easing in slightly later
|
|
2584
|
+
end: 'bottom 65%', // full reveal by near the end of container
|
|
2585
|
+
scrub: 0.5, // smoothing; use true for no smoothing
|
|
2586
|
+
markers: false, // uncomment for debugging
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
|
|
2590
|
+
tl.fromTo(items,
|
|
2591
|
+
{ opacity: 0, y: 28 },
|
|
2592
|
+
{
|
|
2593
|
+
opacity: 1,
|
|
2594
|
+
y: 0,
|
|
2595
|
+
ease: 'power2.out',
|
|
2596
|
+
// Duration is ignored by scrub; timeline length maps to scroll distance.
|
|
2597
|
+
// Stagger distributes the items across the timeline for a nice cascade.
|
|
2598
|
+
stagger: { each: 0.12 }
|
|
2599
|
+
}
|
|
2600
|
+
);
|
|
2601
|
+
};
|
|
2530
2602
|
|
|
2531
2603
|
|
|
2532
2604
|
// Refresh Gsap scrollTriggers
|
|
@@ -2563,6 +2635,254 @@ window.closeInfoBar = function() {
|
|
|
2563
2635
|
}
|
|
2564
2636
|
|
|
2565
2637
|
|
|
2638
|
+
// Hero 2026 animation - navbar letters on scroll
|
|
2639
|
+
window.heroAnimation2026 = function(e) {
|
|
2640
|
+
const wideletters = document.querySelectorAll('.wideletter');
|
|
2641
|
+
if (wideletters.length === 0) return;
|
|
2642
|
+
|
|
2643
|
+
// Timeline for letters OUT
|
|
2644
|
+
const lettersOutTimeline = gsap.timeline({ paused: true });
|
|
2645
|
+
lettersOutTimeline.fromTo(wideletters,
|
|
2646
|
+
{ y: '0%', opacity: 1 },
|
|
2647
|
+
{
|
|
2648
|
+
y: '-150%',
|
|
2649
|
+
opacity: 0,
|
|
2650
|
+
duration: 0.6,
|
|
2651
|
+
ease: 'power2.in',
|
|
2652
|
+
stagger: 0.03,
|
|
2653
|
+
}
|
|
2654
|
+
);
|
|
2655
|
+
|
|
2656
|
+
// Trigger: .update26 top reaches 80% viewport → letters OUT, scroll back → reverse
|
|
2657
|
+
const update26 = document.querySelector('.update26');
|
|
2658
|
+
if (!update26) return;
|
|
2659
|
+
|
|
2660
|
+
ScrollTrigger.create({
|
|
2661
|
+
trigger: update26,
|
|
2662
|
+
start: 'top 80%',
|
|
2663
|
+
onEnter: () => lettersOutTimeline.play(),
|
|
2664
|
+
onLeaveBack: () => lettersOutTimeline.reverse(),
|
|
2665
|
+
});
|
|
2666
|
+
};
|
|
2667
|
+
|
|
2668
|
+
// Intro animation on page load
|
|
2669
|
+
window.introAnimation = function(e) {
|
|
2670
|
+
const introBrand = e.querySelector('[intro-brand]');
|
|
2671
|
+
const introSubtitle = e.querySelector('[intro-subtitle]');
|
|
2672
|
+
const widelettersIntro = e.querySelectorAll('.wideletter-intro');
|
|
2673
|
+
|
|
2674
|
+
// Set initial states
|
|
2675
|
+
gsap.set([introBrand, introSubtitle], { opacity: 0 });
|
|
2676
|
+
gsap.set(widelettersIntro, { y: '-150%' });
|
|
2677
|
+
|
|
2678
|
+
// Prevent browser scroll restoration and force scroll to top
|
|
2679
|
+
history.scrollRestoration = 'manual';
|
|
2680
|
+
window.scrollTo(0, 0);
|
|
2681
|
+
|
|
2682
|
+
// Lock scroll: position fixed keeps scrollbar visible but prevents scrolling
|
|
2683
|
+
document.body.style.position = 'fixed';
|
|
2684
|
+
document.body.style.top = '0px';
|
|
2685
|
+
document.body.style.width = '100%';
|
|
2686
|
+
|
|
2687
|
+
// Page load animation - scroll timeline is created AFTER this completes
|
|
2688
|
+
const introTimeline = gsap.timeline({
|
|
2689
|
+
onComplete: () => {
|
|
2690
|
+
// Unlock scroll
|
|
2691
|
+
document.body.style.position = '';
|
|
2692
|
+
document.body.style.top = '';
|
|
2693
|
+
document.body.style.width = '';
|
|
2694
|
+
window.scrollTo(0, 0);
|
|
2695
|
+
|
|
2696
|
+
// Force all letters to final state before creating ScrollTrigger
|
|
2697
|
+
gsap.set(widelettersIntro, { y: '0%', opacity: 1 });
|
|
2698
|
+
gsap.set(introBrand, { opacity: 1 });
|
|
2699
|
+
|
|
2700
|
+
// Small delay to ensure DOM is ready, then create scroll timeline and refresh ScrollTrigger
|
|
2701
|
+
requestAnimationFrame(() => {
|
|
2702
|
+
createScrollTimeline();
|
|
2703
|
+
ScrollTrigger.refresh();
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2706
|
+
});
|
|
2707
|
+
|
|
2708
|
+
introTimeline.to(introBrand, {
|
|
2709
|
+
opacity: 1,
|
|
2710
|
+
duration: 0.1,
|
|
2711
|
+
});
|
|
2712
|
+
|
|
2713
|
+
introTimeline.to(widelettersIntro, {
|
|
2714
|
+
y: '0%',
|
|
2715
|
+
duration: 1,
|
|
2716
|
+
ease: 'loader2',
|
|
2717
|
+
stagger: 0.1,
|
|
2718
|
+
});
|
|
2719
|
+
|
|
2720
|
+
// EXPERIMENTAL: play/reverse version (no parallax)
|
|
2721
|
+
function createScrollTimeline() {
|
|
2722
|
+
// Timeline 1: Letters out
|
|
2723
|
+
const lettersOutTimeline = gsap.timeline({ paused: true });
|
|
2724
|
+
lettersOutTimeline.to(widelettersIntro, {
|
|
2725
|
+
y: '-150%',
|
|
2726
|
+
opacity: 0,
|
|
2727
|
+
duration: 0.6,
|
|
2728
|
+
ease: 'power2.in',
|
|
2729
|
+
stagger: 0.03,
|
|
2730
|
+
});
|
|
2731
|
+
|
|
2732
|
+
// Trigger 1: Letters out (at 20% of section)
|
|
2733
|
+
ScrollTrigger.create({
|
|
2734
|
+
trigger: e,
|
|
2735
|
+
start: 'top top-=20%',
|
|
2736
|
+
onEnter: () => lettersOutTimeline.play(),
|
|
2737
|
+
onLeaveBack: () => lettersOutTimeline.reverse(),
|
|
2738
|
+
});
|
|
2739
|
+
|
|
2740
|
+
// Timeline 2: Subtitle in
|
|
2741
|
+
const subtitleInTimeline = gsap.timeline({ paused: true });
|
|
2742
|
+
subtitleInTimeline.fromTo(introSubtitle,
|
|
2743
|
+
{ y: '50%', opacity: 0 },
|
|
2744
|
+
{ y: '0%', opacity: 1, duration: 0.6, ease: 'power2.out' }
|
|
2745
|
+
);
|
|
2746
|
+
|
|
2747
|
+
// Trigger 2: Subtitle in (at 90% of section)
|
|
2748
|
+
ScrollTrigger.create({
|
|
2749
|
+
trigger: e,
|
|
2750
|
+
start: 'top top-=90%',
|
|
2751
|
+
onEnter: () => subtitleInTimeline.play(),
|
|
2752
|
+
onLeaveBack: () => subtitleInTimeline.reverse(),
|
|
2753
|
+
});
|
|
2754
|
+
|
|
2755
|
+
// Timeline 3: Subtitle out
|
|
2756
|
+
const subtitleOutTimeline = gsap.timeline({ paused: true });
|
|
2757
|
+
subtitleOutTimeline.to(introSubtitle, {
|
|
2758
|
+
opacity: 0,
|
|
2759
|
+
duration: 0.5,
|
|
2760
|
+
ease: 'power2.out',
|
|
2761
|
+
});
|
|
2762
|
+
|
|
2763
|
+
// Trigger 3: Subtitle out (at 140% - well into section scroll)
|
|
2764
|
+
ScrollTrigger.create({
|
|
2765
|
+
trigger: e,
|
|
2766
|
+
start: 'top top-=140%',
|
|
2767
|
+
onEnter: () => subtitleOutTimeline.play(),
|
|
2768
|
+
onLeaveBack: () => subtitleOutTimeline.reverse(),
|
|
2769
|
+
});
|
|
2770
|
+
}
|
|
2771
|
+
};
|
|
2772
|
+
|
|
2773
|
+
// Global GSAP title animation - animates [gsap-title] elements on scroll
|
|
2774
|
+
function gsapTitleAnimation() {
|
|
2775
|
+
const gsapTitles = document.querySelectorAll('[gsap-title]');
|
|
2776
|
+
|
|
2777
|
+
if (gsapTitles.length === 0) return;
|
|
2778
|
+
|
|
2779
|
+
gsapTitles.forEach((titleElement) => {
|
|
2780
|
+
// Split text into lines
|
|
2781
|
+
const splitTitle = new SplitText(titleElement, {
|
|
2782
|
+
type: 'lines',
|
|
2783
|
+
linesClass: 'gsap-title-line',
|
|
2784
|
+
});
|
|
2785
|
+
|
|
2786
|
+
// Create mask wrapper for each line
|
|
2787
|
+
const splitTitleMask = new SplitText(titleElement, {
|
|
2788
|
+
type: 'lines',
|
|
2789
|
+
linesClass: 'gsap-title-line-mask',
|
|
2790
|
+
});
|
|
2791
|
+
|
|
2792
|
+
const lines = titleElement.querySelectorAll('.gsap-title-line');
|
|
2793
|
+
|
|
2794
|
+
if (lines.length === 0) return;
|
|
2795
|
+
|
|
2796
|
+
// Set initial state - lines hidden below
|
|
2797
|
+
gsap.set(lines, { y: '100%' });
|
|
2798
|
+
|
|
2799
|
+
// Create paused timeline
|
|
2800
|
+
const titleTimeline = gsap.timeline({ paused: true });
|
|
2801
|
+
|
|
2802
|
+
titleTimeline.to(lines, {
|
|
2803
|
+
y: '0%',
|
|
2804
|
+
duration: 0.75,
|
|
2805
|
+
stagger: 0.2,
|
|
2806
|
+
ease: 'loader2',
|
|
2807
|
+
});
|
|
2808
|
+
|
|
2809
|
+
// Create ScrollTrigger with play only
|
|
2810
|
+
ScrollTrigger.create({
|
|
2811
|
+
trigger: titleElement,
|
|
2812
|
+
start: 'top 80%',
|
|
2813
|
+
animation: titleTimeline,
|
|
2814
|
+
toggleActions: 'play',
|
|
2815
|
+
invalidateOnRefresh: true,
|
|
2816
|
+
});
|
|
2817
|
+
});
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
// Global GSAP container animation - animates direct children of [gsap-container]
|
|
2821
|
+
function gsapContainerAnimation() {
|
|
2822
|
+
const gsapContainers = document.querySelectorAll('[gsap-container]');
|
|
2823
|
+
|
|
2824
|
+
if (gsapContainers.length === 0) return;
|
|
2825
|
+
|
|
2826
|
+
gsapContainers.forEach((container) => {
|
|
2827
|
+
const children = container.children;
|
|
2828
|
+
|
|
2829
|
+
if (children.length === 0) return;
|
|
2830
|
+
|
|
2831
|
+
// Set initial state
|
|
2832
|
+
gsap.set(children, { y: '4rem', opacity: 0 });
|
|
2833
|
+
|
|
2834
|
+
// Create paused timeline
|
|
2835
|
+
const containerTimeline = gsap.timeline({ paused: true });
|
|
2836
|
+
|
|
2837
|
+
containerTimeline.to(children, {
|
|
2838
|
+
y: '0rem',
|
|
2839
|
+
opacity: 1,
|
|
2840
|
+
duration: 1,
|
|
2841
|
+
stagger: 0.1,
|
|
2842
|
+
ease: 'power3.out',
|
|
2843
|
+
});
|
|
2844
|
+
|
|
2845
|
+
// Create ScrollTrigger with play only
|
|
2846
|
+
ScrollTrigger.create({
|
|
2847
|
+
trigger: container,
|
|
2848
|
+
start: 'top 80%',
|
|
2849
|
+
animation: containerTimeline,
|
|
2850
|
+
toggleActions: 'play',
|
|
2851
|
+
invalidateOnRefresh: true,
|
|
2852
|
+
});
|
|
2853
|
+
});
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
// Global GSAP fade animation - fades in [gsap-fade] elements on scroll
|
|
2857
|
+
function gsapFadeAnimation() {
|
|
2858
|
+
const gsapFadeElements = document.querySelectorAll('[gsap-fade]');
|
|
2859
|
+
|
|
2860
|
+
if (gsapFadeElements.length === 0) return;
|
|
2861
|
+
|
|
2862
|
+
gsapFadeElements.forEach((element) => {
|
|
2863
|
+
// Set initial state
|
|
2864
|
+
gsap.set(element, { opacity: 0 });
|
|
2865
|
+
|
|
2866
|
+
// Create paused timeline
|
|
2867
|
+
const fadeTimeline = gsap.timeline({ paused: true });
|
|
2868
|
+
|
|
2869
|
+
fadeTimeline.to(element, {
|
|
2870
|
+
opacity: 1,
|
|
2871
|
+
duration: 2,
|
|
2872
|
+
ease: 'power3.out',
|
|
2873
|
+
});
|
|
2874
|
+
|
|
2875
|
+
// Create ScrollTrigger with play only
|
|
2876
|
+
ScrollTrigger.create({
|
|
2877
|
+
trigger: element,
|
|
2878
|
+
start: 'top 65%',
|
|
2879
|
+
animation: fadeTimeline,
|
|
2880
|
+
toggleActions: 'play',
|
|
2881
|
+
invalidateOnRefresh: true,
|
|
2882
|
+
});
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2566
2886
|
// !!!!!!!!! Keep this Alpine init at the end !!!!!!!!!
|
|
2567
2887
|
window.Webflow ||= [];
|
|
2568
2888
|
window.Webflow.push(() => {
|
|
@@ -2586,6 +2906,14 @@ window.Webflow.push(() => {
|
|
|
2586
2906
|
contactFormOpenAnimation();
|
|
2587
2907
|
openContactFormFromURL();
|
|
2588
2908
|
disableScrollMenu();
|
|
2909
|
+
// Wait for DOM to be fully ready before creating ScrollTriggers
|
|
2910
|
+
setTimeout(() => {
|
|
2911
|
+
gsapTitleAnimation();
|
|
2912
|
+
gsapContainerAnimation();
|
|
2913
|
+
gsapFadeAnimation();
|
|
2914
|
+
// Refresh ScrollTrigger after creating all triggers to sync with Lenis
|
|
2915
|
+
ScrollTrigger.refresh();
|
|
2916
|
+
}, 200);
|
|
2589
2917
|
refreshScrollTriggersAfterLoad();
|
|
2590
2918
|
|
|
2591
2919
|
});
|