Skip to content

Instantly share code, notes, and snippets.

@dane-stevens
Last active March 19, 2019 16:14
Show Gist options
  • Save dane-stevens/c9046da4a2f83433dd1803de3b95ff03 to your computer and use it in GitHub Desktop.
Save dane-stevens/c9046da4a2f83433dd1803de3b95ff03 to your computer and use it in GitHub Desktop.
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