Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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