@5even7/dlc-ui 0.1.0 → 0.2.1
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/CHANGELOG.md +33 -3
- package/README.md +277 -248
- package/dist/capsule.cjs +421 -103
- package/dist/capsule.mjs +481 -197
- package/dist/color.cjs +342 -37
- package/dist/color.mjs +390 -105
- package/dist/index.cjs +745 -203
- package/dist/index.mjs +923 -457
- package/dist/index.umd.js +745 -203
- package/dist/index.umd.min.js +1 -1
- package/dist/progress.cjs +487 -116
- package/dist/progress.mjs +568 -245
- package/dist/vue2.cjs +1092 -208
- package/dist/vue2.mjs +1280 -501
- package/dist/vue3.cjs +1092 -208
- package/dist/vue3.mjs +1280 -501
- package/package.json +1 -1
- package/styles/base.css +12 -18
- package/styles/capsule.css +34 -81
- package/styles/progress.css +37 -57
- package/types/index.d.ts +97 -81
- package/types/vue3.d.ts +59 -20
package/dist/color.mjs
CHANGED
|
@@ -91,61 +91,247 @@ const PALETTES = {
|
|
|
91
91
|
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
92
92
|
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
93
93
|
*/
|
|
94
|
-
const CAPSULE_PRESETS = [
|
|
95
|
-
{ id: 'original', code: 'NC-01', name: '
|
|
96
|
-
{ id: 'ocean', code: 'NC-02', name: '
|
|
97
|
-
{ id: 'klein', code: 'NC-03', name: '
|
|
98
|
-
{ id: 'ultraviolet', code: 'NC-04', name: '
|
|
99
|
-
{ id: 'chrome', code: 'NC-05', name: '
|
|
100
|
-
{ id: 'plus', code: 'NC-06', name: '
|
|
94
|
+
const CAPSULE_PRESETS = [
|
|
95
|
+
{ id: 'original', code: 'NC-01', name: '初光', group: 'warm', seed: 1.7, speed: 0.5, colors: [...PALETTES.original] },
|
|
96
|
+
{ id: 'ocean', code: 'NC-02', name: '沧溟', group: 'cold', seed: 8.2, speed: 0.48, colors: [...PALETTES.ocean] },
|
|
97
|
+
{ id: 'klein', code: 'NC-03', name: '玄夜', group: 'cold', seed: 14.1, speed: 0.49, colors: [...PALETTES.klein] },
|
|
98
|
+
{ id: 'ultraviolet', code: 'NC-04', name: '紫霄', group: 'cold', seed: 23.4, speed: 0.47, colors: [...PALETTES.ultraviolet] },
|
|
99
|
+
{ id: 'chrome', code: 'NC-05', name: '银汉', group: 'cold', seed: 37.8, speed: 0.42, colors: [...PALETTES.chrome] },
|
|
100
|
+
{ id: 'plus', code: 'NC-06', name: '熔金', group: 'warm', seed: 51.3, speed: 0.5, colors: [...PALETTES.plus] }
|
|
101
101
|
];
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const list = CAPSULE_PRESETS ;
|
|
118
|
-
if (!list) throw new Error(`Unknown preset kind: ${kind} (use "capsule" or "progress")`);
|
|
119
|
-
if (ref && typeof ref === 'object') {
|
|
120
|
-
const valid = validatePreset(ref) ;
|
|
121
|
-
if (!valid) throw new Error(`Invalid ${kind} preset object`);
|
|
122
|
-
return ref;
|
|
123
|
-
}
|
|
124
|
-
const key = String(ref).trim().toLowerCase();
|
|
125
|
-
const found = list.find(
|
|
126
|
-
(preset) =>
|
|
127
|
-
preset.id.toLowerCase() === key ||
|
|
128
|
-
preset.code.toLowerCase() === key ||
|
|
129
|
-
preset.name.toLowerCase() === key
|
|
130
|
-
);
|
|
131
|
-
if (!found) throw new Error(`Unknown ${kind} preset: ${ref}`);
|
|
132
|
-
return found;
|
|
103
|
+
/**
|
|
104
|
+
* Resolve a preset by its literary name (e.g. '沧溟').
|
|
105
|
+
* Matching is case-insensitive and ignores surrounding whitespace,
|
|
106
|
+
* so '沧溟' and ' 沧溟 ' both work.
|
|
107
|
+
*/
|
|
108
|
+
function getPreset(kind, ref) {
|
|
109
|
+
const list = CAPSULE_PRESETS ;
|
|
110
|
+
if (!list) throw new Error(`Unknown preset kind: ${kind} (use "capsule" or "progress")`);
|
|
111
|
+
const key = String(ref).trim().toLowerCase();
|
|
112
|
+
const found = list.find(
|
|
113
|
+
(preset) => preset.name.toLowerCase() === key
|
|
114
|
+
);
|
|
115
|
+
if (!found) throw new Error(`Unknown ${kind} preset: ${ref}`);
|
|
116
|
+
return found;
|
|
133
117
|
}
|
|
134
118
|
|
|
135
|
-
const DEFAULTS = {
|
|
136
|
-
capsule: {
|
|
137
|
-
quality: 'auto',
|
|
138
|
-
renderer: 'auto',
|
|
119
|
+
const DEFAULTS = {
|
|
120
|
+
capsule: {
|
|
121
|
+
quality: 'auto',
|
|
122
|
+
renderer: 'auto',
|
|
139
123
|
respectReducedMotion: true}};
|
|
140
124
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Color helpers. `normalizeColor` converts any supported CSS color
|
|
127
|
+
* (hex / named / rgb() / rgba()) into a 6-digit hex string, so renderers can
|
|
128
|
+
* keep working with #rrggbb only. rgba() alpha is intentionally dropped:
|
|
129
|
+
* the WebGL shader has no per-color alpha channel, and the component is
|
|
130
|
+
* opaque by design — use component-level `opacity` for transparency.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
const NAMED_COLORS = {
|
|
134
|
+
aliceblue: '#f0f8ff',
|
|
135
|
+
antiquewhite: '#faebd7',
|
|
136
|
+
aqua: '#00ffff',
|
|
137
|
+
aquamarine: '#7fffd4',
|
|
138
|
+
azure: '#f0ffff',
|
|
139
|
+
beige: '#f5f5dc',
|
|
140
|
+
bisque: '#ffe4c4',
|
|
141
|
+
black: '#000000',
|
|
142
|
+
blanchedalmond: '#ffebcd',
|
|
143
|
+
blue: '#0000ff',
|
|
144
|
+
blueviolet: '#8a2be2',
|
|
145
|
+
brown: '#a52a2a',
|
|
146
|
+
burlywood: '#deb887',
|
|
147
|
+
cadetblue: '#5f9ea0',
|
|
148
|
+
chartreuse: '#7fff00',
|
|
149
|
+
chocolate: '#d2691e',
|
|
150
|
+
coral: '#ff7f50',
|
|
151
|
+
cornflowerblue: '#6495ed',
|
|
152
|
+
cornsilk: '#fff8dc',
|
|
153
|
+
crimson: '#dc143c',
|
|
154
|
+
cyan: '#00ffff',
|
|
155
|
+
darkblue: '#00008b',
|
|
156
|
+
darkcyan: '#008b8b',
|
|
157
|
+
darkgoldenrod: '#b8860b',
|
|
158
|
+
darkgray: '#a9a9a9',
|
|
159
|
+
darkgreen: '#006400',
|
|
160
|
+
darkgrey: '#a9a9a9',
|
|
161
|
+
darkkhaki: '#bdb76b',
|
|
162
|
+
darkmagenta: '#8b008b',
|
|
163
|
+
darkolivegreen: '#556b2f',
|
|
164
|
+
darkorange: '#ff8c00',
|
|
165
|
+
darkorchid: '#9932cc',
|
|
166
|
+
darkred: '#8b0000',
|
|
167
|
+
darksalmon: '#e9967a',
|
|
168
|
+
darkseagreen: '#8fbc8f',
|
|
169
|
+
darkslateblue: '#483d8b',
|
|
170
|
+
darkslategray: '#2f4f4f',
|
|
171
|
+
darkslategrey: '#2f4f4f',
|
|
172
|
+
darkturquoise: '#00ced1',
|
|
173
|
+
darkviolet: '#9400d3',
|
|
174
|
+
deeppink: '#ff1493',
|
|
175
|
+
deepskyblue: '#00bfff',
|
|
176
|
+
dimgray: '#696969',
|
|
177
|
+
dimgrey: '#696969',
|
|
178
|
+
dodgerblue: '#1e90ff',
|
|
179
|
+
firebrick: '#b22222',
|
|
180
|
+
floralwhite: '#fffaf0',
|
|
181
|
+
forestgreen: '#228b22',
|
|
182
|
+
fuchsia: '#ff00ff',
|
|
183
|
+
gainsboro: '#dcdcdc',
|
|
184
|
+
ghostwhite: '#f8f8ff',
|
|
185
|
+
gold: '#ffd700',
|
|
186
|
+
goldenrod: '#daa520',
|
|
187
|
+
gray: '#808080',
|
|
188
|
+
green: '#008000',
|
|
189
|
+
greenyellow: '#adff2f',
|
|
190
|
+
grey: '#808080',
|
|
191
|
+
honeydew: '#f0fff0',
|
|
192
|
+
hotpink: '#ff69b4',
|
|
193
|
+
indianred: '#cd5c5c',
|
|
194
|
+
indigo: '#4b0082',
|
|
195
|
+
ivory: '#fffff0',
|
|
196
|
+
khaki: '#f0e68c',
|
|
197
|
+
lavender: '#e6e6fa',
|
|
198
|
+
lavenderblush: '#fff0f5',
|
|
199
|
+
lawngreen: '#7cfc00',
|
|
200
|
+
lemonchiffon: '#fffacd',
|
|
201
|
+
lightblue: '#add8e6',
|
|
202
|
+
lightcoral: '#f08080',
|
|
203
|
+
lightcyan: '#e0ffff',
|
|
204
|
+
lightgoldenrodyellow: '#fafad2',
|
|
205
|
+
lightgray: '#d3d3d3',
|
|
206
|
+
lightgreen: '#90ee90',
|
|
207
|
+
lightgrey: '#d3d3d3',
|
|
208
|
+
lightpink: '#ffb6c1',
|
|
209
|
+
lightsalmon: '#ffa07a',
|
|
210
|
+
lightseagreen: '#20b2aa',
|
|
211
|
+
lightskyblue: '#87cefa',
|
|
212
|
+
lightslategray: '#778899',
|
|
213
|
+
lightslategrey: '#778899',
|
|
214
|
+
lightsteelblue: '#b0c4de',
|
|
215
|
+
lightyellow: '#ffffe0',
|
|
216
|
+
lime: '#00ff00',
|
|
217
|
+
limegreen: '#32cd32',
|
|
218
|
+
linen: '#faf0e6',
|
|
219
|
+
magenta: '#ff00ff',
|
|
220
|
+
maroon: '#800000',
|
|
221
|
+
mediumaquamarine: '#66cdaa',
|
|
222
|
+
mediumblue: '#0000cd',
|
|
223
|
+
mediumorchid: '#ba55d3',
|
|
224
|
+
mediumpurple: '#9370db',
|
|
225
|
+
mediumseagreen: '#3cb371',
|
|
226
|
+
mediumslateblue: '#7b68ee',
|
|
227
|
+
mediumspringgreen: '#00fa9a',
|
|
228
|
+
mediumturquoise: '#48d1cc',
|
|
229
|
+
mediumvioletred: '#c71585',
|
|
230
|
+
midnightblue: '#191970',
|
|
231
|
+
mintcream: '#f5fffa',
|
|
232
|
+
mistyrose: '#ffe4e1',
|
|
233
|
+
moccasin: '#ffe4b5',
|
|
234
|
+
navajowhite: '#ffdead',
|
|
235
|
+
navy: '#000080',
|
|
236
|
+
oldlace: '#fdf5e6',
|
|
237
|
+
olive: '#808000',
|
|
238
|
+
olivedrab: '#6b8e23',
|
|
239
|
+
orange: '#ffa500',
|
|
240
|
+
orangered: '#ff4500',
|
|
241
|
+
orchid: '#da70d6',
|
|
242
|
+
palegoldenrod: '#eee8aa',
|
|
243
|
+
palegreen: '#98fb98',
|
|
244
|
+
paleturquoise: '#afeeee',
|
|
245
|
+
palevioletred: '#db7093',
|
|
246
|
+
papayawhip: '#ffefd5',
|
|
247
|
+
peachpuff: '#ffdab9',
|
|
248
|
+
peru: '#cd853f',
|
|
249
|
+
pink: '#ffc0cb',
|
|
250
|
+
plum: '#dda0dd',
|
|
251
|
+
powderblue: '#b0e0e6',
|
|
252
|
+
purple: '#800080',
|
|
253
|
+
rebeccapurple: '#663399',
|
|
254
|
+
red: '#ff0000',
|
|
255
|
+
rosybrown: '#bc8f8f',
|
|
256
|
+
royalblue: '#4169e1',
|
|
257
|
+
saddlebrown: '#8b4513',
|
|
258
|
+
salmon: '#fa8072',
|
|
259
|
+
sandybrown: '#f4a460',
|
|
260
|
+
seagreen: '#2e8b57',
|
|
261
|
+
seashell: '#fff5ee',
|
|
262
|
+
sienna: '#a0522d',
|
|
263
|
+
silver: '#c0c0c0',
|
|
264
|
+
skyblue: '#87ceeb',
|
|
265
|
+
slateblue: '#6a5acd',
|
|
266
|
+
slategray: '#708090',
|
|
267
|
+
slategrey: '#708090',
|
|
268
|
+
snow: '#fffafa',
|
|
269
|
+
springgreen: '#00ff7f',
|
|
270
|
+
steelblue: '#4682b4',
|
|
271
|
+
tan: '#d2b48c',
|
|
272
|
+
teal: '#008080',
|
|
273
|
+
thistle: '#d8bfd8',
|
|
274
|
+
tomato: '#ff6347',
|
|
275
|
+
turquoise: '#40e0d0',
|
|
276
|
+
violet: '#ee82ee',
|
|
277
|
+
wheat: '#f5deb3',
|
|
278
|
+
white: '#ffffff',
|
|
279
|
+
whitesmoke: '#f5f5f5',
|
|
280
|
+
yellow: '#ffff00',
|
|
281
|
+
yellowgreen: '#9acd32'
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
function clampChannel(value) {
|
|
285
|
+
return Math.min(255, Math.max(0, Math.round(value)));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function normalizeRgbArgs(args) {
|
|
289
|
+
const parts = args.split(/[,\s/]+/).filter(Boolean);
|
|
290
|
+
if (parts.length < 3) return null;
|
|
291
|
+
const to255 = (value) => {
|
|
292
|
+
if (typeof value !== 'string' || !value) return null;
|
|
293
|
+
if (value.endsWith('%')) return clampChannel((parseFloat(value) / 100) * 255);
|
|
294
|
+
const number = Number(value);
|
|
295
|
+
return Number.isFinite(number) ? clampChannel(number) : null;
|
|
296
|
+
};
|
|
297
|
+
const red = to255(parts[0]);
|
|
298
|
+
const green = to255(parts[1]);
|
|
299
|
+
const blue = to255(parts[2]);
|
|
300
|
+
if (red === null || green === null || blue === null) return null;
|
|
301
|
+
return `#${[red, green, blue].map((n) => n.toString(16).padStart(2, '0')).join('')}`;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Convert any supported CSS color into `#rrggbb`. Returns null when the
|
|
306
|
+
* value cannot be parsed. Supports: #rgb / #rrggbb (case-insensitive),
|
|
307
|
+
* CSS named colors, rgb() / rgba() with comma or modern space syntax,
|
|
308
|
+
* including percentages. Alpha in rgba() is ignored.
|
|
309
|
+
*/
|
|
310
|
+
function normalizeColor(value) {
|
|
311
|
+
if (typeof value !== 'string') return null;
|
|
312
|
+
const input = value.trim();
|
|
313
|
+
if (!input) return null;
|
|
314
|
+
const lower = input.toLowerCase();
|
|
315
|
+
if (NAMED_COLORS[lower]) return NAMED_COLORS[lower];
|
|
316
|
+
if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(input)) {
|
|
317
|
+
const hex = input.slice(1).toLowerCase();
|
|
318
|
+
if (hex.length === 3) return `#${hex.split('').map((c) => c + c).join('')}`;
|
|
319
|
+
return `#${hex}`;
|
|
320
|
+
}
|
|
321
|
+
const match = input.match(/^rgba?\((.*)\)$/i);
|
|
322
|
+
if (match) return normalizeRgbArgs(match[1]);
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function hexToRgb01(color) {
|
|
327
|
+
const hex = normalizeColor(color);
|
|
328
|
+
if (!hex) return [0, 0, 0];
|
|
329
|
+
const value = Number.parseInt(hex.slice(1), 16);
|
|
330
|
+
return [
|
|
331
|
+
((value >> 16) & 255) / 255,
|
|
332
|
+
((value >> 8) & 255) / 255,
|
|
333
|
+
(value & 255) / 255
|
|
334
|
+
];
|
|
149
335
|
}
|
|
150
336
|
|
|
151
337
|
const VERTEX_SHADER = `#version 300 es
|
|
@@ -373,12 +559,31 @@ class CosmicRenderer {
|
|
|
373
559
|
this.timeOffset = preset.seed * 0.73;
|
|
374
560
|
}
|
|
375
561
|
|
|
376
|
-
setDprCap(cap) {
|
|
377
|
-
this.options.dprCap = cap;
|
|
378
|
-
this.resize();
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
562
|
+
setDprCap(cap) {
|
|
563
|
+
this.options.dprCap = cap;
|
|
564
|
+
this.resize();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
setMouseColor(enabled) {
|
|
568
|
+
this.options.mouseColor = enabled !== false;
|
|
569
|
+
if (this.options.mouseColor) {
|
|
570
|
+
if (this.onPointerMove) return this;
|
|
571
|
+
this.#bindEvents();
|
|
572
|
+
return this;
|
|
573
|
+
}
|
|
574
|
+
if (this.onPointerMove) {
|
|
575
|
+
const target = this.eventTarget;
|
|
576
|
+
target.removeEventListener('pointermove', this.onPointerMove);
|
|
577
|
+
target.removeEventListener('pointerdown', this.onPointerMove);
|
|
578
|
+
target.removeEventListener('pointerleave', this.onPointerLeave);
|
|
579
|
+
this.onPointerMove = null;
|
|
580
|
+
this.onPointerLeave = null;
|
|
581
|
+
}
|
|
582
|
+
this.motionTarget = 0;
|
|
583
|
+
return this;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
randomize() {
|
|
382
587
|
this.preset.seed = Math.random() * 100;
|
|
383
588
|
this.timeOffset = Math.random() * 40;
|
|
384
589
|
}
|
|
@@ -458,10 +663,12 @@ class FallbackRenderer {
|
|
|
458
663
|
}
|
|
459
664
|
}
|
|
460
665
|
|
|
461
|
-
drawNebula(time) {
|
|
462
|
-
const ctx = this.context;
|
|
463
|
-
const { width, height } = this.canvas;
|
|
464
|
-
const
|
|
666
|
+
drawNebula(time) {
|
|
667
|
+
const ctx = this.context;
|
|
668
|
+
const { width, height } = this.canvas;
|
|
669
|
+
const t = time * (this.preset.speed || 1);
|
|
670
|
+
const phase = (this.preset.seed || 0) * 0.7;
|
|
671
|
+
const gradient = ctx.createLinearGradient(0, 0, width, height);
|
|
465
672
|
gradient.addColorStop(0, this.preset.colors[0]);
|
|
466
673
|
gradient.addColorStop(0.38, this.preset.colors[1]);
|
|
467
674
|
gradient.addColorStop(0.72, this.preset.colors[2]);
|
|
@@ -469,10 +676,10 @@ class FallbackRenderer {
|
|
|
469
676
|
ctx.fillStyle = gradient;
|
|
470
677
|
ctx.fillRect(0, 0, width, height);
|
|
471
678
|
|
|
472
|
-
ctx.globalCompositeOperation = 'screen';
|
|
473
|
-
for (let index = 0; index < 6; index += 1) {
|
|
474
|
-
const x = (0.5 + 0.45 * Math.sin(
|
|
475
|
-
const y = (0.5 + 0.4 * Math.cos(
|
|
679
|
+
ctx.globalCompositeOperation = 'screen';
|
|
680
|
+
for (let index = 0; index < 6; index += 1) {
|
|
681
|
+
const x = (0.5 + 0.45 * Math.sin(t * 0.32 + index * 1.7 + phase)) * width;
|
|
682
|
+
const y = (0.5 + 0.4 * Math.cos(t * 0.25 + index + phase)) * height;
|
|
476
683
|
const radius = Math.max(width, height) * (0.08 + (index % 3) * 0.04);
|
|
477
684
|
const glow = ctx.createRadialGradient(x, y, 0, x, y, radius);
|
|
478
685
|
glow.addColorStop(0, rgb(this.preset.colors[(index + 1) % 4], 0.24));
|
|
@@ -493,8 +700,11 @@ class FallbackRenderer {
|
|
|
493
700
|
this.preset = preset;
|
|
494
701
|
}
|
|
495
702
|
|
|
496
|
-
randomize() {
|
|
497
|
-
|
|
703
|
+
randomize() {
|
|
704
|
+
if (this.preset) this.preset.seed = Math.random() * 100;
|
|
705
|
+
}
|
|
706
|
+
setMouseColor() {}
|
|
707
|
+
dispose() {}
|
|
498
708
|
}
|
|
499
709
|
|
|
500
710
|
/**
|
|
@@ -594,6 +804,22 @@ function createVisibilityGuard(element) {
|
|
|
594
804
|
};
|
|
595
805
|
}
|
|
596
806
|
|
|
807
|
+
/**
|
|
808
|
+
* Run a callback asynchronously, right after the current task and before the
|
|
809
|
+
* next paint. Used for mount-time events (ready / error) so listeners that
|
|
810
|
+
* are attached after create() still receive them. Falls back for legacy
|
|
811
|
+
* browsers that lack queueMicrotask / Promise.
|
|
812
|
+
*/
|
|
813
|
+
function nextTick(fn) {
|
|
814
|
+
if (typeof queueMicrotask === 'function') {
|
|
815
|
+
queueMicrotask(fn);
|
|
816
|
+
} else if (typeof Promise !== 'undefined' && typeof Promise.resolve === 'function') {
|
|
817
|
+
Promise.resolve().then(fn);
|
|
818
|
+
} else {
|
|
819
|
+
setTimeout(fn, 0);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
597
823
|
function prefersReducedMotion() {
|
|
598
824
|
return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
599
825
|
}
|
|
@@ -616,8 +842,8 @@ function createColorBackground(host, options = {}) {
|
|
|
616
842
|
throw new Error('createColorBackground: host element is required');
|
|
617
843
|
}
|
|
618
844
|
|
|
619
|
-
const preset = { ...getPreset('capsule', options.preset ?? '
|
|
620
|
-
const merged = normalizeOptions(
|
|
845
|
+
const preset = { ...getPreset('capsule', options.preset ?? '初光') };
|
|
846
|
+
const merged = normalizeOptions(
|
|
621
847
|
{
|
|
622
848
|
quality: DEFAULTS.capsule.quality,
|
|
623
849
|
renderer: DEFAULTS.capsule.renderer,
|
|
@@ -627,8 +853,12 @@ function createColorBackground(host, options = {}) {
|
|
|
627
853
|
fallbackColor: true
|
|
628
854
|
},
|
|
629
855
|
preset,
|
|
630
|
-
options
|
|
631
|
-
);
|
|
856
|
+
options
|
|
857
|
+
);
|
|
858
|
+
const normalizedColors = merged.colors.map(normalizeColor);
|
|
859
|
+
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
860
|
+
preset.seed = merged.seed;
|
|
861
|
+
preset.speed = merged.speed;
|
|
632
862
|
|
|
633
863
|
const computed = getComputedStyle(host);
|
|
634
864
|
if (computed.position === 'static' || computed.position === '') {
|
|
@@ -657,8 +887,18 @@ function createColorBackground(host, options = {}) {
|
|
|
657
887
|
layer.appendChild(canvas);
|
|
658
888
|
host.appendChild(layer);
|
|
659
889
|
|
|
660
|
-
const emitter = createEmitter();
|
|
661
|
-
let paused = merged.respectReducedMotion && prefersReducedMotion();
|
|
890
|
+
const emitter = createEmitter();
|
|
891
|
+
let paused = merged.respectReducedMotion && prefersReducedMotion();
|
|
892
|
+
let disposed = false;
|
|
893
|
+
const dirty = {
|
|
894
|
+
preset: false,
|
|
895
|
+
seed: false,
|
|
896
|
+
speed: false,
|
|
897
|
+
colors: false,
|
|
898
|
+
opacity: false,
|
|
899
|
+
fallbackColor: false,
|
|
900
|
+
mouseColor: false
|
|
901
|
+
};
|
|
662
902
|
|
|
663
903
|
let renderer;
|
|
664
904
|
const useWebgl = merged.renderer !== 'canvas2d';
|
|
@@ -671,9 +911,12 @@ function createColorBackground(host, options = {}) {
|
|
|
671
911
|
});
|
|
672
912
|
} catch (error) {
|
|
673
913
|
renderer = new FallbackRenderer(canvas, merged);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
914
|
+
nextTick(() => {
|
|
915
|
+
if (disposed) return;
|
|
916
|
+
emitter.emit('error', {
|
|
917
|
+
message: String(error && error.message ? error.message : error)
|
|
918
|
+
});
|
|
919
|
+
});
|
|
677
920
|
}
|
|
678
921
|
} else {
|
|
679
922
|
renderer = new FallbackRenderer(canvas, merged);
|
|
@@ -697,7 +940,10 @@ function createColorBackground(host, options = {}) {
|
|
|
697
940
|
() => paused
|
|
698
941
|
);
|
|
699
942
|
|
|
700
|
-
|
|
943
|
+
nextTick(() => {
|
|
944
|
+
if (disposed) return;
|
|
945
|
+
emitter.emit('ready', { preset: { ...preset } });
|
|
946
|
+
});
|
|
701
947
|
|
|
702
948
|
return {
|
|
703
949
|
element: host,
|
|
@@ -706,38 +952,72 @@ function createColorBackground(host, options = {}) {
|
|
|
706
952
|
preset,
|
|
707
953
|
on: emitter.on,
|
|
708
954
|
off: emitter.off,
|
|
709
|
-
setPreset(ref) {
|
|
710
|
-
const next = getPreset('capsule', ref);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
return this;
|
|
724
|
-
|
|
955
|
+
setPreset(ref) {
|
|
956
|
+
const next = getPreset('capsule', ref);
|
|
957
|
+
dirty.preset = true;
|
|
958
|
+
Object.assign(preset, next);
|
|
959
|
+
const nextColors = preset.colors.map(normalizeColor);
|
|
960
|
+
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
961
|
+
renderer.setPreset({ ...preset });
|
|
962
|
+
renderer.resize();
|
|
963
|
+
syncLayerVars();
|
|
964
|
+
emitter.emit('presetchange', { preset: { ...preset } });
|
|
965
|
+
return this;
|
|
966
|
+
},
|
|
967
|
+
setColors(colors) {
|
|
968
|
+
const next = Array.isArray(colors) ? colors.map(normalizeColor) : [];
|
|
969
|
+
if (next.length !== 4 || next.some((color) => !color)) return this;
|
|
970
|
+
dirty.colors = true;
|
|
971
|
+
preset.colors = next;
|
|
972
|
+
renderer.setPreset({ ...preset, colors: next });
|
|
973
|
+
syncLayerVars();
|
|
974
|
+
return this;
|
|
975
|
+
},
|
|
976
|
+
setSeed(seed) {
|
|
977
|
+
const value = Number(seed);
|
|
978
|
+
if (!Number.isFinite(value)) return this;
|
|
979
|
+
dirty.seed = true;
|
|
980
|
+
preset.seed = value;
|
|
981
|
+
renderer.setPreset({ ...preset });
|
|
982
|
+
return this;
|
|
983
|
+
},
|
|
984
|
+
setSpeed(speed) {
|
|
985
|
+
const value = Number(speed);
|
|
986
|
+
if (!Number.isFinite(value)) return this;
|
|
987
|
+
dirty.speed = true;
|
|
988
|
+
preset.speed = value;
|
|
989
|
+
renderer.setPreset({ ...preset });
|
|
990
|
+
return this;
|
|
991
|
+
},
|
|
992
|
+
setFallbackColor(value) {
|
|
993
|
+
dirty.fallbackColor = true;
|
|
994
|
+
merged.fallbackColor = value;
|
|
995
|
+
syncLayerVars();
|
|
996
|
+
return this;
|
|
997
|
+
},
|
|
998
|
+
setMouseColor(value) {
|
|
999
|
+
dirty.mouseColor = true;
|
|
1000
|
+
merged.mouseColor = value !== false;
|
|
1001
|
+
if (typeof renderer.setMouseColor === 'function') renderer.setMouseColor(merged.mouseColor);
|
|
1002
|
+
return this;
|
|
1003
|
+
},
|
|
725
1004
|
setQuality(quality) {
|
|
726
1005
|
merged.quality = quality;
|
|
727
1006
|
if (typeof renderer.setDprCap === 'function') renderer.setDprCap(dprCapFor(quality));
|
|
728
1007
|
return this;
|
|
729
1008
|
},
|
|
730
|
-
setOpacity(value) {
|
|
731
|
-
const opacity = Number(value);
|
|
732
|
-
if (!Number.isFinite(opacity)) return this;
|
|
733
|
-
|
|
1009
|
+
setOpacity(value) {
|
|
1010
|
+
const opacity = Number(value);
|
|
1011
|
+
if (!Number.isFinite(opacity)) return this;
|
|
1012
|
+
dirty.opacity = true;
|
|
1013
|
+
merged.opacity = Math.min(1, Math.max(0, opacity));
|
|
734
1014
|
layer.style.setProperty('--dlc-color-opacity', String(merged.opacity));
|
|
735
1015
|
return this;
|
|
736
1016
|
},
|
|
737
|
-
randomize() {
|
|
738
|
-
|
|
739
|
-
return this;
|
|
740
|
-
},
|
|
1017
|
+
randomize() {
|
|
1018
|
+
this.setSeed(Math.random() * 100);
|
|
1019
|
+
return this;
|
|
1020
|
+
},
|
|
741
1021
|
pause() {
|
|
742
1022
|
paused = true;
|
|
743
1023
|
return this;
|
|
@@ -746,15 +1026,20 @@ function createColorBackground(host, options = {}) {
|
|
|
746
1026
|
paused = false;
|
|
747
1027
|
return this;
|
|
748
1028
|
},
|
|
749
|
-
dispose() {
|
|
750
|
-
|
|
1029
|
+
dispose() {
|
|
1030
|
+
disposed = true;
|
|
1031
|
+
unsubscribe();
|
|
751
1032
|
visibility.dispose();
|
|
752
1033
|
if (resizeObserver) resizeObserver.disconnect();
|
|
753
1034
|
else window.removeEventListener('resize', renderer.resize);
|
|
754
|
-
renderer.dispose();
|
|
755
|
-
layer.remove();
|
|
756
|
-
}
|
|
757
|
-
|
|
1035
|
+
renderer.dispose();
|
|
1036
|
+
layer.remove();
|
|
1037
|
+
},
|
|
1038
|
+
opacity: merged.opacity,
|
|
1039
|
+
fallbackColor: merged.fallbackColor,
|
|
1040
|
+
mouseColor: merged.mouseColor,
|
|
1041
|
+
dirty
|
|
1042
|
+
};
|
|
758
1043
|
}
|
|
759
1044
|
|
|
760
1045
|
export { createColorBackground };
|