UNPKG

dora-ui

Version:

A React.js Mobile UI Library

203 lines (173 loc) 6.25 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/esm/inherits"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import React, { Component } from 'react'; import cx from 'classnames'; import PropTypes from 'prop-types'; var Countdown = /*#__PURE__*/ function (_Component) { _inherits(Countdown, _Component); /** 计时器句柄 */ /** 计数器用于校正定时器偏差 */ function Countdown(props) { var _this; _classCallCheck(this, Countdown); _this = _possibleConstructorReturn(this, _getPrototypeOf(Countdown).call(this, props)); _defineProperty(_assertThisInitialized(_this), "beginTime", new Date().getTime()); _defineProperty(_assertThisInitialized(_this), "interval", 1000); _defineProperty(_assertThisInitialized(_this), "timeCounter", null); _defineProperty(_assertThisInitialized(_this), "count", 0); _defineProperty(_assertThisInitialized(_this), "initCounter", function () { if (_this.timeCounter) clearTimeout(_this.timeCounter); var endTime = _this.props.endTime; var ms = endTime - _this.beginTime; if (ms < 0) return; _this.setState({ ms: ms }, function () { _this.timeCounter = setTimeout(_this.startCountDown, _this.interval); }); }); _defineProperty(_assertThisInitialized(_this), "startCountDown", function () { var ms = _this.state.ms; var onEnd = _this.props.onEnd; _this.count += 1; var offset = new Date().getTime() - (_this.beginTime + _this.count * _this.interval); // 误差校正 var nextTime = _this.interval - offset; if (nextTime < 0) { nextTime = 0; } _this.setState({ ms: Math.max(ms - _this.interval, 0) }); // console.log( // `误差:${offset} ms,下一次执行:${nextTime} ms 后,离活动开始还有:${this.state.ms} ms` // ); if (_this.state.ms <= 0) { clearTimeout(_this.timeCounter); typeof onEnd === 'function' && onEnd(); } else { _this.timeCounter = setTimeout(_this.startCountDown, nextTime); } }); _defineProperty(_assertThisInitialized(_this), "padNumber", function (mark, num) { var _this$props = _this.props, padding = _this$props.padding, daysPadding = _this$props.daysPadding; if (mark === 'dd' && !daysPadding) return num; if (padding) return num.toString().padStart(2, '0'); return num; }); _this.state = { ms: 1 }; return _this; } _createClass(Countdown, [{ key: "componentDidMount", value: function componentDidMount() { this.initCounter(); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var endTime = this.props.endTime; if (endTime !== prevProps.endTime) { this.initCounter(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { clearTimeout(this.timeCounter); } }, { key: "render", value: function render() { var _this$props2 = this.props, prefixCls = _this$props2.prefixCls, wrapClassName = _this$props2.wrapClassName; var rootCls = cx(prefixCls, wrapClassName); return React.createElement("div", { className: rootCls }, this.formatTime); } }, { key: "parseTime", // 毫秒 => 天 时 分 秒 get: function get() { var ms = this.state.ms; return { days: Math.floor(ms / (1000 * 60 * 60 * 24)), hours: Math.floor(ms / (1000 * 60 * 60) % 24), minutes: Math.floor(ms / (1000 * 60) % 60), seconds: Math.floor(ms / 1000 % 60) }; } // 天 时 分 秒 => 展示字符串 }, { key: "formatTime", get: function get() { var _this2 = this; var _this$props3 = this.props, format = _this$props3.format, prefixCls = _this$props3.prefixCls; var _this$parseTime = this.parseTime, days = _this$parseTime.days, hours = _this$parseTime.hours, minutes = _this$parseTime.minutes, seconds = _this$parseTime.seconds; var timeMap = { dd: days, hh: hours, mm: minutes, ss: seconds }; return format.split(' ').map(function (item) { var _item$split = item.split('-'), _item$split2 = _slicedToArray(_item$split, 2), mark = _item$split2[0], _item$split2$ = _item$split2[1], unit = _item$split2$ === void 0 ? '' : _item$split2$; return React.createElement("span", { className: "".concat(prefixCls, "-time-block"), key: mark + unit }, React.createElement("span", { className: "".concat(prefixCls, "-time") }, String(_this2.padNumber(mark, timeMap[mark])).split('').map(function (s, i) { return ( /* eslint-disable-next-line react/no-array-index-key */ React.createElement("span", { key: i, className: "".concat(prefixCls, "-num") }, s) ); })), React.createElement("span", { className: "".concat(prefixCls, "-unit") }, unit)); }); } }]); return Countdown; }(Component); _defineProperty(Countdown, "propTypes", { endTime: PropTypes.number.isRequired, onEnd: PropTypes.func, prefixCls: PropTypes.string, wrapClassName: PropTypes.string, format: PropTypes.string, padding: PropTypes.bool, daysPadding: PropTypes.bool }); _defineProperty(Countdown, "defaultProps", { prefixCls: 'dora-countdown', wrapClassName: '', format: 'dd-天 hh-时 mm-分 ss-秒', padding: true, daysPadding: false }); export default Countdown;