UNPKG

gui-one-nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

247 lines (246 loc) 8.96 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; var _excluded = ["paused", "startTime", "endTime", "millisecond", "format", "autoStart", "time", "className", "style", "onEnd", "onPaused", "onRestart", "onUpdate", "children"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React__default, { useState, useRef, useImperativeHandle, useEffect } from 'react'; import { c as cn } from './bem-893ad28d.js'; import { u as useConfig } from './configprovider.taro-6c7b3056.js'; var defaultProps = { paused: false, startTime: Date.now(), endTime: Date.now(), millisecond: false, format: 'HH:mm:ss', autoStart: true, time: 0 }; var InternalCountDown = function InternalCountDown(props, ref) { useConfig(); var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), paused = _defaultProps$props.paused, startTime = _defaultProps$props.startTime, endTime = _defaultProps$props.endTime, millisecond = _defaultProps$props.millisecond, format = _defaultProps$props.format, autoStart = _defaultProps$props.autoStart, time = _defaultProps$props.time, className = _defaultProps$props.className, style = _defaultProps$props.style, onEnd = _defaultProps$props.onEnd, onPaused = _defaultProps$props.onPaused, onRestart = _defaultProps$props.onRestart, onUpdate = _defaultProps$props.onUpdate, children = _defaultProps$props.children, rest = _objectWithoutProperties(_defaultProps$props, _excluded); var b = cn('countdown'); var _useState = useState(0), _useState2 = _slicedToArray(_useState, 2), restTimeStamp = _useState2[0], setRestTime = _useState2[1]; var stateRef = useRef({ pauseTime: 0, curr: 0, isPaused: paused, isIninted: false, timer: 0, restTime: 0, counting: !paused && autoStart, handleEndTime: Date.now(), diffTime: 0 // 设置了 startTime 时,与 date.now() 的差异 }); // 时间戳转换 或 获取当前时间的时间戳 var getTimeStamp = function getTimeStamp(timeStr) { if (!timeStr) return Date.now(); var t = timeStr; t = t > 0 ? +t : t.toString().replace(/-/g, '/'); return new Date(t).getTime(); }; // 倒计时 interval var initTime = function initTime() { stateRef.current.handleEndTime = endTime; stateRef.current.diffTime = Date.now() - getTimeStamp(startTime); // 时间差 if (!stateRef.current.counting) stateRef.current.counting = true; tick(); }; var tick = function tick() { stateRef.current.timer = requestAnimationFrame(function () { if (stateRef.current.counting) { var currentTime = Date.now() - stateRef.current.diffTime; var remainTime = Math.max(stateRef.current.handleEndTime - currentTime, 0); stateRef.current.restTime = remainTime; setRestTime(remainTime); if (!remainTime) { stateRef.current.counting = false; pause(); onEnd && onEnd(); } if (remainTime > 0) { tick(); } } }); }; // 将倒计时剩余时间格式化 参数: t 时间戳 type custom 自定义类型 var formatRemainTime = function formatRemainTime(t, type) { var ts = t; var rest = { d: 0, h: 0, m: 0, s: 0, ms: 0 }; var SECOND = 1000; var MINUTE = 60 * SECOND; var HOUR = 60 * MINUTE; var DAY = 24 * HOUR; if (ts > 0) { rest.d = ts >= SECOND ? Math.floor(ts / DAY) : 0; rest.h = Math.floor(ts % DAY / HOUR); rest.m = Math.floor(ts % HOUR / MINUTE); rest.s = Math.floor(ts % MINUTE / SECOND); rest.ms = Math.floor(ts % SECOND); } return type === 'custom' ? rest : parseFormat(_objectSpread({}, rest)); }; var parseFormat = function parseFormat(time) { var d = time.d; var h = time.h, m = time.m, s = time.s, ms = time.ms; var formatCache = format; if (formatCache.includes('DD')) { formatCache = formatCache.replace('DD', padZero(d)); } else { h += Number(d) * 24; } if (formatCache.includes('HH')) { formatCache = formatCache.replace('HH', padZero(h)); } else { m += Number(h) * 60; } if (formatCache.includes('mm')) { formatCache = formatCache.replace('mm', padZero(m)); } else { s += Number(m) * 60; } if (formatCache.includes('ss')) { formatCache = formatCache.replace('ss', padZero(s)); } else { ms += Number(s) * 1000; } if (formatCache.includes('S')) { var msC = padZero(ms, 3).toString(); if (formatCache.includes('SSS')) { formatCache = formatCache.replace('SSS', msC); } else if (formatCache.includes('SS')) { formatCache = formatCache.replace('SS', msC.slice(0, 2)); } else if (formatCache.includes('S')) { formatCache = formatCache.replace('SS', msC.slice(0, 1)); } } return formatCache; }; var padZero = function padZero(num) { var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; num += ''; while (num.length < length) { num = "0".concat(num); } return num.toString(); }; // 暂定 var pause = function pause() { cancelAnimationFrame(stateRef.current.timer); stateRef.current.counting = false; onPaused && onPaused(stateRef.current.restTime); }; useImperativeHandle(ref, function () { return { start: function start() { if (!stateRef.current.counting && !autoStart) { stateRef.current.counting = true; stateRef.current.handleEndTime = Date.now() + Number(stateRef.current.restTime); tick(); onRestart && onRestart(stateRef.current.restTime); } }, pause: function pause() { cancelAnimationFrame(stateRef.current.timer); stateRef.current.counting = false; onPaused && onPaused(stateRef.current.restTime); }, reset: function reset() { if (!autoStart) { pause(); stateRef.current.restTime = time; setRestTime(time); } } }; }); // 监听值变更 useEffect(function () { var tranTime = formatRemainTime(stateRef.current.restTime, 'custom'); onUpdate && onUpdate(tranTime); }, [restTimeStamp]); // 监听暂停 useEffect(function () { if (stateRef.current.isIninted) { if (paused) { if (stateRef.current.counting) { pause(); } } else { if (!stateRef.current.counting) { stateRef.current.counting = true; stateRef.current.handleEndTime = Date.now() + Number(stateRef.current.restTime); tick(); } onRestart && onRestart(stateRef.current.restTime); } } }, [paused]); // 监听开始结束时间变更 useEffect(function () { if (stateRef.current.isIninted) { initTime(); } }, [endTime, startTime]); // 初始化 useEffect(function () { if (autoStart) { initTime(); } else { stateRef.current.restTime = time; setRestTime(time); } if (!stateRef.current.isIninted) { stateRef.current.isIninted = true; } return componentWillUnmount; }, []); var componentWillUnmount = function componentWillUnmount() { clearInterval(stateRef.current.timer); }; var renderTime = function () { return formatRemainTime(stateRef.current.restTime); }(); return React__default.createElement("div", _objectSpread({ className: "".concat(b(), " ").concat(className || ''), style: _objectSpread({}, style) }, rest), children || React__default.createElement("div", { className: b('block'), // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML: { __html: "".concat(renderTime) } })); }; var CountDown = React__default.forwardRef(InternalCountDown); CountDown.defaultProps = defaultProps; CountDown.displayName = 'NutCountDown'; export { CountDown as C };