A React component to render images smoothly.
// RenderSmoothImage.jsx | |
import React from "react"; | |
import './styles.scss'; | |
export default ({ src, alt = "notFound", objectFit = "contain" }) => { | |
const [imageLoaded, setImageLoaded] = React.useState(false); | |
const [isValidSrc, setIsValidSrc] = React.useState(!!src); | |
return ( | |
<div className="smooth-image-wrapper"> | |
{isValidSrc ? ( | |
<img | |
className={`smooth-image img-${imageLoaded ? "visible" : "hidden"}`} | |
style={{ objectFit }} | |
src={src} | |
alt={alt} | |
onLoad={() => setImageLoaded(true)} | |
onError={() => setIsValidSrc(false)} | |
/> | |
) : ( | |
<div className="smooth-no-image">{alt}</div> | |
)} | |
{isValidSrc && !imageLoaded && ( | |
<div className="smooth-preloader"> | |
<span className="loader" /> | |
</div> | |
)} | |
</div> | |
); | |
}; |
// styles.scss | |
.fullSize { | |
width: 100%; | |
height: 100%; | |
} | |
.smooth-image-wrapper { | |
@extend .fullSize; | |
position: relative; | |
.smooth-image { | |
transition: opacity 1s; | |
@extend .fullSize; | |
} | |
.smooth-no-image { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
@extend .fullSize; | |
background-color: #fcfcfc; | |
text-transform: capitalize; | |
} | |
.img-visible { | |
opacity: 1; | |
} | |
.img-hidden { | |
opacity: 0; | |
} | |
@keyframes preloader-block { | |
from { | |
background-position: 0%, 0; | |
} | |
to { | |
background-position: 170%, 0; | |
} | |
} | |
.smooth-preloader { | |
position: absolute; | |
top: 0; | |
left: 0; | |
@extend .fullSize; | |
background: rgba(245, 245, 245, 0.34); | |
.loader { | |
background-image: linear-gradient(to right, #e6e6e6, #ffffff, #e6e6e6); | |
@extend .fullSize; | |
display: inline-block; | |
background-size: 200%; | |
animation: preloader-block 2s linear 0s infinite reverse forwards; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment