Last active
March 19, 2019 16:14
-
-
Save dane-stevens/c9046da4a2f83433dd1803de3b95ff03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Img extends React.Component { | |
constructor(props) { | |
... | |
this.state = { | |
... | |
isInViewport: false | |
lqipLoaded: false | |
} | |
... | |
this.handleViewport = this.handleViewport.bind(this) | |
} | |
componentDidMount() { | |
... | |
this.handleViewport() | |
this.window.addEventListener('scroll', this.handleViewport) | |
} | |
handleViewport() { | |
// Only run if the image has not already been loaded | |
if (this.imgRef.current && !this.state.lqipLoaded) { | |
// Get the viewport height | |
const windowHeight = this.window.innerHeight | |
// Get the top position of the <figure /> element | |
const imageTopPosition = this.imgRef.current.getBoundingClientRect().top | |
// Multiply the viewport * buffer (default buffer: 1.5) | |
const buffer = typeof this.props.buffer === 'number' && this.props.buffer > 1 && this.props.buffer < 10 ? this.props.buffer : 1.5 | |
// If <figure /> is in viewport | |
if (windowHeight * buffer > imageTopPosition) { | |
this.setState({ | |
isInViewport: true | |
}) | |
} | |
} | |
} | |
... | |
componentWillUnmount() { | |
this.window.removeEventListener('scroll', this.handleViewport) | |
} | |
render() { | |
// Destructure props and state | |
... | |
const { isInViewport, width } = this.state | |
... | |
return ( | |
<figure ref={this.imgRef}> | |
{ | |
// If the container width has been set, display the image else null | |
isInViewport && width > 0 ? ( | |
<img | |
onLoad={ () => { this.setState({ lqipLoaded: true }) } } | |
... | |
/> | |
) : null | |
} | |
</figure> | |
) | |
} | |
} | |
export default Img |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment