@vectoriox/iox-builder 1.4.76 → 1.4.78
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.
|
@@ -1266,11 +1266,9 @@ class InteractionEngineService {
|
|
|
1266
1266
|
const cleanups = [];
|
|
1267
1267
|
for (const ix of node.interactions) {
|
|
1268
1268
|
// Pre-state: hide target elements before their entrance animation fires.
|
|
1269
|
-
// In builder mode: skip
|
|
1270
|
-
//
|
|
1271
|
-
|
|
1272
|
-
// (viewportEnter). Click/hover triggers are always active.
|
|
1273
|
-
const skipPreState = inBuilder && ix.trigger !== 'click' && ix.trigger !== 'hover';
|
|
1269
|
+
// In builder mode: skip only suppressed triggers (pageLoad, scrollProgress).
|
|
1270
|
+
// viewportEnter IS active in builder — elements must be hidden before trigger.
|
|
1271
|
+
const skipPreState = inBuilder && (ix.trigger === 'pageLoad' || ix.trigger === 'scrollProgress');
|
|
1274
1272
|
if (!skipPreState) {
|
|
1275
1273
|
for (const action of ix.actions) {
|
|
1276
1274
|
if (this.ENTRANCE_TYPES.has(action.type)) {
|
|
@@ -1446,16 +1444,48 @@ class InteractionEngineService {
|
|
|
1446
1444
|
firedSet.add(key);
|
|
1447
1445
|
this.runActions(node, ix.actions);
|
|
1448
1446
|
};
|
|
1447
|
+
// IntersectionObserver with no root uses the browser viewport.
|
|
1448
|
+
// It respects overflow:hidden clipping from .preview-scroll so it fires
|
|
1449
|
+
// correctly as Lenis scrolls (Lenis changes scrollTop on .preview-scroll).
|
|
1449
1450
|
const observer = new IntersectionObserver((entries) => {
|
|
1450
1451
|
for (const entry of entries) {
|
|
1451
1452
|
if (entry.isIntersecting) {
|
|
1452
|
-
|
|
1453
|
+
cleanup();
|
|
1453
1454
|
fire();
|
|
1454
1455
|
}
|
|
1455
1456
|
}
|
|
1456
1457
|
}, { threshold: 0.1 });
|
|
1457
1458
|
observer.observe(element);
|
|
1458
|
-
|
|
1459
|
+
// Builder: also listen to Lenis scroll events on .preview-lenis-content
|
|
1460
|
+
// as a fallback in case IntersectionObserver misses elements behind a
|
|
1461
|
+
// CSS transform (scale) on iox-page-component.
|
|
1462
|
+
const lenisEl = this.overlayService.getScrollContainer();
|
|
1463
|
+
let scrollFired = false;
|
|
1464
|
+
const onScroll = () => {
|
|
1465
|
+
if (scrollFired)
|
|
1466
|
+
return;
|
|
1467
|
+
const rootEl = this.overlayService.getIntersectionRoot();
|
|
1468
|
+
if (!rootEl)
|
|
1469
|
+
return;
|
|
1470
|
+
const rootRect = rootEl.getBoundingClientRect();
|
|
1471
|
+
const elRect = element.getBoundingClientRect();
|
|
1472
|
+
const overlapH = Math.min(elRect.bottom, rootRect.bottom) - Math.max(elRect.top, rootRect.top);
|
|
1473
|
+
const elH = elRect.bottom - elRect.top;
|
|
1474
|
+
if (elH > 0 && overlapH / elH >= 0.1) {
|
|
1475
|
+
scrollFired = true;
|
|
1476
|
+
cleanup();
|
|
1477
|
+
fire();
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
if (lenisEl)
|
|
1481
|
+
lenisEl.addEventListener('scroll', onScroll, { passive: true });
|
|
1482
|
+
const cleanup = () => {
|
|
1483
|
+
observer.disconnect();
|
|
1484
|
+
scrollFired = true;
|
|
1485
|
+
if (lenisEl)
|
|
1486
|
+
lenisEl.removeEventListener('scroll', onScroll);
|
|
1487
|
+
};
|
|
1488
|
+
return cleanup;
|
|
1459
1489
|
}
|
|
1460
1490
|
isBuilderMode() {
|
|
1461
1491
|
return document.body.classList.contains('builder-active');
|
|
@@ -1601,22 +1631,26 @@ class InteractionEngineService {
|
|
|
1601
1631
|
* trigger fires. Called for ALL entrance-type actions regardless of trigger so
|
|
1602
1632
|
* that a click-triggered fadeIn on a menu overlay also starts it hidden.
|
|
1603
1633
|
*
|
|
1604
|
-
*
|
|
1605
|
-
*
|
|
1606
|
-
*
|
|
1634
|
+
* In builder mode only opacity:0 is applied — transforms on canvas elements
|
|
1635
|
+
* inside iox-page-component's scale() transform break Lenis scroll. The transform
|
|
1636
|
+
* jump at animation t=0 is invisible because the element is already opacity:0.
|
|
1637
|
+
* In production the full keyframe is applied + pointer-events:none.
|
|
1607
1638
|
*/
|
|
1608
1639
|
applyPreState(element, action) {
|
|
1609
1640
|
const { keyframes } = this.buildAnimation(action);
|
|
1610
1641
|
if (!keyframes.length)
|
|
1611
1642
|
return;
|
|
1612
1643
|
const first = keyframes[0];
|
|
1613
|
-
|
|
1614
|
-
element.style
|
|
1644
|
+
if (this.isBuilderMode()) {
|
|
1645
|
+
element.style.setProperty('opacity', '0');
|
|
1646
|
+
}
|
|
1647
|
+
else {
|
|
1648
|
+
for (const [prop, val] of Object.entries(first)) {
|
|
1649
|
+
element.style[prop] = String(val);
|
|
1650
|
+
}
|
|
1651
|
+
element.style.setProperty('pointer-events', 'none');
|
|
1615
1652
|
}
|
|
1616
|
-
// Mark as hidden so the builder overlay and drag engine can ignore this element
|
|
1617
|
-
// and all of its children regardless of which entrance animation type is used.
|
|
1618
1653
|
element.setAttribute('data-iox-hidden', '');
|
|
1619
|
-
element.style.setProperty('pointer-events', 'none');
|
|
1620
1654
|
this.preStatedElements.add(element);
|
|
1621
1655
|
}
|
|
1622
1656
|
clearInlineAnimationStyles(element) {
|