@widelab-nc/widelab 1.1.32 → 1.1.34
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 +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +2 -1
- package/src/index.js +193 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@widelab-nc/widelab",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.34",
|
|
4
4
|
"description": "Widelab starter template based on Finsweet template + add-ons.",
|
|
5
5
|
"homepage": "https://widelab.co",
|
|
6
6
|
"license": "ISC",
|
|
@@ -57,3 +57,4 @@
|
|
|
57
57
|
"gsap": "npm:@gsap/shockingly@^3.12.5"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
|
package/src/index.js
CHANGED
|
@@ -1324,6 +1324,73 @@ window.heroSliders = function(e) {
|
|
|
1324
1324
|
}
|
|
1325
1325
|
|
|
1326
1326
|
|
|
1327
|
+
// Splide without GSAP; pagination inserted as first child INSIDE .splide
|
|
1328
|
+
window.awwwardsSliders = function (el) {
|
|
1329
|
+
if (el.dataset.splideInitialized === '1') return;
|
|
1330
|
+
|
|
1331
|
+
// 1) Find or create Splide root
|
|
1332
|
+
let root = el.classList?.contains('splide') ? el : el.closest?.('.splide');
|
|
1333
|
+
const track = el.querySelector?.('.splide__track') || el.closest?.('.splide__track');
|
|
1334
|
+
|
|
1335
|
+
if (!root && track) {
|
|
1336
|
+
root = document.createElement('div');
|
|
1337
|
+
root.className = 'splide testimonial';
|
|
1338
|
+
track.parentNode.insertBefore(root, track);
|
|
1339
|
+
root.appendChild(track);
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// 2) Validate structure
|
|
1343
|
+
if (!root || !root.querySelector('.splide__track') || !root.querySelector('.splide__list')) {
|
|
1344
|
+
console.warn('[awwwardsSliders] Missing required Splide structure.');
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// 3) Splide config
|
|
1349
|
+
const config = {
|
|
1350
|
+
type: 'loop',
|
|
1351
|
+
perPage: 1,
|
|
1352
|
+
perMove: 1,
|
|
1353
|
+
gap: '0px',
|
|
1354
|
+
arrows: false,
|
|
1355
|
+
pagination: true,
|
|
1356
|
+
drag: false,
|
|
1357
|
+
speed: 300,
|
|
1358
|
+
easing: 'cubic-bezier(0.83, 0, 0.17, 1)',
|
|
1359
|
+
classes: {
|
|
1360
|
+
pagination: 'splide__pagination awwwards-pagination',
|
|
1361
|
+
page: 'splide__pagination__page awwwards-page',
|
|
1362
|
+
},
|
|
1363
|
+
breakpoints: {
|
|
1364
|
+
992: { drag: true },
|
|
1365
|
+
},
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
const splide = new Splide(root, config).mount();
|
|
1369
|
+
|
|
1370
|
+
// 4) Move pagination INSIDE .splide as FIRST child
|
|
1371
|
+
splide.on('pagination:mounted', (data) => {
|
|
1372
|
+
const list = data.list;
|
|
1373
|
+
if (list && root.firstChild) {
|
|
1374
|
+
root.insertBefore(list, root.firstChild);
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
// Fallback if pagination already exists
|
|
1379
|
+
queueMicrotask(() => {
|
|
1380
|
+
const list = root.querySelector('.splide__pagination');
|
|
1381
|
+
const track = root.querySelector('.splide__track');
|
|
1382
|
+
if (list && track && list.nextSibling !== track) {
|
|
1383
|
+
root.insertBefore(list, track);
|
|
1384
|
+
}
|
|
1385
|
+
});
|
|
1386
|
+
|
|
1387
|
+
// 5) Click-to-next on desktop
|
|
1388
|
+
if (window.innerWidth > 992) {
|
|
1389
|
+
root.addEventListener('click', () => splide.go('+1'));
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
el.dataset.splideInitialized = '1';
|
|
1393
|
+
};
|
|
1327
1394
|
|
|
1328
1395
|
// Sliders on Services page
|
|
1329
1396
|
window.servicesSliders = function(e) {
|
|
@@ -1364,6 +1431,132 @@ window.servicesSliders = function(e) {
|
|
|
1364
1431
|
});
|
|
1365
1432
|
}
|
|
1366
1433
|
|
|
1434
|
+
// Play-once timeline: children fade-in from bottom with stagger
|
|
1435
|
+
window.initBentoRevealTimeline = function (container) {
|
|
1436
|
+
// Respect reduced motion
|
|
1437
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
1438
|
+
container.querySelectorAll(':scope > *').forEach(el => {
|
|
1439
|
+
el.style.opacity = 1;
|
|
1440
|
+
el.style.transform = 'none';
|
|
1441
|
+
});
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
const items = Array.from(container.children); // direct children only
|
|
1446
|
+
|
|
1447
|
+
// Set initial state
|
|
1448
|
+
gsap.set(items, { opacity: 0, y: 24 });
|
|
1449
|
+
|
|
1450
|
+
// Build timeline that plays when scrolled into view
|
|
1451
|
+
const tl = gsap.timeline({
|
|
1452
|
+
scrollTrigger: {
|
|
1453
|
+
trigger: container,
|
|
1454
|
+
start: 'top 80%', // when top of container hits 80% of viewport
|
|
1455
|
+
end: 'bottom 40%', // not critical for play-only, but nice bounds
|
|
1456
|
+
toggleActions: 'play none none none',
|
|
1457
|
+
once: true
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
tl.to(items, {
|
|
1462
|
+
opacity: 1,
|
|
1463
|
+
y: 0,
|
|
1464
|
+
duration: 0.6,
|
|
1465
|
+
ease: 'power2.out',
|
|
1466
|
+
stagger: 0.12
|
|
1467
|
+
});
|
|
1468
|
+
};
|
|
1469
|
+
|
|
1470
|
+
// Scrubbed timeline: progress tied to scroll progress
|
|
1471
|
+
window.initBentoRevealScrub = function (container) {
|
|
1472
|
+
// Respect reduced motion
|
|
1473
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
1474
|
+
container.querySelectorAll(':scope > *').forEach(el => {
|
|
1475
|
+
el.style.opacity = 1;
|
|
1476
|
+
el.style.transform = 'none';
|
|
1477
|
+
});
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
const items = Array.from(container.children); // direct children only
|
|
1482
|
+
|
|
1483
|
+
// Important: define from state in timeline for scrub to interpolate smoothly
|
|
1484
|
+
const tl = gsap.timeline({
|
|
1485
|
+
scrollTrigger: {
|
|
1486
|
+
trigger: container,
|
|
1487
|
+
start: 'top 90%', // start easing in slightly later
|
|
1488
|
+
end: 'bottom 65%', // full reveal by near the end of container
|
|
1489
|
+
scrub: 0.5, // smoothing; use true for no smoothing
|
|
1490
|
+
markers: false, // uncomment for debugging
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
tl.fromTo(items,
|
|
1495
|
+
{ opacity: 0, y: 28 },
|
|
1496
|
+
{
|
|
1497
|
+
opacity: 1,
|
|
1498
|
+
y: 0,
|
|
1499
|
+
ease: 'power2.out',
|
|
1500
|
+
// Duration is ignored by scrub; timeline length maps to scroll distance.
|
|
1501
|
+
// Stagger distributes the items across the timeline for a nice cascade.
|
|
1502
|
+
stagger: { each: 0.12 }
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
};
|
|
1506
|
+
|
|
1507
|
+
window.initPartnerVideos = function (container) {
|
|
1508
|
+
const items = Array.from(container.querySelectorAll('.partner_item'));
|
|
1509
|
+
const vids = items.map(i => i.querySelector('video')).filter(Boolean);
|
|
1510
|
+
|
|
1511
|
+
const pauseAll = (except) => {
|
|
1512
|
+
vids.forEach(v => {
|
|
1513
|
+
if (v !== except) {
|
|
1514
|
+
v.pause();
|
|
1515
|
+
v.muted = true;
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
};
|
|
1519
|
+
|
|
1520
|
+
items.forEach((item) => {
|
|
1521
|
+
const v = item.querySelector('video');
|
|
1522
|
+
if (!v) return;
|
|
1523
|
+
|
|
1524
|
+
v.controls = false;
|
|
1525
|
+
v.loop = false;
|
|
1526
|
+
v.muted = true;
|
|
1527
|
+
v.setAttribute('playsinline', '');
|
|
1528
|
+
v.playsInline = true;
|
|
1529
|
+
|
|
1530
|
+
item.addEventListener('click', () => {
|
|
1531
|
+
if (v.paused) {
|
|
1532
|
+
pauseAll(v);
|
|
1533
|
+
v.muted = false;
|
|
1534
|
+
v.play();
|
|
1535
|
+
} else {
|
|
1536
|
+
v.pause();
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
const rootEl =
|
|
1542
|
+
document.querySelector('[data-scroll-root]') ||
|
|
1543
|
+
document.querySelector('[data-smooth-scroll-root]') ||
|
|
1544
|
+
null;
|
|
1545
|
+
|
|
1546
|
+
const io = new IntersectionObserver(
|
|
1547
|
+
(entries) => {
|
|
1548
|
+
entries.forEach(({ isIntersecting, target }) => {
|
|
1549
|
+
const v = target.querySelector('video');
|
|
1550
|
+
if (!v) return;
|
|
1551
|
+
if (!isIntersecting) v.pause();
|
|
1552
|
+
});
|
|
1553
|
+
},
|
|
1554
|
+
{ root: rootEl, threshold: 0.25 }
|
|
1555
|
+
);
|
|
1556
|
+
|
|
1557
|
+
items.forEach((item) => io.observe(item));
|
|
1558
|
+
};
|
|
1559
|
+
|
|
1367
1560
|
|
|
1368
1561
|
|
|
1369
1562
|
// Case study - What's next interaction
|