diff --git a/lib/ReactFitText.js b/lib/ReactFitText.js index 6e2df1f..24228d5 100644 --- a/lib/ReactFitText.js +++ b/lib/ReactFitText.js @@ -14,6 +14,31 @@ var ReactDOM = require('react-dom'); var ReactPropTypes = require('prop-types'); var createClass = require('create-react-class'); +// Map from node to options +const nodes = new Map(); + +function updateElementStyle(element, options, width) { + element.style.fontSize = `${Math.min(Math.max(width / (options.compressor * 10), options.minFontSize), options.maxFontSize)}px`; +} + +let updateQueued = false; + +function onBodyResize() { + updateQueued = true; + const widths = []; + nodes.forEach((options, element) => { + widths.push(element.offsetWidth); + }); + let i = 0; + nodes.forEach((options, element) => { + updateElementStyle(element, options, widths[i]); + i += 1; + }); +} + +window.addEventListener("resize", onBodyResize); +window.addEventListener("load", onBodyResize); + module.exports = createClass({ displayName: 'ReactFitText', @@ -21,7 +46,7 @@ module.exports = createClass({ children: ReactPropTypes.element.isRequired, compressor: ReactPropTypes.number, minFontSize: ReactPropTypes.number, - maxFontSize: ReactPropTypes.number + maxFontSize: ReactPropTypes.number, }, getDefaultProps: function() { @@ -32,35 +57,31 @@ module.exports = createClass({ }; }, - componentDidMount: function() { - window.addEventListener("resize", this._onBodyResize); - window.addEventListener("load", this._onBodyResize); - this._onBodyResize(); + componentWillMount: function() { + if (!updateQueued) { + window.requestAnimationFrame(onBodyResize); + } }, componentWillUnmount: function() { - window.removeEventListener("resize", this._onBodyResize); - window.removeEventListener("load", this._onBodyResize); + if (this._childRef) { + nodes.delete(this._childRef); + } }, componentDidUpdate: function() { - this._onBodyResize(); + onBodyResize(); }, - _onBodyResize: function() { - var element = ReactDOM.findDOMNode(this); - var width = element.offsetWidth; - element.style.fontSize = Math.max( - Math.min((width / (this.props.compressor*10)), - parseFloat(this.props.maxFontSize)), - parseFloat(this.props.minFontSize)) + 'px'; - }, _renderChildren: function(){ var _this = this; return React.Children.map(this.props.children, function (child) { return React.cloneElement(child, { ref: function ref(c) { - return _this._childRef = c; + if (c) { + nodes.set(c, _this.props); + } + _this._childRef = c; } }); }); },