fix(ecommerce): imagen principal del producto se ve borrosa en Chrome/Edge Android
Reportado en vivo por el usuario: la foto principal (y el modal de zoom interactivo) se ven borrosas en mobile, especificamente en Chrome y Edge de Android. Investigado a fondo antes de tocar nada: no es un archivo corrupto ni un problema de nuestro cache/backend -- confirmado con fetch()+createImageBitmap() (que evita <img>/srcset por completo) que el archivo real decodifica perfecto a resolución completa (1200x1200). El bug está en cómo Chromium elige el candidato del srcset con sizes="100vw" + fill a DPR alto (2.6+, cualquier Android real): currentSrc reporta la URL de un candidato grande, pero naturalWidth/Height terminan reflejando un candidato mucho más chico -- reproducido igual en Chromium headless, y consistente con lo reportado en Chrome y Edge Android reales (mismo motor). No hay forma de arreglar el algoritmo de selección de Chromium desde acá. La foto principal y el modal de zoom pasan a unoptimized: al quedar un solo recurso real por foto (sin candidatos de por medio), no hay entre qué elegir mal. Costo: la foto pesa el archivo completo en vez de una versión redimensionada -- aceptable para dos imágenes puntuales donde la nitidez importa. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_012Y4df3Z7odr9Cg8F2nw6uV
This commit is contained in:
1 parent
8d8546fd94
commit
ccaddf546c
1 file changed
+14
-2
@@ -122,12 +122,24 @@ export function ProductGallery({ images, name }: { images: string[]; name: strin
|
||||
onMouseMove={trackHoverZoom}
|
||||
onMouseLeave={() => setHoverZoom(null)}
|
||||
>
|
||||
{/* unoptimized a proposito: confirmado en vivo (createImageBitmap
|
||||
sobre los bytes reales vs. el <img> renderizado) que a DPR
|
||||
alto (2.6+, cualquier Android real) Chromium reporta
|
||||
naturalWidth/Height de un candidato del srcset mucho más
|
||||
chico del que dice currentSrc -- bug del propio motor de
|
||||
Chromium en la selección de candidato con sizes="100vw" en
|
||||
fill, no algo corrupto en el archivo ni en nuestro caché
|
||||
(el archivo decodifica perfecto vía fetch+createImageBitmap
|
||||
fuera de <img>). Reproducido igual en Chrome y Edge Android
|
||||
(ambos Chromium) y en Chromium headless. unoptimized deja
|
||||
un solo recurso real por foto -- sin candidatos entre los
|
||||
que el bug pueda elegir mal. */}
|
||||
<Image
|
||||
src={selected}
|
||||
alt={name}
|
||||
fill
|
||||
priority
|
||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||
unoptimized
|
||||
className="object-cover"
|
||||
/>
|
||||
{/* Lupa: recuadro que marca la region ampliada -- solo cuando
|
||||
@@ -162,7 +174,7 @@ export function ProductGallery({ images, name }: { images: string[]; name: strin
|
||||
<div className="grid min-h-[70vh] grid-rows-[1fr_auto]">
|
||||
<div className="relative overflow-hidden bg-slate-950" onWheel={wheel} onPointerDown={pointerDown} onPointerMove={pointerMove} onPointerUp={pointerEnd} onPointerCancel={pointerEnd} onDoubleClick={() => applyScale(scale > 1 ? 1 : 2)} style={{ touchAction: "none", cursor: scale > 1 ? "grab" : "zoom-in" }}>
|
||||
<div className="absolute inset-6 transition-transform duration-100 will-change-transform" style={{ transform: `translate3d(${offset.x}px, ${offset.y}px, 0) scale(${scale})` }}>
|
||||
<Image src={selected} alt={name} fill sizes="95vw" className="select-none object-contain" draggable={false} />
|
||||
<Image src={selected} alt={name} fill unoptimized className="select-none object-contain" draggable={false} />
|
||||
</div>
|
||||
<div className="pointer-events-none absolute left-5 top-5 rounded-full bg-black/65 px-3 py-1.5 text-xs font-black text-white backdrop-blur">Rueda o botones para acercar · Arrastra para mover</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user