JSFiddle - React, Tailwind, and code Playground
by jestho
JavaScript
import React, { Component, PropTypes } from 'react';
import scrollToY from 'scroll-to-y';
export default class ScrollControl extends Component {
constructor(props) {
super(props);
this.screens = [];
this.state = {
currentIndex: null,
atEnd: false
}
window.addEventListener('scroll', this.handleScroll);
}
static propTypes = {
offsetMargin: PropTypes.number,
children: PropTypes.arrayOf(PropTypes.node).isRequired
}
static defaultProps = {
offsetMargin: 10
}
componentDidMount() {
Array.from(this.parentNode.children).map((child, i) => {
const { offsetTop, offsetHeight } = child;
this.screens[i] = {
index: i,
offsetTop,
offsetBottom: offsetTop + offsetHeight
};
});
}
handleScroll = () => {
const { scrollTop } = document.body;
const { offsetMargin } = this.props;
const inScrollRange = ({ offsetTop, offsetBottom }) => {
return (scrollTop > offsetTop - offsetMargin) && (scrollTop < offsetBottom - offsetMargin);
}
const currentScreen = this.screens.filter(inScrollRange)[0];
if (currentScreen) {
this.setState({
currentIndex: currentScreen.index,
atEnd: currentScreen.index === this.screens.length - 1
});
}
}
handleNext = (evt) => {
evt.preventDefault();
const nextScreen = this.screens[this.state.currentIndex + 1];
if (nextScreen) {
scrollToY(nextScreen.offsetTop, 1500, 'easeInOutQuint');
}
}
render() {
return (
<div ref={parent => this.parentNode = parent}>
{React.Children.map(this.props.children, (child) => (
<div style={{ position: 'relative' }}>
{child}
...