fix blurhash crossfade: keep mounted, fade out on image load, img absolute positioned
This commit is contained in:
@@ -84,8 +84,8 @@ function PhotoGridThumb({ event, onClick }: { event: NostrEvent; onClick: () =>
|
||||
onClick={onClick}
|
||||
aria-label="View photo"
|
||||
>
|
||||
{/* Blurhash placeholder */}
|
||||
{first.blurhash && !loaded && (
|
||||
{/* Blurhash — always mounted, fades out once image loads */}
|
||||
{first.blurhash && (
|
||||
<Blurhash
|
||||
hash={first.blurhash}
|
||||
width="100%"
|
||||
@@ -93,7 +93,7 @@ function PhotoGridThumb({ event, onClick }: { event: NostrEvent; onClick: () =>
|
||||
resolutionX={32}
|
||||
resolutionY={32}
|
||||
punch={1}
|
||||
className="absolute inset-0"
|
||||
className={cn('absolute inset-0 transition-opacity duration-300', loaded ? 'opacity-0' : 'opacity-100')}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
/>
|
||||
)}
|
||||
@@ -104,7 +104,7 @@ function PhotoGridThumb({ event, onClick }: { event: NostrEvent; onClick: () =>
|
||||
width={w}
|
||||
height={h}
|
||||
className={cn(
|
||||
'w-full h-full object-cover transition-transform duration-300 group-hover:scale-[1.04]',
|
||||
'absolute inset-0 w-full h-full object-cover transition-all duration-300 group-hover:scale-[1.04]',
|
||||
loaded ? 'opacity-100' : 'opacity-0',
|
||||
)}
|
||||
loading="lazy"
|
||||
|
||||
@@ -163,20 +163,21 @@ function VideoGridCard({ event }: { event: NostrEvent }) {
|
||||
onKeyDown={(e) => e.key === 'Enter' && onClick()}
|
||||
>
|
||||
<div className="relative aspect-video overflow-hidden rounded-xl bg-muted">
|
||||
{blurhash && !imgLoaded && (
|
||||
{blurhash && (
|
||||
<Blurhash hash={blurhash} width="100%" height="100%" resolutionX={32} resolutionY={32} punch={1}
|
||||
className="absolute inset-0" style={{ width: '100%', height: '100%' }} />
|
||||
className={cn('absolute inset-0 transition-opacity duration-300', imgLoaded ? 'opacity-0' : 'opacity-100')}
|
||||
style={{ width: '100%', height: '100%' }} />
|
||||
)}
|
||||
{thumbnail ? (
|
||||
<img
|
||||
src={thumbnail}
|
||||
alt={title}
|
||||
className={cn('w-full h-full object-cover transition-transform duration-300 group-hover:scale-[1.03]', imgLoaded ? 'opacity-100' : 'opacity-0')}
|
||||
className={cn('absolute inset-0 w-full h-full object-cover transition-all duration-300 group-hover:scale-[1.03]', imgLoaded ? 'opacity-100' : 'opacity-0')}
|
||||
loading="lazy"
|
||||
onLoad={() => setImgLoaded(true)}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<Play className="size-10 text-muted-foreground/30" />
|
||||
</div>
|
||||
)}
|
||||
@@ -322,20 +323,21 @@ function ShortThumb({ event, onClick }: { event: NostrEvent; onClick: () => void
|
||||
return (
|
||||
<button className="group block w-full text-left focus:outline-none" onClick={onClick} aria-label={title}>
|
||||
<div className="relative w-full aspect-[9/16] overflow-hidden rounded-xl bg-muted">
|
||||
{blurhash && !imgLoaded && (
|
||||
{blurhash && (
|
||||
<Blurhash hash={blurhash} width="100%" height="100%" resolutionX={32} resolutionY={32} punch={1}
|
||||
className="absolute inset-0" style={{ width: '100%', height: '100%' }} />
|
||||
className={cn('absolute inset-0 transition-opacity duration-300', imgLoaded ? 'opacity-0' : 'opacity-100')}
|
||||
style={{ width: '100%', height: '100%' }} />
|
||||
)}
|
||||
{thumbnail ? (
|
||||
<img
|
||||
src={thumbnail}
|
||||
alt={title}
|
||||
className={cn('w-full h-full object-cover transition-transform duration-300 group-hover:scale-[1.03]', imgLoaded ? 'opacity-100' : 'opacity-0')}
|
||||
className={cn('absolute inset-0 w-full h-full object-cover transition-all duration-300 group-hover:scale-[1.03]', imgLoaded ? 'opacity-100' : 'opacity-0')}
|
||||
loading="lazy"
|
||||
onLoad={() => setImgLoaded(true)}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<Play className="size-8 text-muted-foreground/30" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user