@5even7/dlc-ui 0.2.2 → 0.2.4
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 +17 -0
- package/README.md +4 -4
- package/dist/capsule.cjs +37 -13
- package/dist/capsule.mjs +46 -20
- package/dist/color.cjs +28 -12
- package/dist/color.mjs +28 -16
- package/dist/index.cjs +97 -58
- package/dist/index.mjs +100 -75
- package/dist/index.umd.js +97 -58
- package/dist/index.umd.min.js +1 -1
- package/dist/progress.cjs +64 -49
- package/dist/progress.mjs +64 -57
- package/dist/vue2.cjs +119 -75
- package/dist/vue2.mjs +115 -85
- package/dist/vue3.cjs +119 -75
- package/dist/vue3.mjs +115 -85
- package/package.json +1 -1
- package/styles/base.css +12 -4
- package/styles/progress.css +4 -0
- package/types/index.d.ts +2 -2
package/dist/index.cjs
CHANGED
|
@@ -417,9 +417,13 @@ function getPreset(kind, ref) {
|
|
|
417
417
|
var list = kind === 'capsule' ? CAPSULE_PRESETS : kind === 'progress' ? PROGRESS_PRESETS : null;
|
|
418
418
|
if (!list) throw new Error("Unknown preset kind: ".concat(kind, " (use \"capsule\" or \"progress\")"));
|
|
419
419
|
var key = String(ref).trim().toLowerCase();
|
|
420
|
-
var found =
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
var found = null;
|
|
421
|
+
for (var index = 0; index < list.length; index += 1) {
|
|
422
|
+
if (list[index].name.toLowerCase() === key) {
|
|
423
|
+
found = list[index];
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
423
427
|
if (!found) throw new Error("Unknown ".concat(kind, " preset: ").concat(ref));
|
|
424
428
|
return found;
|
|
425
429
|
}
|
|
@@ -440,8 +444,8 @@ var DEFAULTS = {
|
|
|
440
444
|
min: 0,
|
|
441
445
|
max: 100,
|
|
442
446
|
draggable: true,
|
|
443
|
-
keyboard: true,
|
|
444
447
|
disabled: false,
|
|
448
|
+
readonly: false,
|
|
445
449
|
valueSuffix: '%',
|
|
446
450
|
edgeStyle: 'flow',
|
|
447
451
|
quality: 'auto',
|
|
@@ -630,7 +634,7 @@ function normalizeRgbArgs(args) {
|
|
|
630
634
|
if (parts.length < 3) return null;
|
|
631
635
|
var to255 = function to255(value) {
|
|
632
636
|
if (typeof value !== 'string' || !value) return null;
|
|
633
|
-
if (value.
|
|
637
|
+
if (value.charAt(value.length - 1) === '%') return clampChannel(parseFloat(value) / 100 * 255);
|
|
634
638
|
var number = Number(value);
|
|
635
639
|
return Number.isFinite(number) ? clampChannel(number) : null;
|
|
636
640
|
};
|
|
@@ -638,9 +642,11 @@ function normalizeRgbArgs(args) {
|
|
|
638
642
|
var green = to255(parts[1]);
|
|
639
643
|
var blue = to255(parts[2]);
|
|
640
644
|
if (red === null || green === null || blue === null) return null;
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
645
|
+
var hex = function hex(n) {
|
|
646
|
+
var text = n.toString(16);
|
|
647
|
+
return text.length === 1 ? "0".concat(text) : text;
|
|
648
|
+
};
|
|
649
|
+
return "#".concat(hex(red)).concat(hex(green)).concat(hex(blue));
|
|
644
650
|
}
|
|
645
651
|
|
|
646
652
|
/**
|
|
@@ -910,6 +916,7 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
910
916
|
this.preset = preset;
|
|
911
917
|
this.context = canvas.getContext('2d');
|
|
912
918
|
this.visible = true;
|
|
919
|
+
this.timePhase = 0;
|
|
913
920
|
}
|
|
914
921
|
return _createClass(FallbackRenderer, [{
|
|
915
922
|
key: "resize",
|
|
@@ -930,7 +937,7 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
930
937
|
var _this$canvas = this.canvas,
|
|
931
938
|
width = _this$canvas.width,
|
|
932
939
|
height = _this$canvas.height;
|
|
933
|
-
var t = time * (this.preset.speed || 1);
|
|
940
|
+
var t = (time + this.timePhase) * (this.preset.speed || 1);
|
|
934
941
|
var phase = (this.preset.seed || 0) * 0.7;
|
|
935
942
|
var gradient = ctx.createLinearGradient(0, 0, width, height);
|
|
936
943
|
gradient.addColorStop(0, this.preset.colors[0]);
|
|
@@ -967,7 +974,10 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
967
974
|
}, {
|
|
968
975
|
key: "randomize",
|
|
969
976
|
value: function randomize() {
|
|
970
|
-
if (this.preset)
|
|
977
|
+
if (this.preset) {
|
|
978
|
+
this.preset.seed = Math.random() * 100;
|
|
979
|
+
this.timePhase = Math.random() * Math.PI * 2;
|
|
980
|
+
}
|
|
971
981
|
}
|
|
972
982
|
}, {
|
|
973
983
|
key: "setMouseColor",
|
|
@@ -1220,6 +1230,8 @@ function createCapsule(container) {
|
|
|
1220
1230
|
}
|
|
1221
1231
|
if (merged.textRatio !== undefined) {
|
|
1222
1232
|
root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
|
|
1233
|
+
var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
|
|
1234
|
+
if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
|
|
1223
1235
|
}
|
|
1224
1236
|
renderer.resize();
|
|
1225
1237
|
};
|
|
@@ -1343,6 +1355,8 @@ function createCapsule(container) {
|
|
|
1343
1355
|
dirty.textRatio = true;
|
|
1344
1356
|
merged.textRatio = value;
|
|
1345
1357
|
root.style.setProperty('--hj-text-width', "".concat(value, "%"));
|
|
1358
|
+
var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
|
|
1359
|
+
if (value === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
|
|
1346
1360
|
return this;
|
|
1347
1361
|
},
|
|
1348
1362
|
setCssVars: function setCssVars(vars) {
|
|
@@ -1361,8 +1375,14 @@ function createCapsule(container) {
|
|
|
1361
1375
|
return this;
|
|
1362
1376
|
},
|
|
1363
1377
|
setSize: function setSize(width, height) {
|
|
1364
|
-
if (width !== undefined)
|
|
1365
|
-
|
|
1378
|
+
if (width !== undefined) {
|
|
1379
|
+
parseSize(width); // 非法尺寸直接抛错前先校验,避免污染内部状态
|
|
1380
|
+
merged.width = width;
|
|
1381
|
+
}
|
|
1382
|
+
if (height !== undefined) {
|
|
1383
|
+
parseSize(height);
|
|
1384
|
+
merged.height = height;
|
|
1385
|
+
}
|
|
1366
1386
|
applySize();
|
|
1367
1387
|
return this;
|
|
1368
1388
|
},
|
|
@@ -1391,8 +1411,12 @@ function createCapsule(container) {
|
|
|
1391
1411
|
renderer.dispose();
|
|
1392
1412
|
root.remove();
|
|
1393
1413
|
},
|
|
1394
|
-
textRatio
|
|
1395
|
-
|
|
1414
|
+
get textRatio() {
|
|
1415
|
+
return merged.textRatio;
|
|
1416
|
+
},
|
|
1417
|
+
get cssVars() {
|
|
1418
|
+
return merged.cssVars;
|
|
1419
|
+
},
|
|
1396
1420
|
dirty: dirty
|
|
1397
1421
|
};
|
|
1398
1422
|
}
|
|
@@ -1688,8 +1712,12 @@ function drawCloud(context, x, y, radiusX, radiusY, color, alpha) {
|
|
|
1688
1712
|
context.translate(x, y);
|
|
1689
1713
|
context.scale(1, radiusY / radiusX);
|
|
1690
1714
|
var gradient = context.createRadialGradient(0, 0, 0, 0, 0, radiusX);
|
|
1691
|
-
|
|
1692
|
-
|
|
1715
|
+
var alphaHex = function alphaHex(value) {
|
|
1716
|
+
var text = Math.round(value).toString(16);
|
|
1717
|
+
return text.length === 1 ? "0".concat(text) : text;
|
|
1718
|
+
};
|
|
1719
|
+
gradient.addColorStop(0, "".concat(color).concat(alphaHex(alpha * 255)));
|
|
1720
|
+
gradient.addColorStop(0.46, "".concat(color).concat(alphaHex(alpha * 0.42 * 255)));
|
|
1693
1721
|
gradient.addColorStop(1, "".concat(color, "00"));
|
|
1694
1722
|
context.fillStyle = gradient;
|
|
1695
1723
|
context.fillRect(-radiusX, -radiusX, radiusX * 2, radiusX * 2);
|
|
@@ -2139,6 +2167,11 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2139
2167
|
}, {
|
|
2140
2168
|
key: "setRange",
|
|
2141
2169
|
value: function setRange(min, max) {
|
|
2170
|
+
if (min > max) {
|
|
2171
|
+
var swap = min;
|
|
2172
|
+
min = max;
|
|
2173
|
+
max = swap;
|
|
2174
|
+
}
|
|
2142
2175
|
this.min = min;
|
|
2143
2176
|
this.max = max;
|
|
2144
2177
|
var clamped = clamp(this.value, this.min, this.max);
|
|
@@ -2274,6 +2307,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2274
2307
|
value: function beginDrag(event) {
|
|
2275
2308
|
if (event.button !== undefined && event.button !== 0) return;
|
|
2276
2309
|
event.preventDefault();
|
|
2310
|
+
// preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
|
|
2311
|
+
try {
|
|
2312
|
+
this.root.focus({
|
|
2313
|
+
preventScroll: true
|
|
2314
|
+
});
|
|
2315
|
+
} catch (_unused) {
|
|
2316
|
+
this.root.focus();
|
|
2317
|
+
}
|
|
2277
2318
|
this.dragging = true;
|
|
2278
2319
|
this.pendingPointer = null;
|
|
2279
2320
|
this._dragRaf = 0;
|
|
@@ -2281,7 +2322,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2281
2322
|
try {
|
|
2282
2323
|
var _this$root$setPointer, _this$root;
|
|
2283
2324
|
(_this$root$setPointer = (_this$root = this.root).setPointerCapture) === null || _this$root$setPointer === void 0 || _this$root$setPointer.call(_this$root, event.pointerId);
|
|
2284
|
-
} catch (
|
|
2325
|
+
} catch (_unused2) {}
|
|
2285
2326
|
this.emitter.emit('dragstart', {
|
|
2286
2327
|
value: this.value
|
|
2287
2328
|
});
|
|
@@ -2321,7 +2362,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2321
2362
|
if ((event === null || event === void 0 ? void 0 : event.pointerId) !== undefined && (_this$root$hasPointer = (_this$root2 = this.root).hasPointerCapture) !== null && _this$root$hasPointer !== void 0 && _this$root$hasPointer.call(_this$root2, event.pointerId)) {
|
|
2322
2363
|
this.root.releasePointerCapture(event.pointerId);
|
|
2323
2364
|
}
|
|
2324
|
-
} catch (
|
|
2365
|
+
} catch (_unused3) {}
|
|
2325
2366
|
this.emitter.emit('dragend', {
|
|
2326
2367
|
value: this.value
|
|
2327
2368
|
});
|
|
@@ -2348,32 +2389,6 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2348
2389
|
this.root.addEventListener('pointerup', this.handlers.pointerup);
|
|
2349
2390
|
this.root.addEventListener('pointercancel', this.handlers.pointercancel);
|
|
2350
2391
|
}
|
|
2351
|
-
if (this.options.keyboard !== false) {
|
|
2352
|
-
this.handlers.keydown = function (event) {
|
|
2353
|
-
var step = (_this3.max - _this3.min) * 0.02;
|
|
2354
|
-
var actions = {
|
|
2355
|
-
ArrowLeft: -step,
|
|
2356
|
-
ArrowDown: -step,
|
|
2357
|
-
ArrowRight: step,
|
|
2358
|
-
ArrowUp: step,
|
|
2359
|
-
PageDown: -step * 5,
|
|
2360
|
-
PageUp: step * 5
|
|
2361
|
-
};
|
|
2362
|
-
if (event.key === 'Home') {
|
|
2363
|
-
event.preventDefault();
|
|
2364
|
-
_this3.setProgress(_this3.min, 'keyboard');
|
|
2365
|
-
} else if (event.key === 'End') {
|
|
2366
|
-
event.preventDefault();
|
|
2367
|
-
_this3.setProgress(_this3.max, 'keyboard');
|
|
2368
|
-
} else if (actions[event.key]) {
|
|
2369
|
-
event.preventDefault();
|
|
2370
|
-
_this3.setProgress(_this3.value + actions[event.key], 'keyboard');
|
|
2371
|
-
} else {
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
};
|
|
2375
|
-
this.root.addEventListener('keydown', this.handlers.keydown);
|
|
2376
|
-
}
|
|
2377
2392
|
}
|
|
2378
2393
|
}, {
|
|
2379
2394
|
key: "update",
|
|
@@ -2420,7 +2435,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2420
2435
|
* Mount a fluid progress capsule into `container`.
|
|
2421
2436
|
*
|
|
2422
2437
|
* Options: preset (id/code/name or object), width, height, value, min, max,
|
|
2423
|
-
* draggable,
|
|
2438
|
+
* draggable, colors, edgeStyle, textRatio (0-100, text region
|
|
2424
2439
|
* width in percent), text (HTML string or DOM nodes for the text slot),
|
|
2425
2440
|
* colorContent (HTML string or DOM nodes for the color slot),
|
|
2426
2441
|
* showValue (show/hide the right-side percentage), quality,
|
|
@@ -2434,6 +2449,11 @@ function createProgressCapsule(container) {
|
|
|
2434
2449
|
}
|
|
2435
2450
|
var preset = _objectSpread2({}, getPreset('progress', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '星火'));
|
|
2436
2451
|
var merged = normalizeOptions(DEFAULTS.progress, preset, options);
|
|
2452
|
+
if (merged.min > merged.max) {
|
|
2453
|
+
var swap = merged.min;
|
|
2454
|
+
merged.min = merged.max;
|
|
2455
|
+
merged.max = swap;
|
|
2456
|
+
}
|
|
2437
2457
|
var normalizedColors = merged.colors.map(normalizeColor);
|
|
2438
2458
|
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
2439
2459
|
preset.edgeStyle = merged.edgeStyle;
|
|
@@ -2442,8 +2462,9 @@ function createProgressCapsule(container) {
|
|
|
2442
2462
|
// Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
|
|
2443
2463
|
// 这里统一按 true 处理。
|
|
2444
2464
|
var disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
|
|
2445
|
-
var
|
|
2446
|
-
var
|
|
2465
|
+
var readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
|
|
2466
|
+
var locked = disabled || readonly;
|
|
2467
|
+
var effectiveDraggable = locked ? false : merged.draggable !== false;
|
|
2447
2468
|
var dirty = {
|
|
2448
2469
|
preset: false,
|
|
2449
2470
|
colors: false,
|
|
@@ -2455,12 +2476,16 @@ function createProgressCapsule(container) {
|
|
|
2455
2476
|
var root = document.createElement('div');
|
|
2456
2477
|
root.className = 'hj-capsule-root hj-progress-root';
|
|
2457
2478
|
root.setAttribute('role', 'slider');
|
|
2458
|
-
root.setAttribute('tabindex', '0');
|
|
2459
2479
|
root.setAttribute('data-draggable', String(effectiveDraggable));
|
|
2460
2480
|
if (disabled) {
|
|
2461
2481
|
root.setAttribute('aria-disabled', 'true');
|
|
2462
2482
|
root.classList.add('is-disabled');
|
|
2463
2483
|
}
|
|
2484
|
+
if (readonly) {
|
|
2485
|
+
root.setAttribute('aria-readonly', 'true');
|
|
2486
|
+
root.classList.add('is-readonly');
|
|
2487
|
+
}
|
|
2488
|
+
if (locked) root.setAttribute('tabindex', '-1');
|
|
2464
2489
|
root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
|
|
2465
2490
|
root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
|
|
2466
2491
|
root.setAttribute('aria-valuenow', String(preset.initialProgress));
|
|
@@ -2472,7 +2497,6 @@ function createProgressCapsule(container) {
|
|
|
2472
2497
|
}));
|
|
2473
2498
|
};
|
|
2474
2499
|
updateAria();
|
|
2475
|
-
if (!effectiveKeyboard) root.setAttribute('tabindex', '-1');
|
|
2476
2500
|
var canvas = document.createElement('canvas');
|
|
2477
2501
|
canvas.className = 'hj-progress-canvas';
|
|
2478
2502
|
canvas.setAttribute('aria-hidden', 'true');
|
|
@@ -2539,8 +2563,7 @@ function createProgressCapsule(container) {
|
|
|
2539
2563
|
preset: preset,
|
|
2540
2564
|
emitter: emitter,
|
|
2541
2565
|
options: _objectSpread2(_objectSpread2({}, merged), {}, {
|
|
2542
|
-
draggable: effectiveDraggable
|
|
2543
|
-
keyboard: effectiveKeyboard
|
|
2566
|
+
draggable: effectiveDraggable
|
|
2544
2567
|
}),
|
|
2545
2568
|
copy: copy,
|
|
2546
2569
|
dirty: dirty
|
|
@@ -2700,8 +2723,14 @@ function createProgressCapsule(container) {
|
|
|
2700
2723
|
return this;
|
|
2701
2724
|
},
|
|
2702
2725
|
setSize: function setSize(width, height) {
|
|
2703
|
-
if (width !== undefined)
|
|
2704
|
-
|
|
2726
|
+
if (width !== undefined) {
|
|
2727
|
+
parseSize(width);
|
|
2728
|
+
merged.width = width;
|
|
2729
|
+
}
|
|
2730
|
+
if (height !== undefined) {
|
|
2731
|
+
parseSize(height);
|
|
2732
|
+
merged.height = height;
|
|
2733
|
+
}
|
|
2705
2734
|
applySize();
|
|
2706
2735
|
controller.resizeCanvas();
|
|
2707
2736
|
return this;
|
|
@@ -2732,8 +2761,12 @@ function createProgressCapsule(container) {
|
|
|
2732
2761
|
controller.dispose();
|
|
2733
2762
|
root.remove();
|
|
2734
2763
|
},
|
|
2735
|
-
textRatio
|
|
2736
|
-
|
|
2764
|
+
get textRatio() {
|
|
2765
|
+
return merged.textRatio;
|
|
2766
|
+
},
|
|
2767
|
+
get cssVars() {
|
|
2768
|
+
return merged.cssVars;
|
|
2769
|
+
},
|
|
2737
2770
|
dirty: dirty
|
|
2738
2771
|
};
|
|
2739
2772
|
}
|
|
@@ -2938,9 +2971,15 @@ function createColorBackground(host) {
|
|
|
2938
2971
|
renderer.dispose();
|
|
2939
2972
|
layer.remove();
|
|
2940
2973
|
},
|
|
2941
|
-
opacity
|
|
2942
|
-
|
|
2943
|
-
|
|
2974
|
+
get opacity() {
|
|
2975
|
+
return merged.opacity;
|
|
2976
|
+
},
|
|
2977
|
+
get fallbackColor() {
|
|
2978
|
+
return merged.fallbackColor;
|
|
2979
|
+
},
|
|
2980
|
+
get mouseColor() {
|
|
2981
|
+
return merged.mouseColor;
|
|
2982
|
+
},
|
|
2944
2983
|
dirty: dirty
|
|
2945
2984
|
};
|
|
2946
2985
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -176,9 +176,13 @@ function getPreset(kind, ref) {
|
|
|
176
176
|
const list = kind === 'capsule' ? CAPSULE_PRESETS : kind === 'progress' ? PROGRESS_PRESETS : null;
|
|
177
177
|
if (!list) throw new Error(`Unknown preset kind: ${kind} (use "capsule" or "progress")`);
|
|
178
178
|
const key = String(ref).trim().toLowerCase();
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
let found = null;
|
|
180
|
+
for (let index = 0; index < list.length; index += 1) {
|
|
181
|
+
if (list[index].name.toLowerCase() === key) {
|
|
182
|
+
found = list[index];
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
182
186
|
if (!found) throw new Error(`Unknown ${kind} preset: ${ref}`);
|
|
183
187
|
return found;
|
|
184
188
|
}
|
|
@@ -197,10 +201,10 @@ const DEFAULTS = {
|
|
|
197
201
|
width: 454,
|
|
198
202
|
height: 104,
|
|
199
203
|
min: 0,
|
|
200
|
-
max: 100,
|
|
204
|
+
max: 100,
|
|
201
205
|
draggable: true,
|
|
202
|
-
keyboard: true,
|
|
203
206
|
disabled: false,
|
|
207
|
+
readonly: false,
|
|
204
208
|
valueSuffix: '%',
|
|
205
209
|
edgeStyle: 'flow',
|
|
206
210
|
quality: 'auto',
|
|
@@ -391,7 +395,7 @@ function normalizeRgbArgs(args) {
|
|
|
391
395
|
if (parts.length < 3) return null;
|
|
392
396
|
const to255 = (value) => {
|
|
393
397
|
if (typeof value !== 'string' || !value) return null;
|
|
394
|
-
if (value.
|
|
398
|
+
if (value.charAt(value.length - 1) === '%') return clampChannel((parseFloat(value) / 100) * 255);
|
|
395
399
|
const number = Number(value);
|
|
396
400
|
return Number.isFinite(number) ? clampChannel(number) : null;
|
|
397
401
|
};
|
|
@@ -399,7 +403,11 @@ function normalizeRgbArgs(args) {
|
|
|
399
403
|
const green = to255(parts[1]);
|
|
400
404
|
const blue = to255(parts[2]);
|
|
401
405
|
if (red === null || green === null || blue === null) return null;
|
|
402
|
-
|
|
406
|
+
const hex = (n) => {
|
|
407
|
+
const text = n.toString(16);
|
|
408
|
+
return text.length === 1 ? `0${text}` : text;
|
|
409
|
+
};
|
|
410
|
+
return `#${hex(red)}${hex(green)}${hex(blue)}`;
|
|
403
411
|
}
|
|
404
412
|
|
|
405
413
|
/**
|
|
@@ -762,12 +770,13 @@ function rgb(color, alpha = 1) {
|
|
|
762
770
|
}
|
|
763
771
|
|
|
764
772
|
class FallbackRenderer {
|
|
765
|
-
constructor(canvas, preset) {
|
|
766
|
-
this.canvas = canvas;
|
|
767
|
-
this.preset = preset;
|
|
768
|
-
this.context = canvas.getContext('2d');
|
|
769
|
-
this.visible = true;
|
|
770
|
-
|
|
773
|
+
constructor(canvas, preset) {
|
|
774
|
+
this.canvas = canvas;
|
|
775
|
+
this.preset = preset;
|
|
776
|
+
this.context = canvas.getContext('2d');
|
|
777
|
+
this.visible = true;
|
|
778
|
+
this.timePhase = 0;
|
|
779
|
+
}
|
|
771
780
|
|
|
772
781
|
resize() {
|
|
773
782
|
const rect = this.canvas.getBoundingClientRect();
|
|
@@ -783,7 +792,7 @@ class FallbackRenderer {
|
|
|
783
792
|
drawNebula(time) {
|
|
784
793
|
const ctx = this.context;
|
|
785
794
|
const { width, height } = this.canvas;
|
|
786
|
-
const t = time * (this.preset.speed || 1);
|
|
795
|
+
const t = (time + this.timePhase) * (this.preset.speed || 1);
|
|
787
796
|
const phase = (this.preset.seed || 0) * 0.7;
|
|
788
797
|
const gradient = ctx.createLinearGradient(0, 0, width, height);
|
|
789
798
|
gradient.addColorStop(0, this.preset.colors[0]);
|
|
@@ -818,7 +827,10 @@ class FallbackRenderer {
|
|
|
818
827
|
}
|
|
819
828
|
|
|
820
829
|
randomize() {
|
|
821
|
-
if (this.preset)
|
|
830
|
+
if (this.preset) {
|
|
831
|
+
this.preset.seed = Math.random() * 100;
|
|
832
|
+
this.timePhase = Math.random() * Math.PI * 2;
|
|
833
|
+
}
|
|
822
834
|
}
|
|
823
835
|
setMouseColor() {}
|
|
824
836
|
dispose() {}
|
|
@@ -1053,6 +1065,10 @@ function createCapsule(container, options = {}) {
|
|
|
1053
1065
|
for (const name of Object.keys(vars)) root.style.setProperty(name, vars[name]);
|
|
1054
1066
|
if (merged.textRatio !== undefined) {
|
|
1055
1067
|
root.style.setProperty('--hj-text-width', `${merged.textRatio}%`);
|
|
1068
|
+
const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
|
|
1069
|
+
if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');
|
|
1070
|
+
else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
|
|
1071
|
+
else root.style.removeProperty('--hj-text-min-width');
|
|
1056
1072
|
}
|
|
1057
1073
|
renderer.resize();
|
|
1058
1074
|
};
|
|
@@ -1151,6 +1167,10 @@ function createCapsule(container, options = {}) {
|
|
|
1151
1167
|
dirty.textRatio = true;
|
|
1152
1168
|
merged.textRatio = value;
|
|
1153
1169
|
root.style.setProperty('--hj-text-width', `${value}%`);
|
|
1170
|
+
const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
|
|
1171
|
+
if (value === 0) root.style.setProperty('--hj-text-min-width', '0');
|
|
1172
|
+
else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
|
|
1173
|
+
else root.style.removeProperty('--hj-text-min-width');
|
|
1154
1174
|
return this;
|
|
1155
1175
|
},
|
|
1156
1176
|
setCssVars(vars) {
|
|
@@ -1166,11 +1186,17 @@ function createCapsule(container, options = {}) {
|
|
|
1166
1186
|
return this;
|
|
1167
1187
|
},
|
|
1168
1188
|
setSize(width, height) {
|
|
1169
|
-
if (width !== undefined)
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1189
|
+
if (width !== undefined) {
|
|
1190
|
+
parseSize(width); // 非法尺寸直接抛错前先校验,避免污染内部状态
|
|
1191
|
+
merged.width = width;
|
|
1192
|
+
}
|
|
1193
|
+
if (height !== undefined) {
|
|
1194
|
+
parseSize(height);
|
|
1195
|
+
merged.height = height;
|
|
1196
|
+
}
|
|
1197
|
+
applySize();
|
|
1198
|
+
return this;
|
|
1199
|
+
},
|
|
1174
1200
|
randomize() {
|
|
1175
1201
|
this.setSeed(Math.random() * 100);
|
|
1176
1202
|
return this;
|
|
@@ -1197,8 +1223,8 @@ function createCapsule(container, options = {}) {
|
|
|
1197
1223
|
renderer.dispose();
|
|
1198
1224
|
root.remove();
|
|
1199
1225
|
},
|
|
1200
|
-
textRatio
|
|
1201
|
-
cssVars
|
|
1226
|
+
get textRatio() { return merged.textRatio; },
|
|
1227
|
+
get cssVars() { return merged.cssVars; },
|
|
1202
1228
|
dirty
|
|
1203
1229
|
};
|
|
1204
1230
|
}
|
|
@@ -1683,13 +1709,17 @@ const PALETTES = {
|
|
|
1683
1709
|
'tide': ['#0a2239', '#2e9bff', '#7fe3ff', '#eaf9ff']
|
|
1684
1710
|
};
|
|
1685
1711
|
|
|
1686
|
-
function drawCloud(context, x, y, radiusX, radiusY, color, alpha) {
|
|
1687
|
-
context.save();
|
|
1688
|
-
context.translate(x, y);
|
|
1689
|
-
context.scale(1, radiusY / radiusX);
|
|
1690
|
-
const gradient = context.createRadialGradient(0, 0, 0, 0, 0, radiusX);
|
|
1691
|
-
|
|
1692
|
-
|
|
1712
|
+
function drawCloud(context, x, y, radiusX, radiusY, color, alpha) {
|
|
1713
|
+
context.save();
|
|
1714
|
+
context.translate(x, y);
|
|
1715
|
+
context.scale(1, radiusY / radiusX);
|
|
1716
|
+
const gradient = context.createRadialGradient(0, 0, 0, 0, 0, radiusX);
|
|
1717
|
+
const alphaHex = (value) => {
|
|
1718
|
+
const text = Math.round(value).toString(16);
|
|
1719
|
+
return text.length === 1 ? `0${text}` : text;
|
|
1720
|
+
};
|
|
1721
|
+
gradient.addColorStop(0, `${color}${alphaHex(alpha * 255)}`);
|
|
1722
|
+
gradient.addColorStop(0.46, `${color}${alphaHex(alpha * 0.42 * 255)}`);
|
|
1693
1723
|
gradient.addColorStop(1, `${color}00`);
|
|
1694
1724
|
context.fillStyle = gradient;
|
|
1695
1725
|
context.fillRect(-radiusX, -radiusX, radiusX * 2, radiusX * 2);
|
|
@@ -2119,9 +2149,14 @@ class ProgressCapsuleController {
|
|
|
2119
2149
|
ctx.restore();
|
|
2120
2150
|
}
|
|
2121
2151
|
|
|
2122
|
-
setRange(min, max) {
|
|
2123
|
-
|
|
2124
|
-
|
|
2152
|
+
setRange(min, max) {
|
|
2153
|
+
if (min > max) {
|
|
2154
|
+
const swap = min;
|
|
2155
|
+
min = max;
|
|
2156
|
+
max = swap;
|
|
2157
|
+
}
|
|
2158
|
+
this.min = min;
|
|
2159
|
+
this.max = max;
|
|
2125
2160
|
const clamped = clamp(this.value, this.min, this.max);
|
|
2126
2161
|
if (clamped !== this.value) this.setProgress(clamped, 'prop');
|
|
2127
2162
|
}
|
|
@@ -2260,6 +2295,8 @@ class ProgressCapsuleController {
|
|
|
2260
2295
|
beginDrag(event) {
|
|
2261
2296
|
if (event.button !== undefined && event.button !== 0) return;
|
|
2262
2297
|
event.preventDefault();
|
|
2298
|
+
// preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
|
|
2299
|
+
try { this.root.focus({ preventScroll: true }); } catch { this.root.focus(); }
|
|
2263
2300
|
this.dragging = true;
|
|
2264
2301
|
this.pendingPointer = null;
|
|
2265
2302
|
this._dragRaf = 0;
|
|
@@ -2314,33 +2351,7 @@ class ProgressCapsuleController {
|
|
|
2314
2351
|
this.root.addEventListener('pointercancel', this.handlers.pointercancel);
|
|
2315
2352
|
}
|
|
2316
2353
|
|
|
2317
|
-
|
|
2318
|
-
this.handlers.keydown = (event) => {
|
|
2319
|
-
const step = (this.max - this.min) * 0.02;
|
|
2320
|
-
const actions = {
|
|
2321
|
-
ArrowLeft: -step,
|
|
2322
|
-
ArrowDown: -step,
|
|
2323
|
-
ArrowRight: step,
|
|
2324
|
-
ArrowUp: step,
|
|
2325
|
-
PageDown: -step * 5,
|
|
2326
|
-
PageUp: step * 5
|
|
2327
|
-
};
|
|
2328
|
-
if (event.key === 'Home') {
|
|
2329
|
-
event.preventDefault();
|
|
2330
|
-
this.setProgress(this.min, 'keyboard');
|
|
2331
|
-
} else if (event.key === 'End') {
|
|
2332
|
-
event.preventDefault();
|
|
2333
|
-
this.setProgress(this.max, 'keyboard');
|
|
2334
|
-
} else if (actions[event.key]) {
|
|
2335
|
-
event.preventDefault();
|
|
2336
|
-
this.setProgress(this.value + actions[event.key], 'keyboard');
|
|
2337
|
-
} else {
|
|
2338
|
-
return;
|
|
2339
|
-
}
|
|
2340
|
-
};
|
|
2341
|
-
this.root.addEventListener('keydown', this.handlers.keydown);
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2354
|
+
}
|
|
2344
2355
|
|
|
2345
2356
|
update(delta, paused) {
|
|
2346
2357
|
if (!paused) this.flowTime += delta;
|
|
@@ -2378,7 +2389,7 @@ class ProgressCapsuleController {
|
|
|
2378
2389
|
* Mount a fluid progress capsule into `container`.
|
|
2379
2390
|
*
|
|
2380
2391
|
* Options: preset (id/code/name or object), width, height, value, min, max,
|
|
2381
|
-
* draggable,
|
|
2392
|
+
* draggable, colors, edgeStyle, textRatio (0-100, text region
|
|
2382
2393
|
* width in percent), text (HTML string or DOM nodes for the text slot),
|
|
2383
2394
|
* colorContent (HTML string or DOM nodes for the color slot),
|
|
2384
2395
|
* showValue (show/hide the right-side percentage), quality,
|
|
@@ -2391,6 +2402,11 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2391
2402
|
|
|
2392
2403
|
const preset = { ...getPreset('progress', options.preset ?? '星火') };
|
|
2393
2404
|
const merged = normalizeOptions(DEFAULTS.progress, preset, options);
|
|
2405
|
+
if (merged.min > merged.max) {
|
|
2406
|
+
const swap = merged.min;
|
|
2407
|
+
merged.min = merged.max;
|
|
2408
|
+
merged.max = swap;
|
|
2409
|
+
}
|
|
2394
2410
|
const normalizedColors = merged.colors.map(normalizeColor);
|
|
2395
2411
|
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
2396
2412
|
preset.edgeStyle = merged.edgeStyle;
|
|
@@ -2399,8 +2415,9 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2399
2415
|
// Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
|
|
2400
2416
|
// 这里统一按 true 处理。
|
|
2401
2417
|
const disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
|
|
2402
|
-
const
|
|
2403
|
-
const
|
|
2418
|
+
const readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
|
|
2419
|
+
const locked = disabled || readonly;
|
|
2420
|
+
const effectiveDraggable = locked ? false : merged.draggable !== false;
|
|
2404
2421
|
const dirty = {
|
|
2405
2422
|
preset: false,
|
|
2406
2423
|
colors: false,
|
|
@@ -2413,12 +2430,16 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2413
2430
|
const root = document.createElement('div');
|
|
2414
2431
|
root.className = 'hj-capsule-root hj-progress-root';
|
|
2415
2432
|
root.setAttribute('role', 'slider');
|
|
2416
|
-
root.setAttribute('tabindex', '0');
|
|
2417
2433
|
root.setAttribute('data-draggable', String(effectiveDraggable));
|
|
2418
2434
|
if (disabled) {
|
|
2419
2435
|
root.setAttribute('aria-disabled', 'true');
|
|
2420
2436
|
root.classList.add('is-disabled');
|
|
2421
2437
|
}
|
|
2438
|
+
if (readonly) {
|
|
2439
|
+
root.setAttribute('aria-readonly', 'true');
|
|
2440
|
+
root.classList.add('is-readonly');
|
|
2441
|
+
}
|
|
2442
|
+
if (locked) root.setAttribute('tabindex', '-1');
|
|
2422
2443
|
root.setAttribute('aria-valuemin', String(merged.min ?? 0));
|
|
2423
2444
|
root.setAttribute('aria-valuemax', String(merged.max ?? 100));
|
|
2424
2445
|
root.setAttribute('aria-valuenow', String(preset.initialProgress));
|
|
@@ -2429,8 +2450,6 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2429
2450
|
);
|
|
2430
2451
|
};
|
|
2431
2452
|
updateAria();
|
|
2432
|
-
if (!effectiveKeyboard) root.setAttribute('tabindex', '-1');
|
|
2433
|
-
|
|
2434
2453
|
const canvas = document.createElement('canvas');
|
|
2435
2454
|
canvas.className = 'hj-progress-canvas';
|
|
2436
2455
|
canvas.setAttribute('aria-hidden', 'true');
|
|
@@ -2492,7 +2511,7 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2492
2511
|
valueElement,
|
|
2493
2512
|
preset,
|
|
2494
2513
|
emitter,
|
|
2495
|
-
options: { ...merged, draggable: effectiveDraggable
|
|
2514
|
+
options: { ...merged, draggable: effectiveDraggable },
|
|
2496
2515
|
copy,
|
|
2497
2516
|
dirty
|
|
2498
2517
|
});
|
|
@@ -2633,10 +2652,16 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2633
2652
|
controller.resizeCanvas();
|
|
2634
2653
|
return this;
|
|
2635
2654
|
},
|
|
2636
|
-
setSize(width, height) {
|
|
2637
|
-
if (width !== undefined)
|
|
2638
|
-
|
|
2639
|
-
|
|
2655
|
+
setSize(width, height) {
|
|
2656
|
+
if (width !== undefined) {
|
|
2657
|
+
parseSize(width);
|
|
2658
|
+
merged.width = width;
|
|
2659
|
+
}
|
|
2660
|
+
if (height !== undefined) {
|
|
2661
|
+
parseSize(height);
|
|
2662
|
+
merged.height = height;
|
|
2663
|
+
}
|
|
2664
|
+
applySize();
|
|
2640
2665
|
controller.resizeCanvas();
|
|
2641
2666
|
return this;
|
|
2642
2667
|
},
|
|
@@ -2666,8 +2691,8 @@ function createProgressCapsule(container, options = {}) {
|
|
|
2666
2691
|
controller.dispose();
|
|
2667
2692
|
root.remove();
|
|
2668
2693
|
},
|
|
2669
|
-
textRatio
|
|
2670
|
-
cssVars
|
|
2694
|
+
get textRatio() { return merged.textRatio; },
|
|
2695
|
+
get cssVars() { return merged.cssVars; },
|
|
2671
2696
|
dirty
|
|
2672
2697
|
};
|
|
2673
2698
|
}
|
|
@@ -2887,9 +2912,9 @@ function createColorBackground(host, options = {}) {
|
|
|
2887
2912
|
renderer.dispose();
|
|
2888
2913
|
layer.remove();
|
|
2889
2914
|
},
|
|
2890
|
-
opacity
|
|
2891
|
-
fallbackColor
|
|
2892
|
-
mouseColor
|
|
2915
|
+
get opacity() { return merged.opacity; },
|
|
2916
|
+
get fallbackColor() { return merged.fallbackColor; },
|
|
2917
|
+
get mouseColor() { return merged.mouseColor; },
|
|
2893
2918
|
dirty
|
|
2894
2919
|
};
|
|
2895
2920
|
}
|