Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | 3x 3x 1x 3x | import React from 'react' // eslint-disable-line semi import ScrollReveal from 'scrollreveal' // eslint-disable-line semi /** * Creates React Component that will have animated elements on scroll * * @param {Array|object} srOptions * @param {string} srOptions.selector * @param {object} srOptions.options * @param {number} srOptions.interval * @return {function} React component */ const ReactScrollreveal = (srOptions = {}) => (Component) => { const sr = ScrollReveal(); class ComponentWithScrollReveal extends React.Component { static displayName = 'ComponentWithScrollReveal'; componentDidMount() { this.initialize(); } componentWillUpdate() { this.refresh(); } componentWillUnmount() { this.clean(); } /** * * @param {function} fn */ forEachSrElement = (fn) => { const elements = []; this.forEachSrOption(({ selector }) => { elements.concat(Array.prototype.slice.apply(document.querySelectorAll(selector))); }); elements.forEach(fn); }; /** * Iterates through all srOptions and applies given function * * @param {function} fn * @return undefined */ forEachSrOption = (fn) => { if (Array.isArray(srOptions)) { srOptions.forEach((options) => { fn(options); }); } else if (typeof srOptions === 'object') { fn(srOptions); } else { throw new TypeError('Invalid arguments were passed'); } }; /** * Get reveal elements by given selector * * @param {string} selector * @return {NodeList} */ getRevealElements(selector) { return selector ? this.animationContainer.querySelectorAll(selector) : this.animationContainer; } /** * Init scrollreveal for all reveal elements by selector * * @param {number} interval - ScrollReveal's interval value to make sequential animation * @param {object} options - ScrollReveal's options (see https://github.com/jlmakes/scrollreveal#2-configuration) * @param {string} selector - selector that gets elements to reveal */ applyRevealAnimation = ({ selector, options = {}, interval }) => { const revealElements = this.getRevealElements(selector); const opts = Object.assign({}, options); // revealElements can be NodeList or single node if (revealElements.length || !!revealElements.nodeType) { sr.reveal(revealElements, opts, interval); } }; /** * Initialize sr animations for every reveal element by given selector * * @return undefined */ initialize() { if (!this.animationContainer) { return; } this.forEachSrOption(this.applyRevealAnimation); } clean(cleanStyles) { // cleaning styles makes sr animation initialize again // on same element that were still in DOM if (cleanStyles) { this.forEachSrElement(sr.clean); } else { // remove event listeners // on component unmount event sr.destroy(); } } refresh() { this.clean(true); this.initialize(); } /** * Gets ref to the child's component desired animation container DOM node * * @param {object} node * @return undefined */ getRef = (node) => { if (typeof node.nodeType === 'number') { this.animationContainer = node; } else { throw new Error('You should put animationContainerReference on DOM node, not React component.'); } }; render() { return ( <Component animationContainerReference={this.getRef} destroyRevealAnimation={this.clean} refreshRevealAnimation={this.refresh} {...this.props} /> ); } } return ComponentWithScrollReveal; }; export default ReactScrollreveal; |