UNPKG

react-dynamic-font

Version:

make your text does not wrap and dynamically adjust the font size

144 lines (134 loc) 5.77 kB
import { createRef, createElement, Component } from 'react'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function getNodeWidth(node) { var nodeStyles = window.getComputedStyle(node); var width = node.offsetWidth; var borderLeftWidth = parseFloat(nodeStyles.borderLeftWidth); var borderRightWidth = parseFloat(nodeStyles.borderRightWidth); var paddingLeft = parseFloat(nodeStyles.paddingLeft); var paddingRight = parseFloat(nodeStyles.paddingRight); return width - borderRightWidth - borderLeftWidth - paddingLeft - paddingRight; } var styles = { main: { display: 'inline-block', whiteSpace: 'nowrap', msTransformOrigin: '0 50%', WebkitTransformOrigin: '0 50%', OTransformOrigin: '0 50%', MozTransformOrigin: '0 50%', transformOrigin: '0 50%', }, animate: { // msTransition: '-ms-transform 400ms', WebkitTransition: '-webkit-transform 400ms', OTransition: '-o-transform 400ms', MozTransition: '-moz-transform 400ms', transition: 'transform 400ms', }, }; var ReactDynamicFont = /** @class */ (function (_super) { __extends(ReactDynamicFont, _super); function ReactDynamicFont() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { scale: 1, }; _this.spanRef = createRef(); _this.getMaxWidth = function () { return getNodeWidth(_this.spanRef.current.parentElement); }; _this.getCurrentWidth = function () { return getNodeWidth(_this.spanRef.current); }; _this.retryTimmer = null; _this.timesOfRetryGetWidth = 0; _this.fixWidth = function () { var maxWidth = _this.getMaxWidth(); var currentWidth = _this.getCurrentWidth(); if (currentWidth <= 0) { _this.setRetryTimmer(); } else { _this.timesOfRetryGetWidth = 0; if (currentWidth > maxWidth) { _this.setState({ scale: maxWidth / currentWidth }); } else { _this.setState({ scale: 1 }); } } }; return _this; } ReactDynamicFont.prototype.componentDidMount = function () { if (this.props.content && this.props.content.length) { this.fixWidth(); } }; ReactDynamicFont.prototype.componentDidUpdate = function (prevProps) { if (prevProps.content !== this.props.content && (this.props.content || '').length) { this.fixWidth(); } }; ReactDynamicFont.prototype.setRetryTimmer = function () { if (this.retryTimmer != null) { clearTimeout(this.retryTimmer); this.retryTimmer = null; } if (this.timesOfRetryGetWidth <= ReactDynamicFont.maxRetryTimes) { this.retryTimmer = window.setTimeout(this.fixWidth, ReactDynamicFont.retryDelayMillisecond); } }; ReactDynamicFont.prototype.render = function () { var scaleStyle; if (this.state.scale === 1) { scaleStyle = undefined; } else { var transformValue = "scale(" + this.state.scale + ", " + this.state.scale + ")"; scaleStyle = { msTransform: transformValue, WebkitTransform: transformValue, OTransform: transformValue, MozTransform: transformValue, transform: transformValue, }; } var finalStyle = __assign({}, styles.main, ((this.props.smooth != null ? this.props.smooth : false) ? styles.animate : undefined), scaleStyle); return (createElement("span", { style: finalStyle, ref: this.spanRef }, this.props.content)); }; ReactDynamicFont.retryDelayMillisecond = 300; ReactDynamicFont.maxRetryTimes = 5; return ReactDynamicFont; }(Component)); export default ReactDynamicFont;