1 | "use client";
|
2 |
|
3 | import classNames from 'classnames';
|
4 | import * as React from 'react';
|
5 | function UnitNumber(_ref) {
|
6 | let {
|
7 | prefixCls,
|
8 | value,
|
9 | current,
|
10 | offset = 0
|
11 | } = _ref;
|
12 | let style;
|
13 | if (offset) {
|
14 | style = {
|
15 | position: 'absolute',
|
16 | top: `${offset}00%`,
|
17 | left: 0
|
18 | };
|
19 | }
|
20 | return React.createElement("span", {
|
21 | style: style,
|
22 | className: classNames(`${prefixCls}-only-unit`, {
|
23 | current
|
24 | })
|
25 | }, value);
|
26 | }
|
27 | function getOffset(start, end, unit) {
|
28 | let index = start;
|
29 | let offset = 0;
|
30 | while ((index + 10) % 10 !== end) {
|
31 | index += unit;
|
32 | offset += unit;
|
33 | }
|
34 | return offset;
|
35 | }
|
36 | export default function SingleNumber(props) {
|
37 | const {
|
38 | prefixCls,
|
39 | count: originCount,
|
40 | value: originValue
|
41 | } = props;
|
42 | const value = Number(originValue);
|
43 | const count = Math.abs(originCount);
|
44 | const [prevValue, setPrevValue] = React.useState(value);
|
45 | const [prevCount, setPrevCount] = React.useState(count);
|
46 |
|
47 | const onTransitionEnd = () => {
|
48 | setPrevValue(value);
|
49 | setPrevCount(count);
|
50 | };
|
51 |
|
52 | React.useEffect(() => {
|
53 | const timeout = setTimeout(() => {
|
54 | onTransitionEnd();
|
55 | }, 1000);
|
56 | return () => {
|
57 | clearTimeout(timeout);
|
58 | };
|
59 | }, [value]);
|
60 |
|
61 |
|
62 | let unitNodes;
|
63 | let offsetStyle;
|
64 | if (prevValue === value || Number.isNaN(value) || Number.isNaN(prevValue)) {
|
65 |
|
66 | unitNodes = [React.createElement(UnitNumber, Object.assign({}, props, {
|
67 | key: value,
|
68 | current: true
|
69 | }))];
|
70 | offsetStyle = {
|
71 | transition: 'none'
|
72 | };
|
73 | } else {
|
74 | unitNodes = [];
|
75 |
|
76 | const end = value + 10;
|
77 | const unitNumberList = [];
|
78 | for (let index = value; index <= end; index += 1) {
|
79 | unitNumberList.push(index);
|
80 | }
|
81 |
|
82 | const prevIndex = unitNumberList.findIndex(n => n % 10 === prevValue);
|
83 | unitNodes = unitNumberList.map((n, index) => {
|
84 | const singleUnit = n % 10;
|
85 | return React.createElement(UnitNumber, Object.assign({}, props, {
|
86 | key: n,
|
87 | value: singleUnit,
|
88 | offset: index - prevIndex,
|
89 | current: index === prevIndex
|
90 | }));
|
91 | });
|
92 |
|
93 | const unit = prevCount < count ? 1 : -1;
|
94 | offsetStyle = {
|
95 | transform: `translateY(${-getOffset(prevValue, value, unit)}00%)`
|
96 | };
|
97 | }
|
98 | return React.createElement("span", {
|
99 | className: `${prefixCls}-only`,
|
100 | style: offsetStyle,
|
101 | onTransitionEnd: onTransitionEnd
|
102 | }, unitNodes);
|
103 | } |
\ | No newline at end of file |