@radishon/lumina 1.0.3 → 1.0.5
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.
- package/README.md +60 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +59 -9
- package/dist/index.mjs +59 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# Lumina
|
|
2
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
🌐 **在线演示**: [https://lumina.redishon.com](https://lumina.redishon.com)
|
|
6
|
+
|
|
3
7
|
一个优雅的动画加载指示器 **Web Component**,提供多种预设动画序列,为你的应用增添独特的视觉体验。**适用于所有前端框架**。
|
|
4
8
|
|
|
9
|
+
</div>
|
|
10
|
+
|
|
5
11
|
## 简介
|
|
6
12
|
|
|
7
13
|
Lumina 是一个轻量级的 Loading 组件,通过精心设计的 Unicode 字符序列和颜色配置,呈现出流畅的动画效果。无论是科技感的赛博朋克风格,还是自然的月相变化,都能为你的应用加载状态提供独特的视觉表达。
|
|
@@ -181,6 +187,58 @@ export class AppModule {}
|
|
|
181
187
|
<lumina-loading type="braille" speed="100"></lumina-loading>
|
|
182
188
|
```
|
|
183
189
|
|
|
190
|
+
### 高级自定义
|
|
191
|
+
|
|
192
|
+
#### 自定义字符序列
|
|
193
|
+
|
|
194
|
+
通过 `chars` 属性传入 JSON 格式的字符数组,完全自定义动画内容:
|
|
195
|
+
|
|
196
|
+
```html
|
|
197
|
+
<!-- 使用自定义字符 -->
|
|
198
|
+
<lumina-loading chars='["🚀","⭐","🌙","☀️"]' speed="100"></lumina-loading>
|
|
199
|
+
|
|
200
|
+
<!-- 自定义文字动画 -->
|
|
201
|
+
<lumina-loading chars='["L","O","A","D","I","N","G"]' speed="150"></lumina-loading>
|
|
202
|
+
|
|
203
|
+
<!-- 自定义符号 -->
|
|
204
|
+
<lumina-loading chars='["▖","▘","▝","▗"]' speed="120"></lumina-loading>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### 自定义颜色
|
|
208
|
+
|
|
209
|
+
通过 `color` 属性传入任意 CSS 颜色值:
|
|
210
|
+
|
|
211
|
+
```html
|
|
212
|
+
<!-- 自定义预设序列的颜色 -->
|
|
213
|
+
<lumina-loading type="star" color="#ff6b6b"></lumina-loading>
|
|
214
|
+
|
|
215
|
+
<!-- 结合自定义字符和颜色 -->
|
|
216
|
+
<lumina-loading chars='["●","○","★"]' color="#00ff88"></lumina-loading>
|
|
217
|
+
|
|
218
|
+
<!-- 支持所有 CSS 颜色格式 -->
|
|
219
|
+
<lumina-loading type="snow" color="rgb(255, 107, 107)"></lumina-loading>
|
|
220
|
+
<lumina-loading type="snow" color="hsl(330, 80%, 60%)"></lumina-loading>
|
|
221
|
+
<lumina-loading type="snow" color="coral"></lumina-loading>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### 完整自定义示例
|
|
225
|
+
|
|
226
|
+
```html
|
|
227
|
+
<!-- 完全自定义:字符 + 颜色 + 速度 -->
|
|
228
|
+
<lumina-loading
|
|
229
|
+
chars='["🔥","✨","💫","🌟"]'
|
|
230
|
+
color="#ffd700"
|
|
231
|
+
speed="80">
|
|
232
|
+
</lumina-loading>
|
|
233
|
+
|
|
234
|
+
<!-- 混合使用:预设序列 + 自定义颜色 -->
|
|
235
|
+
<lumina-loading
|
|
236
|
+
type="flower"
|
|
237
|
+
color="#ff1493"
|
|
238
|
+
speed="200">
|
|
239
|
+
</lumina-loading>
|
|
240
|
+
```
|
|
241
|
+
|
|
184
242
|
### JavaScript 动态控制
|
|
185
243
|
|
|
186
244
|
```javascript
|
|
@@ -195,6 +253,8 @@ el.speed = 200;
|
|
|
195
253
|
|------|------|--------|------|
|
|
196
254
|
| `type` | `SequenceKey` | `'claude'` | 动画序列类型,见下方可用序列列表 |
|
|
197
255
|
| `speed` | `number` | `180` | 动画帧切换速度(毫秒) |
|
|
256
|
+
| `chars` | `string[]` | `null` | 自定义字符序列(JSON 数组格式),优先级高于 `type` |
|
|
257
|
+
| `color` | `string` | `null` | 自定义颜色值,支持所有 CSS 颜色格式,优先级高于预设颜色 |
|
|
198
258
|
|
|
199
259
|
## 可用的序列类型
|
|
200
260
|
|
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,13 @@ declare class LuminaElement extends HTMLElement {
|
|
|
18
18
|
set type(value: SequenceKey);
|
|
19
19
|
get speed(): number;
|
|
20
20
|
set speed(value: number);
|
|
21
|
+
get chars(): string[] | null;
|
|
22
|
+
set chars(value: string[] | null);
|
|
23
|
+
get color(): string | null;
|
|
24
|
+
set color(value: string | null);
|
|
25
|
+
private getChars;
|
|
26
|
+
private getConfig;
|
|
27
|
+
private getColor;
|
|
21
28
|
private render;
|
|
22
29
|
private startAnimation;
|
|
23
30
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,13 @@ declare class LuminaElement extends HTMLElement {
|
|
|
18
18
|
set type(value: SequenceKey);
|
|
19
19
|
get speed(): number;
|
|
20
20
|
set speed(value: number);
|
|
21
|
+
get chars(): string[] | null;
|
|
22
|
+
set chars(value: string[] | null);
|
|
23
|
+
get color(): string | null;
|
|
24
|
+
set color(value: string | null);
|
|
25
|
+
private getChars;
|
|
26
|
+
private getConfig;
|
|
27
|
+
private getColor;
|
|
21
28
|
private render;
|
|
22
29
|
private startAnimation;
|
|
23
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -112,7 +112,7 @@ var LuminaElement = class extends HTMLElement {
|
|
|
112
112
|
this.attachShadow({ mode: "open" });
|
|
113
113
|
}
|
|
114
114
|
static get observedAttributes() {
|
|
115
|
-
return ["type", "speed"];
|
|
115
|
+
return ["type", "speed", "chars", "color"];
|
|
116
116
|
}
|
|
117
117
|
connectedCallback() {
|
|
118
118
|
this.render();
|
|
@@ -128,7 +128,7 @@ var LuminaElement = class extends HTMLElement {
|
|
|
128
128
|
if (name === "speed" && this._timer) {
|
|
129
129
|
this.startAnimation();
|
|
130
130
|
}
|
|
131
|
-
if (name === "type") {
|
|
131
|
+
if (name === "type" || name === "chars" || name === "color") {
|
|
132
132
|
this.render();
|
|
133
133
|
this.startAnimation();
|
|
134
134
|
}
|
|
@@ -147,17 +147,67 @@ var LuminaElement = class extends HTMLElement {
|
|
|
147
147
|
set speed(value) {
|
|
148
148
|
this.setAttribute("speed", String(value));
|
|
149
149
|
}
|
|
150
|
-
|
|
150
|
+
get chars() {
|
|
151
|
+
const charsAttr = this.getAttribute("chars");
|
|
152
|
+
if (charsAttr) {
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(charsAttr);
|
|
155
|
+
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
|
|
156
|
+
return parsed;
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
set chars(value) {
|
|
164
|
+
if (value === null) {
|
|
165
|
+
this.removeAttribute("chars");
|
|
166
|
+
} else {
|
|
167
|
+
this.setAttribute("chars", JSON.stringify(value));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
get color() {
|
|
171
|
+
return this.getAttribute("color");
|
|
172
|
+
}
|
|
173
|
+
set color(value) {
|
|
174
|
+
if (value === null) {
|
|
175
|
+
this.removeAttribute("color");
|
|
176
|
+
} else {
|
|
177
|
+
this.setAttribute("color", value);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
getChars() {
|
|
181
|
+
const customChars = this.chars;
|
|
182
|
+
if (customChars) {
|
|
183
|
+
return customChars;
|
|
184
|
+
}
|
|
151
185
|
const config = SEQUENCES[this.type] || SEQUENCES["claude"];
|
|
152
|
-
|
|
186
|
+
return config.chars;
|
|
187
|
+
}
|
|
188
|
+
getConfig() {
|
|
189
|
+
return SEQUENCES[this.type] || SEQUENCES["claude"];
|
|
190
|
+
}
|
|
191
|
+
getColor() {
|
|
192
|
+
const customColor = this.color;
|
|
193
|
+
if (customColor) {
|
|
194
|
+
return customColor;
|
|
195
|
+
}
|
|
196
|
+
const config = this.getConfig();
|
|
197
|
+
return config.color;
|
|
198
|
+
}
|
|
199
|
+
render() {
|
|
200
|
+
const chars = this.getChars();
|
|
201
|
+
const color = this.getColor();
|
|
202
|
+
const currentChar = chars[this._index] || chars[0];
|
|
153
203
|
this.shadowRoot.innerHTML = `
|
|
154
204
|
<style>
|
|
155
205
|
:host {
|
|
156
206
|
display: inline-block;
|
|
157
207
|
}
|
|
158
208
|
.container {
|
|
159
|
-
color: ${
|
|
160
|
-
text-shadow: 0 0 20px ${
|
|
209
|
+
color: ${color};
|
|
210
|
+
text-shadow: 0 0 20px ${color}66;
|
|
161
211
|
font-size: 42px;
|
|
162
212
|
height: 60px;
|
|
163
213
|
display: flex;
|
|
@@ -175,11 +225,11 @@ var LuminaElement = class extends HTMLElement {
|
|
|
175
225
|
if (this._timer) {
|
|
176
226
|
clearInterval(this._timer);
|
|
177
227
|
}
|
|
178
|
-
const
|
|
228
|
+
const chars = this.getChars();
|
|
179
229
|
this._timer = setInterval(() => {
|
|
180
|
-
this._index = (this._index + 1) %
|
|
230
|
+
this._index = (this._index + 1) % chars.length;
|
|
181
231
|
if (this._div) {
|
|
182
|
-
this._div.textContent =
|
|
232
|
+
this._div.textContent = chars[this._index];
|
|
183
233
|
}
|
|
184
234
|
}, this.speed);
|
|
185
235
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -85,7 +85,7 @@ var LuminaElement = class extends HTMLElement {
|
|
|
85
85
|
this.attachShadow({ mode: "open" });
|
|
86
86
|
}
|
|
87
87
|
static get observedAttributes() {
|
|
88
|
-
return ["type", "speed"];
|
|
88
|
+
return ["type", "speed", "chars", "color"];
|
|
89
89
|
}
|
|
90
90
|
connectedCallback() {
|
|
91
91
|
this.render();
|
|
@@ -101,7 +101,7 @@ var LuminaElement = class extends HTMLElement {
|
|
|
101
101
|
if (name === "speed" && this._timer) {
|
|
102
102
|
this.startAnimation();
|
|
103
103
|
}
|
|
104
|
-
if (name === "type") {
|
|
104
|
+
if (name === "type" || name === "chars" || name === "color") {
|
|
105
105
|
this.render();
|
|
106
106
|
this.startAnimation();
|
|
107
107
|
}
|
|
@@ -120,17 +120,67 @@ var LuminaElement = class extends HTMLElement {
|
|
|
120
120
|
set speed(value) {
|
|
121
121
|
this.setAttribute("speed", String(value));
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
get chars() {
|
|
124
|
+
const charsAttr = this.getAttribute("chars");
|
|
125
|
+
if (charsAttr) {
|
|
126
|
+
try {
|
|
127
|
+
const parsed = JSON.parse(charsAttr);
|
|
128
|
+
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
|
|
129
|
+
return parsed;
|
|
130
|
+
}
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
set chars(value) {
|
|
137
|
+
if (value === null) {
|
|
138
|
+
this.removeAttribute("chars");
|
|
139
|
+
} else {
|
|
140
|
+
this.setAttribute("chars", JSON.stringify(value));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
get color() {
|
|
144
|
+
return this.getAttribute("color");
|
|
145
|
+
}
|
|
146
|
+
set color(value) {
|
|
147
|
+
if (value === null) {
|
|
148
|
+
this.removeAttribute("color");
|
|
149
|
+
} else {
|
|
150
|
+
this.setAttribute("color", value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
getChars() {
|
|
154
|
+
const customChars = this.chars;
|
|
155
|
+
if (customChars) {
|
|
156
|
+
return customChars;
|
|
157
|
+
}
|
|
124
158
|
const config = SEQUENCES[this.type] || SEQUENCES["claude"];
|
|
125
|
-
|
|
159
|
+
return config.chars;
|
|
160
|
+
}
|
|
161
|
+
getConfig() {
|
|
162
|
+
return SEQUENCES[this.type] || SEQUENCES["claude"];
|
|
163
|
+
}
|
|
164
|
+
getColor() {
|
|
165
|
+
const customColor = this.color;
|
|
166
|
+
if (customColor) {
|
|
167
|
+
return customColor;
|
|
168
|
+
}
|
|
169
|
+
const config = this.getConfig();
|
|
170
|
+
return config.color;
|
|
171
|
+
}
|
|
172
|
+
render() {
|
|
173
|
+
const chars = this.getChars();
|
|
174
|
+
const color = this.getColor();
|
|
175
|
+
const currentChar = chars[this._index] || chars[0];
|
|
126
176
|
this.shadowRoot.innerHTML = `
|
|
127
177
|
<style>
|
|
128
178
|
:host {
|
|
129
179
|
display: inline-block;
|
|
130
180
|
}
|
|
131
181
|
.container {
|
|
132
|
-
color: ${
|
|
133
|
-
text-shadow: 0 0 20px ${
|
|
182
|
+
color: ${color};
|
|
183
|
+
text-shadow: 0 0 20px ${color}66;
|
|
134
184
|
font-size: 42px;
|
|
135
185
|
height: 60px;
|
|
136
186
|
display: flex;
|
|
@@ -148,11 +198,11 @@ var LuminaElement = class extends HTMLElement {
|
|
|
148
198
|
if (this._timer) {
|
|
149
199
|
clearInterval(this._timer);
|
|
150
200
|
}
|
|
151
|
-
const
|
|
201
|
+
const chars = this.getChars();
|
|
152
202
|
this._timer = setInterval(() => {
|
|
153
|
-
this._index = (this._index + 1) %
|
|
203
|
+
this._index = (this._index + 1) % chars.length;
|
|
154
204
|
if (this._div) {
|
|
155
|
-
this._div.textContent =
|
|
205
|
+
this._div.textContent = chars[this._index];
|
|
156
206
|
}
|
|
157
207
|
}, this.speed);
|
|
158
208
|
}
|