@widelab-nc/widehue 1.0.43 → 1.0.45
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 +408 -37
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -24,6 +24,7 @@ function customGsapEasing() {
|
|
|
24
24
|
// Contact form open animation
|
|
25
25
|
let contactFormOpen;
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
function refreshScrollTriggersAfterLoad() {
|
|
28
29
|
window.addEventListener('load', () => {
|
|
29
30
|
console.log('[ScrollTrigger] Page fully loaded — refreshing all triggers');
|
|
@@ -489,16 +490,12 @@ window.customCursorText = function(e) {
|
|
|
489
490
|
});
|
|
490
491
|
}
|
|
491
492
|
|
|
493
|
+
|
|
494
|
+
|
|
492
495
|
window.heroAnimationOnLoad = function(e) {
|
|
493
496
|
console.log('heroAnimationOnLoad function started');
|
|
494
497
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (performance.navigation.type === 1) {
|
|
498
|
-
sessionStorage.removeItem('hasPlayedHeroAnimation');
|
|
499
|
-
hasPlayedAnimation = null;
|
|
500
|
-
console.log('Page reloaded; session flag cleared.');
|
|
501
|
-
}
|
|
498
|
+
const hasPlayedAnimation = window.name.includes('heroPlayed');
|
|
502
499
|
|
|
503
500
|
gsap.set('.wideletter', { y: '-150%', scale: 1 });
|
|
504
501
|
|
|
@@ -530,7 +527,6 @@ window.heroAnimationOnLoad = function(e) {
|
|
|
530
527
|
return;
|
|
531
528
|
}
|
|
532
529
|
|
|
533
|
-
// Handle video source replacement based on viewport width
|
|
534
530
|
function updateVideoSources() {
|
|
535
531
|
const isMobile = window.innerWidth < 992;
|
|
536
532
|
const mobileMp4 = video.getAttribute('mobile-mp4');
|
|
@@ -539,31 +535,22 @@ window.heroAnimationOnLoad = function(e) {
|
|
|
539
535
|
const webmSource = video.querySelector('source[type="video/webm"]');
|
|
540
536
|
|
|
541
537
|
if (isMobile) {
|
|
542
|
-
if (mobileMp4)
|
|
543
|
-
|
|
544
|
-
}
|
|
545
|
-
if (mobileWebm) {
|
|
546
|
-
webmSource.setAttribute('data-src', mobileWebm);
|
|
547
|
-
}
|
|
538
|
+
if (mobileMp4) mp4Source.setAttribute('data-src', mobileMp4);
|
|
539
|
+
if (mobileWebm) webmSource.setAttribute('data-src', mobileWebm);
|
|
548
540
|
} else {
|
|
549
|
-
// Revert to desktop sources if necessary
|
|
550
541
|
mp4Source.setAttribute('data-src', mp4Source.getAttribute('data-src').replace('mobile-', ''));
|
|
551
542
|
webmSource.setAttribute('data-src', webmSource.getAttribute('data-src').replace('mobile-', ''));
|
|
552
543
|
}
|
|
553
544
|
}
|
|
554
545
|
|
|
555
|
-
// Initial call to update video sources
|
|
556
546
|
updateVideoSources();
|
|
557
|
-
|
|
558
|
-
// Add event listener for window resize to update video sources
|
|
559
547
|
window.addEventListener('resize', updateVideoSources);
|
|
560
548
|
|
|
561
549
|
if (video) {
|
|
562
|
-
// Prevent the video from autoplaying when lazy-loaded
|
|
563
550
|
video.setAttribute('data-no-autoplay', 'true');
|
|
564
551
|
video.addEventListener('loadeddata', () => {
|
|
565
552
|
if (video.hasAttribute('data-no-autoplay')) {
|
|
566
|
-
video.pause();
|
|
553
|
+
video.pause();
|
|
567
554
|
}
|
|
568
555
|
});
|
|
569
556
|
}
|
|
@@ -577,7 +564,6 @@ window.heroAnimationOnLoad = function(e) {
|
|
|
577
564
|
|
|
578
565
|
heroAnimation.to('.navbar_brand_lottie', {
|
|
579
566
|
duration: 1.5,
|
|
580
|
-
// Usuń progress: 1 całkowicie
|
|
581
567
|
onComplete: function() {
|
|
582
568
|
console.log('Lottie animation completed');
|
|
583
569
|
gsap.to('.navbar_brand_lottie', { opacity: 0, duration: 0.25 });
|
|
@@ -605,7 +591,7 @@ window.heroAnimationOnLoad = function(e) {
|
|
|
605
591
|
ease: 'loader2',
|
|
606
592
|
}, '+=1');
|
|
607
593
|
|
|
608
|
-
|
|
594
|
+
window.name += 'heroPlayed;';
|
|
609
595
|
} else {
|
|
610
596
|
console.log('Skipping initial hero line animations as they have already been played in this session');
|
|
611
597
|
}
|
|
@@ -635,7 +621,11 @@ window.heroAnimationOnLoad = function(e) {
|
|
|
635
621
|
}, '>-0.4');
|
|
636
622
|
|
|
637
623
|
console.log('Animation timeline setup completed');
|
|
638
|
-
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
639
629
|
|
|
640
630
|
|
|
641
631
|
window.briefContact = function(e) {
|
|
@@ -1358,18 +1348,15 @@ window.animationTest3 = function(root) {
|
|
|
1358
1348
|
});
|
|
1359
1349
|
};
|
|
1360
1350
|
|
|
1361
|
-
|
|
1362
1351
|
window.animationTest4 = function(root) {
|
|
1363
1352
|
const hoverWrappers = root.querySelectorAll('.h-wrapper');
|
|
1364
1353
|
const hoverMasks = root.querySelectorAll('.hover-mask');
|
|
1365
1354
|
const hoverTitles = root.querySelectorAll('.h-title');
|
|
1366
1355
|
|
|
1367
|
-
// Stałe rozmiary bg-video
|
|
1368
1356
|
const VIDEO_WIDTH = 380;
|
|
1369
1357
|
const VIDEO_HEIGHT = 280;
|
|
1370
1358
|
const VISIBLE_RATIO = 0.7;
|
|
1371
1359
|
|
|
1372
|
-
// Ukryj wszystkie maski na starcie
|
|
1373
1360
|
hoverMasks.forEach(mask => {
|
|
1374
1361
|
mask.style.display = 'none';
|
|
1375
1362
|
mask.style.position = 'fixed';
|
|
@@ -1378,7 +1365,7 @@ window.animationTest4 = function(root) {
|
|
|
1378
1365
|
mask.style.width = '100vw';
|
|
1379
1366
|
mask.style.height = '100vh';
|
|
1380
1367
|
mask.style.zIndex = '999';
|
|
1381
|
-
mask.style.pointerEvents = 'none';
|
|
1368
|
+
mask.style.pointerEvents = 'none';
|
|
1382
1369
|
});
|
|
1383
1370
|
|
|
1384
1371
|
function resetOpacity() {
|
|
@@ -1394,6 +1381,7 @@ window.animationTest4 = function(root) {
|
|
|
1394
1381
|
video.style.left = '';
|
|
1395
1382
|
video.style.top = '';
|
|
1396
1383
|
video.style.position = '';
|
|
1384
|
+
video.style.zIndex = '';
|
|
1397
1385
|
});
|
|
1398
1386
|
}
|
|
1399
1387
|
|
|
@@ -1418,7 +1406,6 @@ window.animationTest4 = function(root) {
|
|
|
1418
1406
|
el.style.position = 'absolute';
|
|
1419
1407
|
el.style.width = `${VIDEO_WIDTH}px`;
|
|
1420
1408
|
el.style.height = `${VIDEO_HEIGHT}px`;
|
|
1421
|
-
el.style.zIndex = '1001';
|
|
1422
1409
|
el.style.pointerEvents = 'none';
|
|
1423
1410
|
}
|
|
1424
1411
|
|
|
@@ -1434,7 +1421,6 @@ window.animationTest4 = function(root) {
|
|
|
1434
1421
|
video.style.width = `${VIDEO_WIDTH}px`;
|
|
1435
1422
|
video.style.height = `${VIDEO_HEIGHT}px`;
|
|
1436
1423
|
video.style.position = 'absolute';
|
|
1437
|
-
video.style.zIndex = '1001';
|
|
1438
1424
|
video.style.pointerEvents = 'none';
|
|
1439
1425
|
});
|
|
1440
1426
|
|
|
@@ -1451,8 +1437,7 @@ window.animationTest4 = function(root) {
|
|
|
1451
1437
|
|
|
1452
1438
|
videoTimeline = gsap.timeline();
|
|
1453
1439
|
|
|
1454
|
-
|
|
1455
|
-
const videoIndexes = Array.from({length: videos.length}, (_, i) => i);
|
|
1440
|
+
const videoIndexes = Array.from({ length: videos.length }, (_, i) => i);
|
|
1456
1441
|
const shuffledIndexes = videoIndexes.sort(() => Math.random() - 0.5);
|
|
1457
1442
|
|
|
1458
1443
|
shuffledIndexes.forEach((videoIndex, timeIndex) => {
|
|
@@ -1460,6 +1445,7 @@ window.animationTest4 = function(root) {
|
|
|
1460
1445
|
|
|
1461
1446
|
videoTimeline.add(() => {
|
|
1462
1447
|
placeElementAtRandomVisiblePosition(video, mask);
|
|
1448
|
+
video.style.zIndex = 1001 + timeIndex; // <-- z-index rośnie
|
|
1463
1449
|
}, timeIndex * 0.75);
|
|
1464
1450
|
|
|
1465
1451
|
videoTimeline.to(video, {
|
|
@@ -1492,18 +1478,51 @@ window.animationTest4 = function(root) {
|
|
|
1492
1478
|
|
|
1493
1479
|
|
|
1494
1480
|
|
|
1495
|
-
|
|
1496
1481
|
window.pricingInteraction = function(e) {
|
|
1482
|
+
console.log('[pricingInteraction] Function called');
|
|
1483
|
+
console.log('[pricingInteraction] Window width:', window.innerWidth);
|
|
1484
|
+
|
|
1497
1485
|
// Check if the screen width is 992px or wider
|
|
1498
1486
|
if (window.innerWidth >= 992) {
|
|
1487
|
+
console.log('[pricingInteraction] Desktop mode - creating pin');
|
|
1488
|
+
|
|
1489
|
+
const tabsContent = document.querySelector('.tabs-content');
|
|
1490
|
+
const tabsMenu = document.querySelector('.tabs-menu');
|
|
1491
|
+
|
|
1492
|
+
console.log('[pricingInteraction] .tabs-content found:', tabsContent);
|
|
1493
|
+
console.log('[pricingInteraction] .tabs-menu found:', tabsMenu);
|
|
1494
|
+
|
|
1495
|
+
if (!tabsContent || !tabsMenu) {
|
|
1496
|
+
console.error('[pricingInteraction] Required elements not found!');
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
// Debug computed styles
|
|
1501
|
+
const tabsContentStyles = window.getComputedStyle(tabsContent);
|
|
1502
|
+
const tabsMenuStyles = window.getComputedStyle(tabsMenu);
|
|
1503
|
+
console.log('[pricingInteraction] .tabs-content styles:', {
|
|
1504
|
+
position: tabsContentStyles.position,
|
|
1505
|
+
height: tabsContentStyles.height,
|
|
1506
|
+
display: tabsContentStyles.display,
|
|
1507
|
+
});
|
|
1508
|
+
console.log('[pricingInteraction] .tabs-menu styles:', {
|
|
1509
|
+
position: tabsMenuStyles.position,
|
|
1510
|
+
height: tabsMenuStyles.height,
|
|
1511
|
+
display: tabsMenuStyles.display,
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1499
1514
|
// Create the pinning effect
|
|
1500
|
-
ScrollTrigger.create({
|
|
1515
|
+
const trigger = ScrollTrigger.create({
|
|
1501
1516
|
trigger: ".tabs-content",
|
|
1502
|
-
start: "top-=48px top",
|
|
1503
|
-
end: "bottom bottom",
|
|
1504
|
-
pin: ".tabs-menu",
|
|
1505
|
-
|
|
1517
|
+
start: "top-=48px top",
|
|
1518
|
+
end: "bottom bottom",
|
|
1519
|
+
pin: ".tabs-menu",
|
|
1520
|
+
|
|
1506
1521
|
});
|
|
1522
|
+
|
|
1523
|
+
console.log('[pricingInteraction] ScrollTrigger created:', trigger);
|
|
1524
|
+
} else {
|
|
1525
|
+
console.log('[pricingInteraction] Mobile mode - skipping pin');
|
|
1507
1526
|
}
|
|
1508
1527
|
};
|
|
1509
1528
|
|
|
@@ -1993,6 +2012,42 @@ window.clientLogosAnimation = function(e) {
|
|
|
1993
2012
|
});
|
|
1994
2013
|
}
|
|
1995
2014
|
|
|
2015
|
+
// Hue Awards animation with individual ScrollTriggers
|
|
2016
|
+
window.hueAwardsAnimation = function(e) {
|
|
2017
|
+
const logoItems = e.querySelectorAll('.clients_collection_item_mask.is-3');
|
|
2018
|
+
|
|
2019
|
+
logoItems.forEach((maskEl) => {
|
|
2020
|
+
const imgEl = maskEl.querySelector('.skills-item_img');
|
|
2021
|
+
|
|
2022
|
+
// Set initial height of mask to 100%
|
|
2023
|
+
gsap.set(maskEl, { height: '100%' });
|
|
2024
|
+
|
|
2025
|
+
// Animate mask height to 0% when it enters viewport
|
|
2026
|
+
gsap.to(maskEl, {
|
|
2027
|
+
scrollTrigger: {
|
|
2028
|
+
trigger: maskEl,
|
|
2029
|
+
start: 'top bottom-=25%',
|
|
2030
|
+
},
|
|
2031
|
+
height: '0%',
|
|
2032
|
+
duration: 0.7,
|
|
2033
|
+
ease: 'loader2',
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2036
|
+
// Animate logo opacity (fade in)
|
|
2037
|
+
gsap.from(imgEl, {
|
|
2038
|
+
scrollTrigger: {
|
|
2039
|
+
trigger: maskEl,
|
|
2040
|
+
start: 'top bottom-=25%',
|
|
2041
|
+
},
|
|
2042
|
+
opacity: 0,
|
|
2043
|
+
delay: 0.4,
|
|
2044
|
+
duration: 0.45,
|
|
2045
|
+
ease: 'loader2',
|
|
2046
|
+
});
|
|
2047
|
+
});
|
|
2048
|
+
};
|
|
2049
|
+
|
|
2050
|
+
|
|
1996
2051
|
// Hero span video on hover
|
|
1997
2052
|
window.heroSpanVideoOnHover = function(e) {
|
|
1998
2053
|
window.customCursorText(e);
|
|
@@ -2506,6 +2561,42 @@ window.formSubmitAnimation = function(e) {
|
|
|
2506
2561
|
observeDisplayChanges();
|
|
2507
2562
|
}
|
|
2508
2563
|
|
|
2564
|
+
// Scrubbed timeline: progress tied to scroll progress
|
|
2565
|
+
window.initBentoRevealScrub = function (container) {
|
|
2566
|
+
// Respect reduced motion
|
|
2567
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
2568
|
+
container.querySelectorAll(':scope > *').forEach(el => {
|
|
2569
|
+
el.style.opacity = 1;
|
|
2570
|
+
el.style.transform = 'none';
|
|
2571
|
+
});
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
const items = Array.from(container.children); // direct children only
|
|
2576
|
+
|
|
2577
|
+
// Important: define from state in timeline for scrub to interpolate smoothly
|
|
2578
|
+
const tl = gsap.timeline({
|
|
2579
|
+
scrollTrigger: {
|
|
2580
|
+
trigger: container,
|
|
2581
|
+
start: 'top 90%', // start easing in slightly later
|
|
2582
|
+
end: 'bottom 65%', // full reveal by near the end of container
|
|
2583
|
+
scrub: 0.5, // smoothing; use true for no smoothing
|
|
2584
|
+
markers: false, // uncomment for debugging
|
|
2585
|
+
}
|
|
2586
|
+
});
|
|
2587
|
+
|
|
2588
|
+
tl.fromTo(items,
|
|
2589
|
+
{ opacity: 0, y: 28 },
|
|
2590
|
+
{
|
|
2591
|
+
opacity: 1,
|
|
2592
|
+
y: 0,
|
|
2593
|
+
ease: 'power2.out',
|
|
2594
|
+
// Duration is ignored by scrub; timeline length maps to scroll distance.
|
|
2595
|
+
// Stagger distributes the items across the timeline for a nice cascade.
|
|
2596
|
+
stagger: { each: 0.12 }
|
|
2597
|
+
}
|
|
2598
|
+
);
|
|
2599
|
+
};
|
|
2509
2600
|
|
|
2510
2601
|
|
|
2511
2602
|
// Refresh Gsap scrollTriggers
|
|
@@ -2542,6 +2633,283 @@ window.closeInfoBar = function() {
|
|
|
2542
2633
|
}
|
|
2543
2634
|
|
|
2544
2635
|
|
|
2636
|
+
// Hero 2026 animation - navbar letters on scroll
|
|
2637
|
+
// EXPERIMENTAL: play/reverse version (to revert: replace this whole function with scrub version)
|
|
2638
|
+
window.heroAnimation2026 = function(e) {
|
|
2639
|
+
const wideletters = document.querySelectorAll('.wideletter');
|
|
2640
|
+
const introSection = document.querySelector('[x-init*="introAnimation"]');
|
|
2641
|
+
|
|
2642
|
+
if (!introSection) return;
|
|
2643
|
+
|
|
2644
|
+
// Wideletters animation timeline (paused)
|
|
2645
|
+
const widelettersTimeline = gsap.timeline({ paused: true });
|
|
2646
|
+
widelettersTimeline.fromTo(wideletters,
|
|
2647
|
+
{ y: '-150%' },
|
|
2648
|
+
{
|
|
2649
|
+
y: '0%',
|
|
2650
|
+
duration: 0.8,
|
|
2651
|
+
ease: 'power2.out',
|
|
2652
|
+
stagger: 0.05,
|
|
2653
|
+
}
|
|
2654
|
+
);
|
|
2655
|
+
|
|
2656
|
+
// Trigger for wideletters
|
|
2657
|
+
ScrollTrigger.create({
|
|
2658
|
+
trigger: introSection,
|
|
2659
|
+
start: 'bottom bottom-=25%',
|
|
2660
|
+
onEnter: () => widelettersTimeline.play(),
|
|
2661
|
+
onLeaveBack: () => widelettersTimeline.reverse(),
|
|
2662
|
+
});
|
|
2663
|
+
|
|
2664
|
+
// Partner section animation
|
|
2665
|
+
const partnerSection = document.querySelector('#partner');
|
|
2666
|
+
const heroFlex = document.querySelector('.hero-flex');
|
|
2667
|
+
const coverBg = document.querySelector('.cover-bg');
|
|
2668
|
+
|
|
2669
|
+
if (!partnerSection || !heroFlex || !coverBg) return;
|
|
2670
|
+
|
|
2671
|
+
// Partner timeline (cover-bg + wideletters reverse)
|
|
2672
|
+
const partnerTimeline = gsap.timeline({ paused: true });
|
|
2673
|
+
|
|
2674
|
+
// Cover-bg fade-in
|
|
2675
|
+
partnerTimeline.fromTo(coverBg,
|
|
2676
|
+
{ opacity: 0 },
|
|
2677
|
+
{ opacity: 1, duration: 0.6, ease: 'power2.out' },
|
|
2678
|
+
0
|
|
2679
|
+
);
|
|
2680
|
+
|
|
2681
|
+
// Reverse wideletters
|
|
2682
|
+
partnerTimeline.to(wideletters, {
|
|
2683
|
+
y: '-150%',
|
|
2684
|
+
duration: 0.6,
|
|
2685
|
+
ease: 'power2.in',
|
|
2686
|
+
stagger: 0.03,
|
|
2687
|
+
}, 0);
|
|
2688
|
+
|
|
2689
|
+
// Trigger for partner timeline
|
|
2690
|
+
ScrollTrigger.create({
|
|
2691
|
+
trigger: partnerSection,
|
|
2692
|
+
start: 'top 80%',
|
|
2693
|
+
onEnter: () => partnerTimeline.play(),
|
|
2694
|
+
onLeaveBack: () => partnerTimeline.reverse(),
|
|
2695
|
+
});
|
|
2696
|
+
};
|
|
2697
|
+
|
|
2698
|
+
// Intro animation on page load
|
|
2699
|
+
window.introAnimation = function(e) {
|
|
2700
|
+
const introBrand = e.querySelector('[intro-brand]');
|
|
2701
|
+
const introSubtitle = e.querySelector('[intro-subtitle]');
|
|
2702
|
+
const widelettersIntro = e.querySelectorAll('.wideletter-intro');
|
|
2703
|
+
|
|
2704
|
+
// Set initial states
|
|
2705
|
+
gsap.set([introBrand, introSubtitle], { opacity: 0 });
|
|
2706
|
+
gsap.set(widelettersIntro, { y: '-150%' });
|
|
2707
|
+
|
|
2708
|
+
// Prevent browser scroll restoration and force scroll to top
|
|
2709
|
+
history.scrollRestoration = 'manual';
|
|
2710
|
+
window.scrollTo(0, 0);
|
|
2711
|
+
|
|
2712
|
+
// Lock scroll: position fixed keeps scrollbar visible but prevents scrolling
|
|
2713
|
+
document.body.style.position = 'fixed';
|
|
2714
|
+
document.body.style.top = '0px';
|
|
2715
|
+
document.body.style.width = '100%';
|
|
2716
|
+
|
|
2717
|
+
// Page load animation - scroll timeline is created AFTER this completes
|
|
2718
|
+
const introTimeline = gsap.timeline({
|
|
2719
|
+
onComplete: () => {
|
|
2720
|
+
// Unlock scroll
|
|
2721
|
+
document.body.style.position = '';
|
|
2722
|
+
document.body.style.top = '';
|
|
2723
|
+
document.body.style.width = '';
|
|
2724
|
+
window.scrollTo(0, 0);
|
|
2725
|
+
|
|
2726
|
+
// Force all letters to final state before creating ScrollTrigger
|
|
2727
|
+
gsap.set(widelettersIntro, { y: '0%', opacity: 1 });
|
|
2728
|
+
gsap.set(introBrand, { opacity: 1 });
|
|
2729
|
+
|
|
2730
|
+
// Small delay to ensure DOM is ready, then create scroll timeline and refresh ScrollTrigger
|
|
2731
|
+
requestAnimationFrame(() => {
|
|
2732
|
+
createScrollTimeline();
|
|
2733
|
+
ScrollTrigger.refresh();
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
});
|
|
2737
|
+
|
|
2738
|
+
introTimeline.to(introBrand, {
|
|
2739
|
+
opacity: 1,
|
|
2740
|
+
duration: 0.1,
|
|
2741
|
+
});
|
|
2742
|
+
|
|
2743
|
+
introTimeline.to(widelettersIntro, {
|
|
2744
|
+
y: '0%',
|
|
2745
|
+
duration: 1,
|
|
2746
|
+
ease: 'loader2',
|
|
2747
|
+
stagger: 0.1,
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
// EXPERIMENTAL: play/reverse version (no parallax)
|
|
2751
|
+
function createScrollTimeline() {
|
|
2752
|
+
// Timeline 1: Letters out
|
|
2753
|
+
const lettersOutTimeline = gsap.timeline({ paused: true });
|
|
2754
|
+
lettersOutTimeline.to(widelettersIntro, {
|
|
2755
|
+
y: '-150%',
|
|
2756
|
+
opacity: 0,
|
|
2757
|
+
duration: 0.6,
|
|
2758
|
+
ease: 'power2.in',
|
|
2759
|
+
stagger: 0.03,
|
|
2760
|
+
});
|
|
2761
|
+
|
|
2762
|
+
// Trigger 1: Letters out (at 20% of section)
|
|
2763
|
+
ScrollTrigger.create({
|
|
2764
|
+
trigger: e,
|
|
2765
|
+
start: 'top top-=20%',
|
|
2766
|
+
onEnter: () => lettersOutTimeline.play(),
|
|
2767
|
+
onLeaveBack: () => lettersOutTimeline.reverse(),
|
|
2768
|
+
});
|
|
2769
|
+
|
|
2770
|
+
// Timeline 2: Subtitle in
|
|
2771
|
+
const subtitleInTimeline = gsap.timeline({ paused: true });
|
|
2772
|
+
subtitleInTimeline.fromTo(introSubtitle,
|
|
2773
|
+
{ y: '50%', opacity: 0 },
|
|
2774
|
+
{ y: '0%', opacity: 1, duration: 0.6, ease: 'power2.out' }
|
|
2775
|
+
);
|
|
2776
|
+
|
|
2777
|
+
// Trigger 2: Subtitle in (at 90% of section)
|
|
2778
|
+
ScrollTrigger.create({
|
|
2779
|
+
trigger: e,
|
|
2780
|
+
start: 'top top-=90%',
|
|
2781
|
+
onEnter: () => subtitleInTimeline.play(),
|
|
2782
|
+
onLeaveBack: () => subtitleInTimeline.reverse(),
|
|
2783
|
+
});
|
|
2784
|
+
|
|
2785
|
+
// Timeline 3: Subtitle out
|
|
2786
|
+
const subtitleOutTimeline = gsap.timeline({ paused: true });
|
|
2787
|
+
subtitleOutTimeline.to(introSubtitle, {
|
|
2788
|
+
opacity: 0,
|
|
2789
|
+
duration: 0.5,
|
|
2790
|
+
ease: 'power2.out',
|
|
2791
|
+
});
|
|
2792
|
+
|
|
2793
|
+
// Trigger 3: Subtitle out (at 140% - well into section scroll)
|
|
2794
|
+
ScrollTrigger.create({
|
|
2795
|
+
trigger: e,
|
|
2796
|
+
start: 'top top-=140%',
|
|
2797
|
+
onEnter: () => subtitleOutTimeline.play(),
|
|
2798
|
+
onLeaveBack: () => subtitleOutTimeline.reverse(),
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
};
|
|
2802
|
+
|
|
2803
|
+
// Global GSAP title animation - animates [gsap-title] elements on scroll
|
|
2804
|
+
function gsapTitleAnimation() {
|
|
2805
|
+
const gsapTitles = document.querySelectorAll('[gsap-title]');
|
|
2806
|
+
|
|
2807
|
+
if (gsapTitles.length === 0) return;
|
|
2808
|
+
|
|
2809
|
+
gsapTitles.forEach((titleElement) => {
|
|
2810
|
+
// Split text into lines
|
|
2811
|
+
const splitTitle = new SplitText(titleElement, {
|
|
2812
|
+
type: 'lines',
|
|
2813
|
+
linesClass: 'gsap-title-line',
|
|
2814
|
+
});
|
|
2815
|
+
|
|
2816
|
+
// Create mask wrapper for each line
|
|
2817
|
+
const splitTitleMask = new SplitText(titleElement, {
|
|
2818
|
+
type: 'lines',
|
|
2819
|
+
linesClass: 'gsap-title-line-mask',
|
|
2820
|
+
});
|
|
2821
|
+
|
|
2822
|
+
const lines = titleElement.querySelectorAll('.gsap-title-line');
|
|
2823
|
+
|
|
2824
|
+
if (lines.length === 0) return;
|
|
2825
|
+
|
|
2826
|
+
// Set initial state - lines hidden below
|
|
2827
|
+
gsap.set(lines, { y: '100%' });
|
|
2828
|
+
|
|
2829
|
+
// Create paused timeline
|
|
2830
|
+
const titleTimeline = gsap.timeline({ paused: true });
|
|
2831
|
+
|
|
2832
|
+
titleTimeline.to(lines, {
|
|
2833
|
+
y: '0%',
|
|
2834
|
+
duration: 0.75,
|
|
2835
|
+
stagger: 0.2,
|
|
2836
|
+
ease: 'loader2',
|
|
2837
|
+
});
|
|
2838
|
+
|
|
2839
|
+
// Create ScrollTrigger with play/reverse
|
|
2840
|
+
ScrollTrigger.create({
|
|
2841
|
+
trigger: titleElement,
|
|
2842
|
+
start: 'top 80%',
|
|
2843
|
+
onEnter: () => titleTimeline.play(),
|
|
2844
|
+
onLeaveBack: () => titleTimeline.reverse(),
|
|
2845
|
+
});
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
// Global GSAP container animation - animates direct children of [gsap-container]
|
|
2850
|
+
function gsapContainerAnimation() {
|
|
2851
|
+
const gsapContainers = document.querySelectorAll('[gsap-container]');
|
|
2852
|
+
|
|
2853
|
+
if (gsapContainers.length === 0) return;
|
|
2854
|
+
|
|
2855
|
+
gsapContainers.forEach((container) => {
|
|
2856
|
+
const children = container.children;
|
|
2857
|
+
|
|
2858
|
+
if (children.length === 0) return;
|
|
2859
|
+
|
|
2860
|
+
// Set initial state
|
|
2861
|
+
gsap.set(children, { y: '4rem', opacity: 0 });
|
|
2862
|
+
|
|
2863
|
+
// Create paused timeline
|
|
2864
|
+
const containerTimeline = gsap.timeline({ paused: true });
|
|
2865
|
+
|
|
2866
|
+
containerTimeline.to(children, {
|
|
2867
|
+
y: '0rem',
|
|
2868
|
+
opacity: 1,
|
|
2869
|
+
duration: 1,
|
|
2870
|
+
stagger: 0.1,
|
|
2871
|
+
ease: 'power3.out',
|
|
2872
|
+
});
|
|
2873
|
+
|
|
2874
|
+
// Create ScrollTrigger with play/reverse
|
|
2875
|
+
ScrollTrigger.create({
|
|
2876
|
+
trigger: container,
|
|
2877
|
+
start: 'top 80%',
|
|
2878
|
+
onEnter: () => containerTimeline.play(),
|
|
2879
|
+
onLeaveBack: () => containerTimeline.reverse(),
|
|
2880
|
+
});
|
|
2881
|
+
});
|
|
2882
|
+
}
|
|
2883
|
+
|
|
2884
|
+
// Global GSAP fade animation - fades in [gsap-fade] elements on scroll
|
|
2885
|
+
function gsapFadeAnimation() {
|
|
2886
|
+
const gsapFadeElements = document.querySelectorAll('[gsap-fade]');
|
|
2887
|
+
|
|
2888
|
+
if (gsapFadeElements.length === 0) return;
|
|
2889
|
+
|
|
2890
|
+
gsapFadeElements.forEach((element) => {
|
|
2891
|
+
// Set initial state
|
|
2892
|
+
gsap.set(element, { opacity: 0 });
|
|
2893
|
+
|
|
2894
|
+
// Create paused timeline
|
|
2895
|
+
const fadeTimeline = gsap.timeline({ paused: true });
|
|
2896
|
+
|
|
2897
|
+
fadeTimeline.to(element, {
|
|
2898
|
+
opacity: 1,
|
|
2899
|
+
duration: 2,
|
|
2900
|
+
ease: 'power3.out',
|
|
2901
|
+
});
|
|
2902
|
+
|
|
2903
|
+
// Create ScrollTrigger with play/reverse
|
|
2904
|
+
ScrollTrigger.create({
|
|
2905
|
+
trigger: element,
|
|
2906
|
+
start: 'top 65%',
|
|
2907
|
+
onEnter: () => fadeTimeline.play(),
|
|
2908
|
+
onLeaveBack: () => fadeTimeline.reverse(),
|
|
2909
|
+
});
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2545
2913
|
// !!!!!!!!! Keep this Alpine init at the end !!!!!!!!!
|
|
2546
2914
|
window.Webflow ||= [];
|
|
2547
2915
|
window.Webflow.push(() => {
|
|
@@ -2565,6 +2933,9 @@ window.Webflow.push(() => {
|
|
|
2565
2933
|
contactFormOpenAnimation();
|
|
2566
2934
|
openContactFormFromURL();
|
|
2567
2935
|
disableScrollMenu();
|
|
2936
|
+
gsapTitleAnimation();
|
|
2937
|
+
gsapContainerAnimation();
|
|
2938
|
+
gsapFadeAnimation();
|
|
2568
2939
|
refreshScrollTriggersAfterLoad();
|
|
2569
2940
|
|
|
2570
2941
|
});
|