UNPKG

@nutui/nutui-react-taro

Version:

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

89 lines (88 loc) 3.98 kB
import React__default, { useRef, useCallback, useState, useEffect, Component } from "react"; import { _ as __rest } from "./tslib.es6-iWu3F_1J.js"; import { createSelectorQuery } from "@tarojs/taro"; import { C as ComponentDefaults } from "./typings-DV9RBfhj.js"; import { m as mergeProps } from "./merge-props-2rRqFlJz.js"; const defaultProps$1 = Object.assign(Object.assign({}, ComponentDefaults), { length: 0, value: "", delay: 300, duration: 1, thousands: false }); const CountUp = (props) => { const _a = mergeProps(defaultProps$1, props), { length, value, delay, duration, className, thousands, style } = _a; __rest(_a, ["length", "value", "delay", "duration", "className", "thousands", "style"]); const classPrefix = "nut-countup"; const countupRef = useRef(null); const timerRef = useRef(0); const numbers = Array.from({ length: 10 }, (v, i) => i); const getShowNumber = useCallback(() => { const splitArr = value.split("."); const intNumber = length && splitArr[0].length < length ? (Array(length).join("0") + splitArr[0]).slice(-length) : splitArr[0]; const currNumber = `${thousands ? intNumber.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,") : intNumber}${splitArr[1] ? "." : ""}${splitArr[1] || ""}`; return currNumber.split(""); }, [length, thousands, value]); const [numerArr, setNumerArr] = useState([]); const [transformArr, setTransformArr] = useState([]); const isLoaded = useRef(false); const setNumberTransform = useCallback(() => { if (countupRef.current && numerArr.length) { createSelectorQuery().selectAll(".nut-countup-listitem").node((numberItems) => { const transformArrCache = []; Object.keys(numberItems).forEach((key) => { const elem = numberItems[Number(key)]; const idx = Number(numerArr[Number(key)]); if (elem) { const transform = idx || idx === 0 ? `translate(0, -${(idx === 0 ? 10 : idx) * 5}%)` : ""; transformArrCache.push(transform); } }); setTransformArr([...transformArrCache]); }).exec(); } }, [numerArr]); const numberEaseStyle = (idx) => { return { transition: `transform ${duration}s ease-in-out`, transform: transformArr[idx] ? transformArr[idx] : null }; }; useEffect(() => { setNumberTransform(); }, [numerArr, setNumberTransform]); useEffect(() => { if (!isLoaded.current) { isLoaded.current = true; timerRef.current = window.setTimeout(() => { setNumerArr(getShowNumber()); }, delay); } else { setNumerArr(getShowNumber()); } return () => { window.clearTimeout(timerRef.current); }; }, [value, delay, getShowNumber]); return React__default.createElement( "div", { className: `${classPrefix} ${className}`, ref: countupRef }, React__default.createElement("ul", { className: `${classPrefix}-list` }, numerArr.map((item, idx) => { return React__default.createElement("li", { className: `${classPrefix}-listitem ${!Number.isNaN(Number(item)) ? `${classPrefix}-listitem-number` : ""}`, key: idx }, !Number.isNaN(Number(item)) ? React__default.createElement("span", { className: `${classPrefix}-number`, style: numberEaseStyle(idx) }, [...numbers, ...numbers].map((number, subidx) => { return React__default.createElement("span", { key: subidx }, number); })) : React__default.createElement("span", { className: `${classPrefix}-separator` }, item)); })) ); }; CountUp.displayName = "NutCountUp"; const defaultProps = {}; class AnimatingNumbers extends Component { constructor(props) { super(props); this.state = {}; } render() { return React__default.createElement("div", { className: "nut-animatingnumbers" }); } } AnimatingNumbers.defaultProps = defaultProps; AnimatingNumbers.displayName = "NutAnimatingNumbers"; AnimatingNumbers.CountUp = CountUp; AnimatingNumbers.CountUp = CountUp; export { AnimatingNumbers as default };