Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from kirill-konshin/master
Browse files Browse the repository at this point in the history
Performance improvements
  • Loading branch information
gtwalford authored Jan 4, 2018
2 parents 8db8b7a + 189981c commit a3a1278
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Thumbs.db
npm-debug.log
node_modules
bower_components
package-lock.json

################################################
# Grunt
Expand Down
38 changes: 29 additions & 9 deletions dist/inview.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _debounce = require('lodash/debounce');

var _debounce2 = _interopRequireDefault(_debounce);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
Expand Down Expand Up @@ -66,7 +70,9 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
_ref$showGuides = _ref.showGuides,
showGuides = _ref$showGuides === undefined ? false : _ref$showGuides,
_ref$fullElementInVie = _ref.fullElementInView,
fullElementInView = _ref$fullElementInVie === undefined ? true : _ref$fullElementInVie;
fullElementInView = _ref$fullElementInVie === undefined ? true : _ref$fullElementInVie,
_ref$debounceTime = _ref.debounceTime,
debounceTime = _ref$debounceTime === undefined ? 100 : _ref$debounceTime;

return function (ComposedComponent) {

Expand All @@ -84,6 +90,9 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
boundingBox: {},
viewPortBox: {}
};

_this.scrollListener = _this.scrollListener.bind(_this);
_this.handleScroll = (0, _debounce2.default)(_this.handleScroll.bind(_this), debounceTime);
return _this;
}

Expand All @@ -95,17 +104,26 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
}

if (typeof window !== 'undefined') {
window.addEventListener('scroll', this.handleScroll.bind(this));
window.addEventListener('scroll', this.scrollListener);
this.handleScroll();
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (typeof window !== 'undefined') {
window.removeEventListener('scroll', this.handleScroll.bind(this));
window.removeEventListener('scroll', this.scrollListener);
}
}
}, {
key: 'scrollListener',
value: function scrollListener() {
var _this2 = this;

window.requestAnimationFrame(function () {
_this2.handleScroll();
});
}
}, {
key: 'handleScroll',
value: function handleScroll() {
Expand All @@ -123,13 +141,15 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
} else {
elementIsInView = isElementTopVisible(element, boundingBox, viewPortBox);
}
var newState = {
elementIsInView: elementIsInView,
boundingBox: boundingBox,
viewPortBox: viewPortBox
};
if (elementIsInView) {
this.setState({ elementHasBeenInView: elementIsInView });
newState.elementHasBeenInView = elementIsInView;
}

this.setState({ elementIsInView: elementIsInView });
this.setState({ boundingBox: boundingBox });
this.setState({ viewPortBox: viewPortBox });
this.setState(newState);
}
}, {
key: '_showGuides',
Expand Down Expand Up @@ -167,7 +187,7 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
return _react2.default.createElement(
'div',
{ style: styles, ref: 'container' },
_react2.default.createElement(ComposedComponent, _extends({ update: this.handleScroll.bind(this) }, this.state, this.props)),
_react2.default.createElement(ComposedComponent, _extends({ update: this.handleScroll }, this.state, this.props)),
this._showGuides()
);
}
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
"standard": "^6.0.8"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0",
"react-dom": "^0.14.0 || ^15.0.0"
"react": "^0.14.0 || ^15.0.0 || ^16.0.0",
"react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0"
},
"dependencies": {
"lodash": "^4.17.4"
}
}
53 changes: 33 additions & 20 deletions src/inview.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import debounce from "lodash/debounce";

// Returns dimensions of container
function getViewPortBox(offsetY, boundingBox) {
Expand All @@ -10,8 +11,8 @@ function getViewPortBox(offsetY, boundingBox) {
if (offsetY >= 0 && offsetY <= 1) {
const newHeight = vHeight * (1- offsetY);
const newTop = (vHeight - newHeight) /2;
vTop = newTop;
vHeight = newHeight;
vTop = newTop;
vHeight = newHeight;
}

return {
Expand All @@ -33,14 +34,14 @@ function isElementFullyVisible (el, rect, viewport) {
return (
rect.top >= viewport.top &&
rect.left >= 0 &&
rect.bottom <= viewport.top + viewport.height &&
rect.bottom <= viewport.top + viewport.height &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}

function isElementTopVisible (el, rect, viewport) {
const topIsInView = !(rect.top >= (viewport.top + viewport.height));
const topIsAboveView = !((rect.top + rect.height - viewport.height) <= viewport.top);
const topIsAboveView = !((rect.top + rect.height - viewport.height) <= viewport.top);
return (
topIsInView && topIsAboveView
);
Expand All @@ -49,21 +50,25 @@ function isElementTopVisible (el, rect, viewport) {
let ReactInviewWrapper = function ReactInviewWrapper ({
offsetY = 0,
showGuides = false,
fullElementInView = true
fullElementInView = true,
debounceTime = 100
}={}) {
return (ComposedComponent) => {

return class ReactInview extends Component {

constructor() {
super();

this.state = {
elementIsInView: false,
elementIsHasBeenInView: false,
boundingBox: {},
viewPortBox: {}
};

this.scrollListener = this.scrollListener.bind(this);
this.handleScroll = debounce(this.handleScroll.bind(this), debounceTime);
}

componentDidMount() {
Expand All @@ -72,20 +77,26 @@ let ReactInviewWrapper = function ReactInviewWrapper ({
}

if (typeof(window) !== 'undefined') {
window.addEventListener('scroll', this.handleScroll.bind(this));
window.addEventListener('scroll', this.scrollListener);
this.handleScroll();
}

}

componentWillUnmount() {
if (typeof(window) !== 'undefined') {
window.removeEventListener('scroll', this.handleScroll.bind(this));
}
window.removeEventListener('scroll', this.scrollListener);
}
}

scrollListener() {
window.requestAnimationFrame(() => {
this.handleScroll();
});
}

handleScroll() {
if (typeof this.refs.container === 'undefined') { return; }
if (typeof this.refs.container === 'undefined') { return; }

const element = this.refs.container.children[0];
const boundingBox = getBoundingBox(element);
Expand All @@ -97,20 +108,22 @@ let ReactInviewWrapper = function ReactInviewWrapper ({
} else {
elementIsInView = isElementTopVisible(element, boundingBox, viewPortBox);
}
const newState = {
elementIsInView: elementIsInView,
boundingBox: boundingBox,
viewPortBox: viewPortBox
};
if (elementIsInView) {
this.setState({elementHasBeenInView: elementIsInView});
newState.elementHasBeenInView = elementIsInView;
}

this.setState({elementIsInView: elementIsInView});
this.setState({boundingBox: boundingBox});
this.setState({viewPortBox: viewPortBox});
this.setState(newState);
}

_showGuides() {
if (showGuides && typeof this.state.viewPortBox.top !== 'undefined') {
const {top, left, height, width} = this.state.viewPortBox;
let styles = {
'backgroundColor': '#ccc',
'backgroundColor': '#ccc',
'position': 'fixed',
'opacity': '.5',
'top': top,
Expand All @@ -121,8 +134,8 @@ let ReactInviewWrapper = function ReactInviewWrapper ({
};

return <div style={styles}></div>;
}
}
}
}

render() {
let styles = {};
Expand All @@ -133,7 +146,7 @@ let ReactInviewWrapper = function ReactInviewWrapper ({
}
return (
<div style={styles} ref="container">
<ComposedComponent update={this.handleScroll.bind(this)} {...this.state} {...this.props} />
<ComposedComponent update={this.handleScroll} {...this.state} {...this.props} />
{ this._showGuides() }
</div>
);
Expand Down

0 comments on commit a3a1278

Please sign in to comment.