Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useState } from "react";
- import { useInView } from "react-intersection-observer";
- import PropTypes from "prop-types";
- const Img = ({
- src,
- srcSet,
- placeholder,
- width,
- height,
- alt = "",
- title = "",
- style
- }) => {
- const [imgLoaded, setLoaded] = useState(false);
- const [ref, inView] = useInView({
- threshold: 0,
- triggerOnce: true
- });
- const wrapperStyles = Object.assign(
- {
- position: `relative`,
- overflow: `hidden`
- },
- style
- );
- const paddingDivStyles = {
- width: `100%`,
- paddingBottom: `
- ${(Math.min(width, height) / Math.max(width, height)) * 100}%`
- };
- return (
- <div ref={ref} style={wrapperStyles}>
- {/* PADDING */}
- <div style={paddingDivStyles} />
- {inView && (
- <>
- {/* PLACEHOLDER */}
- <img
- src={placeholder}
- style={{
- position: `absolute`,
- top: 0,
- left: 0,
- width: `100%`,
- height: `100%`,
- objectFit: `cover`,
- objectPosition: `center center`,
- transition: `opacity 500ms 500ms ease`,
- opacity: imgLoaded ? 0 : 1
- }}
- alt={alt}
- title={title}
- />
- {/* IMAGE */}
- <img
- srcSet={srcSet}
- src={src}
- alt={alt}
- style={{
- position: `absolute`,
- top: 0,
- left: 0,
- width: `100%`,
- height: `100%`,
- objectFit: `cover`,
- objectPosition: `center center`,
- transition: `opacity 500ms ease`,
- opacity: imgLoaded ? 1 : 0
- }}
- onLoad={() => setLoaded(true)}
- alt={alt}
- title={title}
- />
- </>
- )}
- </div>
- );
- };
- Img.propTypes = {
- src: PropTypes.string.isRequired,
- srcSet: PropTypes.string.isRequired,
- width: PropTypes.number.isRequired,
- height: PropTypes.number.isRequired,
- alt: PropTypes.string,
- title: PropTypes.string
- };
- export default Img;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement