From 7aec34f00569a14b5fad1fc95b75676dde7c2a99 Mon Sep 17 00:00:00 2001 From: Mirko Pecora Date: Mon, 18 May 2026 16:30:27 +0200 Subject: [PATCH 1/2] fix(dom): improve background layer styling and optimize object fit handling --- src/dom-renderer/domRenderer.ts | 53 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/dom-renderer/domRenderer.ts b/src/dom-renderer/domRenderer.ts index bd77bd5..34a4229 100644 --- a/src/dom-renderer/domRenderer.ts +++ b/src/dom-renderer/domRenderer.ts @@ -680,7 +680,14 @@ function updateNodeStyles(node: DOMNode | DOMText) { } let bgLayerStyle = - 'position: absolute; top:0; left:0; right:0; bottom:0; z-index: -1; pointer-events: none; -webkit-clip-path: inset(0); clip-path: inset(0);'; + 'position: absolute; top:0; left:0; right:0; bottom:0; z-index: -1; pointer-events: none;'; + // overflow:hidden clips the transformed imgEl to prevent sprite bleed-through + // for non-tinted subtextures. NOT applied when hasDivBgTint because + // overflow:hidden + CSS mask-image causes a 1px white border artifact on WebKit. + // Tinted nodes use mask-image for visual clipping, so overflow:hidden is unnecessary. + if (srcPos !== null && !hasDivBgTint) { + bgLayerStyle += 'overflow: hidden;'; + } if (bgStyle) { bgLayerStyle += bgStyle; } @@ -720,16 +727,18 @@ function updateNodeStyles(node: DOMNode | DOMText) { const resizeMode = (node.props.textureOptions as any)?.resizeMode; const clipX = resizeMode?.clipX ?? 0.5; const clipY = resizeMode?.clipY ?? 0.5; - computeLegacyObjectFit( - node, - node.imgEl!, - resizeMode, - clipX, - clipY, - node.lazyImageSubTextureProps, - supportsObjectFit, - supportsObjectPosition, - ); + if (!node.lazyImageSubTextureProps) { + computeLegacyObjectFit( + node, + node.imgEl!, + resizeMode, + clipX, + clipY, + null, + supportsObjectFit, + supportsObjectPosition, + ); + } // Reveal only after final fit/positioning is applied if (node.imgEl) { @@ -864,16 +873,18 @@ function updateNodeStyles(node: DOMNode | DOMText) { const resizeMode = (node.props.textureOptions as any)?.resizeMode; const clipX = resizeMode?.clipX ?? 0.5; const clipY = resizeMode?.clipY ?? 0.5; - computeLegacyObjectFit( - node, - node.imgEl!, - resizeMode, - clipX, - clipY, - node.lazyImageSubTextureProps, - supportsObjectFit, - supportsObjectPosition, - ); + if (!node.lazyImageSubTextureProps) { + computeLegacyObjectFit( + node, + node.imgEl!, + resizeMode, + clipX, + clipY, + null, + supportsObjectFit, + supportsObjectPosition, + ); + } if (node.imgEl) { node.imageLoading = false; From 0b3e0e9f04ce1a5e518f3ce312e7a5412d7d7b0b Mon Sep 17 00:00:00 2001 From: Mirko Pecora Date: Mon, 18 May 2026 16:51:11 +0200 Subject: [PATCH 2/2] fix(dom): refactor legacy object fit handling into a separate function --- src/dom-renderer/domRenderer.ts | 76 +++++++++++---------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/src/dom-renderer/domRenderer.ts b/src/dom-renderer/domRenderer.ts index 34a4229..11f8596 100644 --- a/src/dom-renderer/domRenderer.ts +++ b/src/dom-renderer/domRenderer.ts @@ -300,6 +300,26 @@ function updateRenderStateIfNeeded(node: DOMNode | DOMText): void { } } +function applyLegacyObjectFit( + node: DOMNode, + img: HTMLImageElement, + srcPos: InstanceType['props'] | null, +): void { + const resizeMode = (node.props.textureOptions as any)?.resizeMode; + const clipX = resizeMode?.clipX ?? 0.5; + const clipY = resizeMode?.clipY ?? 0.5; + computeLegacyObjectFit( + node, + img, + resizeMode, + clipX, + clipY, + srcPos, + supportsObjectFit, + supportsObjectPosition, + ); +} + function updateNodeStyles(node: DOMNode | DOMText) { let { props } = node; @@ -724,20 +744,8 @@ function updateNodeStyles(node: DOMNode | DOMText) { node.lazyImageSubTextureProps, ); - const resizeMode = (node.props.textureOptions as any)?.resizeMode; - const clipX = resizeMode?.clipX ?? 0.5; - const clipY = resizeMode?.clipY ?? 0.5; if (!node.lazyImageSubTextureProps) { - computeLegacyObjectFit( - node, - node.imgEl!, - resizeMode, - clipX, - clipY, - null, - supportsObjectFit, - supportsObjectPosition, - ); + applyLegacyObjectFit(node, node.imgEl!, null); } // Reveal only after final fit/positioning is applied @@ -807,19 +815,7 @@ function updateNodeStyles(node: DOMNode | DOMText) { (!supportsObjectFit || !supportsObjectPosition) && node.imgEl.dataset.rawSrc === rawImgSrc ) { - const resizeMode = (node.props.textureOptions as any)?.resizeMode; - const clipX = resizeMode?.clipX ?? 0.5; - const clipY = resizeMode?.clipY ?? 0.5; - computeLegacyObjectFit( - node, - node.imgEl, - resizeMode, - clipX, - clipY, - srcPos, - supportsObjectFit, - supportsObjectPosition, - ); + applyLegacyObjectFit(node, node.imgEl, srcPos); } } else { node.lazyImagePendingSrc = null; @@ -870,20 +866,8 @@ function updateNodeStyles(node: DOMNode | DOMText) { node.lazyImageSubTextureProps, ); - const resizeMode = (node.props.textureOptions as any)?.resizeMode; - const clipX = resizeMode?.clipX ?? 0.5; - const clipY = resizeMode?.clipY ?? 0.5; if (!node.lazyImageSubTextureProps) { - computeLegacyObjectFit( - node, - node.imgEl!, - resizeMode, - clipX, - clipY, - null, - supportsObjectFit, - supportsObjectPosition, - ); + applyLegacyObjectFit(node, node.imgEl!, null); } if (node.imgEl) { @@ -945,19 +929,7 @@ function updateNodeStyles(node: DOMNode | DOMText) { (!supportsObjectFit || !supportsObjectPosition) && node.imgEl.dataset.rawSrc === rawImgSrc ) { - const resizeMode = (node.props.textureOptions as any)?.resizeMode; - const clipX = resizeMode?.clipX ?? 0.5; - const clipY = resizeMode?.clipY ?? 0.5; - computeLegacyObjectFit( - node, - node.imgEl, - resizeMode, - clipX, - clipY, - srcPos, - supportsObjectFit, - supportsObjectPosition, - ); + applyLegacyObjectFit(node, node.imgEl, srcPos); } } else { node.lazyImagePendingSrc = null;