@arcblock/ux 1.17.11 → 1.17.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,234 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import styled from 'styled-components';
3
+ import PropTypes from 'prop-types';
4
+ import Lottie from 'react-lottie-player';
5
+ import lottieJson from './default-animation.json';
6
+
7
+ /**
8
+ * 用于长时间等待的用的动画组件
9
+ * 动画会随着时间的变化而逐步加快播放速度,好适应用户的等待心理
10
+ * @param {Object} animationData lottie json 动画数据
11
+ * @param {Number} size 动画的尺寸,单位px
12
+ * @param {String|Array} message 动画下方的文字;数组情况下会在一定时间切换文案
13
+ * @param {Number} messageDuration 动画下方的文字为数组时,每个文案的持续时间;默认5000ms
14
+ * @param {Number} messageLoop 动画下方的文字为数组时,文案是否循环播放
15
+ * @param {Array} tips 底部的提示元素
16
+ * @param {Number} tipsDuration 底部提示的切换时间,单位毫秒,默认3000ms
17
+ * @param {Number} speed 动画默认的播放速度
18
+ * @param {Number} maybeDuration 整个动画大概的持续时间,单位毫秒,用于计算增量下的动画速度,默认两分钟(120000ms)
19
+ * @param {Number} increaseSpeed 在 maybeDuration 时间下增加的速度,默认为0(不增加速度)
20
+ * @returns element
21
+ */
22
+ export default function AnimationWaiter({
23
+ animationData,
24
+ size,
25
+ message,
26
+ messageDuration,
27
+ messageLoop,
28
+ tips,
29
+ tipsDuration,
30
+ maybeDuration,
31
+ speed,
32
+ increaseSpeed,
33
+ ...rest
34
+ }) {
35
+ const [tipsId, setTipsId] = useState(0);
36
+ const [currentSpeed, setCurrentSpeed] = useState(speed);
37
+ const [desc, setDesc] = useState('');
38
+ // 动画的开始时间
39
+ const startTime = useRef(new Date().getTime());
40
+
41
+ useEffect(() => {
42
+ if (!message) {
43
+ return;
44
+ }
45
+
46
+ let timer1;
47
+ let msgId = 0;
48
+
49
+ if (Array.isArray(message)) {
50
+ setDesc(message[msgId]);
51
+ timer1 = setInterval(() => {
52
+ msgId++;
53
+ if (msgId >= message.length) {
54
+ if (messageLoop) {
55
+ msgId = 0;
56
+ } else {
57
+ msgId = message.length - 1;
58
+ }
59
+ }
60
+ setDesc(message[msgId]);
61
+ }, messageDuration);
62
+ } else {
63
+ setDesc(message);
64
+ }
65
+
66
+ // eslint-disable-next-line consistent-return
67
+ return () => {
68
+ clearInterval(timer1);
69
+ };
70
+ }, [message, messageDuration]);
71
+
72
+ // tips
73
+ useEffect(() => {
74
+ if (!tips.length) {
75
+ return () => {};
76
+ }
77
+
78
+ const timer = setTimeout(() => {
79
+ let nextId = tipsId + 1;
80
+
81
+ if (nextId >= tips.length) {
82
+ nextId = 0;
83
+ }
84
+
85
+ setTipsId(nextId);
86
+ }, tipsDuration);
87
+
88
+ return () => clearTimeout(timer);
89
+ }, [tips, tipsDuration, tipsId]);
90
+
91
+ // 动画speed
92
+ useEffect(() => {
93
+ const timer = setTimeout(() => {
94
+ const diffTime = new Date().getTime() - startTime.current;
95
+
96
+ let percentage = diffTime / maybeDuration;
97
+ if (percentage > 1) {
98
+ percentage = 1;
99
+ }
100
+
101
+ const newSpeed = speed + increaseSpeed * percentage;
102
+
103
+ setCurrentSpeed(newSpeed);
104
+ }, 1000);
105
+
106
+ return () => clearTimeout(timer);
107
+ }, [currentSpeed]);
108
+
109
+ return (
110
+ <Container {...rest}>
111
+ <Lottie
112
+ loop
113
+ animationData={animationData || lottieJson}
114
+ play
115
+ speed={currentSpeed}
116
+ style={{
117
+ width: size,
118
+ height: size,
119
+ }}
120
+ />
121
+ {message && (
122
+ <div className="waiter-message">
123
+ {desc}
124
+ <span className="waiter-loading" />
125
+ </div>
126
+ )}
127
+
128
+ {tips.length ? (
129
+ <div className="waiter-tips-container">
130
+ {tips.map((e, index) => {
131
+ return (
132
+ <div
133
+ className={`waiter-tips-block ${tipsId === index ? 'show-tips' : ''}`}
134
+ // eslint-disable-next-line react/no-array-index-key
135
+ key={index}>
136
+ {e}
137
+ </div>
138
+ );
139
+ })}
140
+ </div>
141
+ ) : (
142
+ ''
143
+ )}
144
+ </Container>
145
+ );
146
+ }
147
+
148
+ AnimationWaiter.propTypes = {
149
+ animationData: PropTypes.any,
150
+ size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
151
+ message: PropTypes.any,
152
+ messageDuration: PropTypes.number,
153
+ messageLoop: PropTypes.bool,
154
+ tips: PropTypes.array,
155
+ tipsDuration: PropTypes.number,
156
+ speed: PropTypes.number,
157
+ maybeDuration: PropTypes.number,
158
+ increaseSpeed: PropTypes.number,
159
+ };
160
+
161
+ AnimationWaiter.defaultProps = {
162
+ animationData: null,
163
+ size: '',
164
+ message: '',
165
+ messageDuration: 5000,
166
+ messageLoop: true,
167
+ tips: [],
168
+ tipsDuration: 5000,
169
+ speed: 1,
170
+ maybeDuration: 120000,
171
+ increaseSpeed: 0,
172
+ };
173
+
174
+ const Container = styled.div`
175
+ display: flex;
176
+ justify-content: center;
177
+ align-items: center;
178
+ flex-direction: column;
179
+ width: 100%;
180
+ height: 100%;
181
+
182
+ .waiter-message {
183
+ font-weight: 700;
184
+ font-size: 18px;
185
+ line-height: 22px;
186
+ }
187
+
188
+ .waiter-tips-container {
189
+ position: relative;
190
+ margin-top: auto;
191
+ width: 100%;
192
+ .waiter-tips-block {
193
+ position: absolute;
194
+ bottom: 0;
195
+ left: 0;
196
+ width: 100%;
197
+ opacity: 0;
198
+ pointer-events: none;
199
+ z-index: 1;
200
+ transform: translate(-20px, 0);
201
+ transition: all ease 0.4s;
202
+ &.show-tips {
203
+ opacity: 1;
204
+ pointer-events: auto;
205
+ z-index: 2;
206
+ transform: translate(0, 0);
207
+ }
208
+ }
209
+ }
210
+
211
+ .waiter-loading::after {
212
+ display: inline-block;
213
+ animation: dotty steps(1, end) 2s infinite;
214
+ content: '';
215
+ }
216
+
217
+ @keyframes dotty {
218
+ 0% {
219
+ content: '';
220
+ }
221
+ 25% {
222
+ content: '.';
223
+ }
224
+ 50% {
225
+ content: '..';
226
+ }
227
+ 75% {
228
+ content: '...';
229
+ }
230
+ 100% {
231
+ content: '';
232
+ }
233
+ }
234
+ `;
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import ActionButton from './ActionButton';
2
2
  import ActivityIndicator from './ActivityIndicator';
3
3
  import Alert from './Alert';
4
+ import AnimationWaiter from './AnimationWaiter';
4
5
  import Async from './Async';
5
6
  import Badge from './Badge';
6
7
  import Button from './Button';
@@ -33,6 +34,7 @@ export {
33
34
  ActionButton,
34
35
  ActivityIndicator,
35
36
  Alert,
37
+ AnimationWaiter,
36
38
  Async,
37
39
  Badge,
38
40
  Button,