Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { PureComponent } from 'react';
- import PropTypes from 'prop-types';
- export default class ViewportTrigger extends PureComponent {
- static propTypes = {
- onViewportEnter: PropTypes.func,
- onViewportLeave: PropTypes.func,
- children: PropTypes.node,
- threshold: PropTypes.number,
- };
- static defaultProps = {
- threshold: 0,
- };
- state = {
- hasEntered: false,
- };
- componentDidMount() {
- window.addEventListener('scroll', this.onToggle, false);
- window.addEventListener('resize', this.onToggle, false);
- }
- componentWillUnmount() {
- window.removeEventListener('scroll', this.onToggle, false);
- window.removeEventListener('resize', this.onToggle, false);
- }
- onToggle = () => {
- if (this.trigger) {
- if (!this.state.hasEntered && this.isInViewport()) {
- this.onViewportEnter();
- } else if (this.state.hasEntered && !this.isInViewport()) {
- this.onViewportLeave();
- }
- }
- }
- onViewportEnter() {
- const { onViewportEnter } = this.props;
- if (onViewportEnter) onViewportEnter();
- this.setState({
- hasEntered: true,
- });
- }
- onViewportLeave() {
- const { onViewportLeave } = this.props;
- if (onViewportLeave) onViewportLeave();
- this.setState({
- hasEntered: false,
- });
- }
- isInViewport() {
- const { threshold } = this.props;
- if (!this.trigger) return false;
- const {
- top,
- left,
- bottom,
- right,
- } = this.trigger.getBoundingClientRect();
- const width = document.documentElement.clientWidth
- || document.body.clientWidth
- || window.innerWidth;
- const height = document.documentElement.clientHeight
- || document.body.clientHeight
- || window.innerHeight;
- const maxWidth = width + threshold;
- const maxHeight = height + threshold;
- return ((
- (top >= -threshold && top <= maxHeight) || (bottom >= -threshold && bottom <= maxHeight)
- )
- && (
- (left >= -threshold && left <= maxWidth) || (right >= -threshold && right <= maxWidth)
- ));
- }
- setTrigger = (ref) => {
- this.trigger = ref;
- };
- render() {
- const { children } = this.props;
- return (
- <span ref={this.setTrigger}>
- {children}
- </span>
- );
- }
- }
Add Comment
Please, Sign In to add comment