74 lines
2.7 KiB
JavaScript
74 lines
2.7 KiB
JavaScript
import React, { useState } from 'react'
|
|
|
|
const FALLBACK_MD = 'https://files.skinbase.org/default/missing_md.webp'
|
|
const FALLBACK_LG = 'https://files.skinbase.org/default/missing_lg.webp'
|
|
const FALLBACK_XL = 'https://files.skinbase.org/default/missing_xl.webp'
|
|
|
|
export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl }) {
|
|
const [isLoaded, setIsLoaded] = useState(false)
|
|
|
|
const mdSource = presentMd?.url || artwork?.thumbs?.md?.url || null
|
|
const lgSource = presentLg?.url || artwork?.thumbs?.lg?.url || null
|
|
const xlSource = presentXl?.url || artwork?.thumbs?.xl?.url || null
|
|
|
|
const md = mdSource || FALLBACK_MD
|
|
const lg = lgSource || FALLBACK_LG
|
|
const xl = xlSource || FALLBACK_XL
|
|
|
|
const hasRealArtworkImage = Boolean(mdSource || lgSource || xlSource)
|
|
const blurBackdropSrc = mdSource || lgSource || xlSource || null
|
|
|
|
const srcSet = `${md} 640w, ${lg} 1280w, ${xl} 1920w`
|
|
|
|
return (
|
|
<figure className="w-full">
|
|
<div className="relative mx-auto w-full max-w-[1280px]">
|
|
{blurBackdropSrc && (
|
|
<div className="pointer-events-none absolute inset-0 -z-10 scale-105 overflow-hidden rounded-2xl">
|
|
<img
|
|
src={blurBackdropSrc}
|
|
alt=""
|
|
aria-hidden="true"
|
|
className="h-full w-full object-cover opacity-35 blur-2xl"
|
|
loading="lazy"
|
|
decoding="async"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{hasRealArtworkImage && (
|
|
<div className="absolute inset-0 -z-10 rounded-2xl bg-gradient-to-b from-nova-700/20 via-nova-900/15 to-deep/40" />
|
|
)}
|
|
|
|
<div className="relative w-full aspect-video rounded-xl overflow-hidden bg-deep shadow-2xl ring-1 ring-nova-600/30">
|
|
<img
|
|
src={md}
|
|
alt={artwork?.title ?? 'Artwork'}
|
|
className="absolute inset-0 h-full w-full object-contain"
|
|
loading="eager"
|
|
decoding="async"
|
|
/>
|
|
|
|
<img
|
|
src={lg}
|
|
srcSet={srcSet}
|
|
sizes="(min-width: 1280px) 1280px, (min-width: 768px) 90vw, 100vw"
|
|
alt={artwork?.title ?? 'Artwork'}
|
|
className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-500 ${isLoaded ? 'opacity-100' : 'opacity-0'}`}
|
|
loading="eager"
|
|
decoding="async"
|
|
onLoad={() => setIsLoaded(true)}
|
|
onError={(event) => {
|
|
event.currentTarget.src = FALLBACK_LG
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
{hasRealArtworkImage && (
|
|
<div className="pointer-events-none absolute inset-x-8 -bottom-5 h-10 rounded-full bg-accent/25 blur-2xl" />
|
|
)}
|
|
</div>
|
|
</figure>
|
|
)
|
|
}
|