@5even7/dlc-ui 0.2.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/dist/vue2.cjs CHANGED
@@ -148,6 +148,9 @@ function _objectSpread2(e) {
148
148
  }
149
149
  return e;
150
150
  }
151
+ function _readOnlyError(r) {
152
+ throw new TypeError('"' + r + '" is read-only');
153
+ }
151
154
  function _slicedToArray(r, e) {
152
155
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
153
156
  }
@@ -431,7 +434,7 @@ var DEFAULTS = {
431
434
  renderer: 'auto',
432
435
  respectReducedMotion: true,
433
436
  mouseColor: true,
434
- showCopy: true
437
+ textRatio: 39
435
438
  },
436
439
  progress: {
437
440
  width: 454,
@@ -440,35 +443,242 @@ var DEFAULTS = {
440
443
  max: 100,
441
444
  draggable: true,
442
445
  keyboard: true,
446
+ disabled: false,
447
+ valueSuffix: '%',
443
448
  edgeStyle: 'flow',
444
449
  quality: 'auto',
445
450
  renderer: 'auto',
446
- showCopy: true,
451
+ textRatio: 54,
452
+ showValue: true,
447
453
  respectReducedMotion: true
448
454
  }
449
455
  };
450
456
 
451
- /**
452
- * All user-facing copy lives here so wording/brand changes never require a
453
- * global search. Templates use {brand} {code} {name} placeholders.
457
+ /**
458
+ * Internal accessibility labels and small UI text. Since the copy API was
459
+ * removed (slots own the text area), these are no longer user-overridable.
460
+ * Templates use {brand} {code} {name} placeholders.
454
461
  */
455
462
  var COPY = {
456
463
  brandName: '画境观屿',
457
- dragLabel: 'DRAG',
458
464
  valueSuffix: '%',
459
465
  progressAria: '{brand} {code} 加载进度',
460
466
  capsuleAria: '打开 {name} 沉浸预览'
461
467
  };
462
468
 
463
- function hexToRgb01$1(hex) {
464
- var normalized = hex.replace('#', '');
465
- var value = Number.parseInt(normalized, 16);
469
+ /**
470
+ * Color helpers. `normalizeColor` converts any supported CSS color
471
+ * (hex / named / rgb() / rgba()) into a 6-digit hex string, so renderers can
472
+ * keep working with #rrggbb only. rgba() alpha is intentionally dropped:
473
+ * the WebGL shader has no per-color alpha channel, and the component is
474
+ * opaque by design — use component-level `opacity` for transparency.
475
+ */
476
+
477
+ var NAMED_COLORS = {
478
+ aliceblue: '#f0f8ff',
479
+ antiquewhite: '#faebd7',
480
+ aqua: '#00ffff',
481
+ aquamarine: '#7fffd4',
482
+ azure: '#f0ffff',
483
+ beige: '#f5f5dc',
484
+ bisque: '#ffe4c4',
485
+ black: '#000000',
486
+ blanchedalmond: '#ffebcd',
487
+ blue: '#0000ff',
488
+ blueviolet: '#8a2be2',
489
+ brown: '#a52a2a',
490
+ burlywood: '#deb887',
491
+ cadetblue: '#5f9ea0',
492
+ chartreuse: '#7fff00',
493
+ chocolate: '#d2691e',
494
+ coral: '#ff7f50',
495
+ cornflowerblue: '#6495ed',
496
+ cornsilk: '#fff8dc',
497
+ crimson: '#dc143c',
498
+ cyan: '#00ffff',
499
+ darkblue: '#00008b',
500
+ darkcyan: '#008b8b',
501
+ darkgoldenrod: '#b8860b',
502
+ darkgray: '#a9a9a9',
503
+ darkgreen: '#006400',
504
+ darkgrey: '#a9a9a9',
505
+ darkkhaki: '#bdb76b',
506
+ darkmagenta: '#8b008b',
507
+ darkolivegreen: '#556b2f',
508
+ darkorange: '#ff8c00',
509
+ darkorchid: '#9932cc',
510
+ darkred: '#8b0000',
511
+ darksalmon: '#e9967a',
512
+ darkseagreen: '#8fbc8f',
513
+ darkslateblue: '#483d8b',
514
+ darkslategray: '#2f4f4f',
515
+ darkslategrey: '#2f4f4f',
516
+ darkturquoise: '#00ced1',
517
+ darkviolet: '#9400d3',
518
+ deeppink: '#ff1493',
519
+ deepskyblue: '#00bfff',
520
+ dimgray: '#696969',
521
+ dimgrey: '#696969',
522
+ dodgerblue: '#1e90ff',
523
+ firebrick: '#b22222',
524
+ floralwhite: '#fffaf0',
525
+ forestgreen: '#228b22',
526
+ fuchsia: '#ff00ff',
527
+ gainsboro: '#dcdcdc',
528
+ ghostwhite: '#f8f8ff',
529
+ gold: '#ffd700',
530
+ goldenrod: '#daa520',
531
+ gray: '#808080',
532
+ green: '#008000',
533
+ greenyellow: '#adff2f',
534
+ grey: '#808080',
535
+ honeydew: '#f0fff0',
536
+ hotpink: '#ff69b4',
537
+ indianred: '#cd5c5c',
538
+ indigo: '#4b0082',
539
+ ivory: '#fffff0',
540
+ khaki: '#f0e68c',
541
+ lavender: '#e6e6fa',
542
+ lavenderblush: '#fff0f5',
543
+ lawngreen: '#7cfc00',
544
+ lemonchiffon: '#fffacd',
545
+ lightblue: '#add8e6',
546
+ lightcoral: '#f08080',
547
+ lightcyan: '#e0ffff',
548
+ lightgoldenrodyellow: '#fafad2',
549
+ lightgray: '#d3d3d3',
550
+ lightgreen: '#90ee90',
551
+ lightgrey: '#d3d3d3',
552
+ lightpink: '#ffb6c1',
553
+ lightsalmon: '#ffa07a',
554
+ lightseagreen: '#20b2aa',
555
+ lightskyblue: '#87cefa',
556
+ lightslategray: '#778899',
557
+ lightslategrey: '#778899',
558
+ lightsteelblue: '#b0c4de',
559
+ lightyellow: '#ffffe0',
560
+ lime: '#00ff00',
561
+ limegreen: '#32cd32',
562
+ linen: '#faf0e6',
563
+ magenta: '#ff00ff',
564
+ maroon: '#800000',
565
+ mediumaquamarine: '#66cdaa',
566
+ mediumblue: '#0000cd',
567
+ mediumorchid: '#ba55d3',
568
+ mediumpurple: '#9370db',
569
+ mediumseagreen: '#3cb371',
570
+ mediumslateblue: '#7b68ee',
571
+ mediumspringgreen: '#00fa9a',
572
+ mediumturquoise: '#48d1cc',
573
+ mediumvioletred: '#c71585',
574
+ midnightblue: '#191970',
575
+ mintcream: '#f5fffa',
576
+ mistyrose: '#ffe4e1',
577
+ moccasin: '#ffe4b5',
578
+ navajowhite: '#ffdead',
579
+ navy: '#000080',
580
+ oldlace: '#fdf5e6',
581
+ olive: '#808000',
582
+ olivedrab: '#6b8e23',
583
+ orange: '#ffa500',
584
+ orangered: '#ff4500',
585
+ orchid: '#da70d6',
586
+ palegoldenrod: '#eee8aa',
587
+ palegreen: '#98fb98',
588
+ paleturquoise: '#afeeee',
589
+ palevioletred: '#db7093',
590
+ papayawhip: '#ffefd5',
591
+ peachpuff: '#ffdab9',
592
+ peru: '#cd853f',
593
+ pink: '#ffc0cb',
594
+ plum: '#dda0dd',
595
+ powderblue: '#b0e0e6',
596
+ purple: '#800080',
597
+ rebeccapurple: '#663399',
598
+ red: '#ff0000',
599
+ rosybrown: '#bc8f8f',
600
+ royalblue: '#4169e1',
601
+ saddlebrown: '#8b4513',
602
+ salmon: '#fa8072',
603
+ sandybrown: '#f4a460',
604
+ seagreen: '#2e8b57',
605
+ seashell: '#fff5ee',
606
+ sienna: '#a0522d',
607
+ silver: '#c0c0c0',
608
+ skyblue: '#87ceeb',
609
+ slateblue: '#6a5acd',
610
+ slategray: '#708090',
611
+ slategrey: '#708090',
612
+ snow: '#fffafa',
613
+ springgreen: '#00ff7f',
614
+ steelblue: '#4682b4',
615
+ tan: '#d2b48c',
616
+ teal: '#008080',
617
+ thistle: '#d8bfd8',
618
+ tomato: '#ff6347',
619
+ turquoise: '#40e0d0',
620
+ violet: '#ee82ee',
621
+ wheat: '#f5deb3',
622
+ white: '#ffffff',
623
+ whitesmoke: '#f5f5f5',
624
+ yellow: '#ffff00',
625
+ yellowgreen: '#9acd32'
626
+ };
627
+ function clampChannel(value) {
628
+ return Math.min(255, Math.max(0, Math.round(value)));
629
+ }
630
+ function normalizeRgbArgs(args) {
631
+ var parts = args.split(/[,\s/]+/).filter(Boolean);
632
+ if (parts.length < 3) return null;
633
+ var to255 = function to255(value) {
634
+ if (typeof value !== 'string' || !value) return null;
635
+ if (value.endsWith('%')) return clampChannel(parseFloat(value) / 100 * 255);
636
+ var number = Number(value);
637
+ return Number.isFinite(number) ? clampChannel(number) : null;
638
+ };
639
+ var red = to255(parts[0]);
640
+ var green = to255(parts[1]);
641
+ var blue = to255(parts[2]);
642
+ if (red === null || green === null || blue === null) return null;
643
+ return "#".concat([red, green, blue].map(function (n) {
644
+ return n.toString(16).padStart(2, '0');
645
+ }).join(''));
646
+ }
647
+
648
+ /**
649
+ * Convert any supported CSS color into `#rrggbb`. Returns null when the
650
+ * value cannot be parsed. Supports: #rgb / #rrggbb (case-insensitive),
651
+ * CSS named colors, rgb() / rgba() with comma or modern space syntax,
652
+ * including percentages. Alpha in rgba() is ignored.
653
+ */
654
+ function normalizeColor(value) {
655
+ if (typeof value !== 'string') return null;
656
+ var input = value.trim();
657
+ if (!input) return null;
658
+ var lower = input.toLowerCase();
659
+ if (NAMED_COLORS[lower]) return NAMED_COLORS[lower];
660
+ if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(input)) {
661
+ var hex = input.slice(1).toLowerCase();
662
+ if (hex.length === 3) return "#".concat(hex.split('').map(function (c) {
663
+ return c + c;
664
+ }).join(''));
665
+ return "#".concat(hex);
666
+ }
667
+ var match = input.match(/^rgba?\((.*)\)$/i);
668
+ if (match) return normalizeRgbArgs(match[1]);
669
+ return null;
670
+ }
671
+ function hexToRgb01$1(color) {
672
+ var hex = normalizeColor(color);
673
+ if (!hex) return [0, 0, 0];
674
+ var value = Number.parseInt(hex.slice(1), 16);
466
675
  return [(value >> 16 & 255) / 255, (value >> 8 & 255) / 255, (value & 255) / 255];
467
676
  }
468
- function hexToRgba(hex) {
677
+ function hexToRgba(color) {
469
678
  var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
470
- var normalized = hex.replace('#', '');
471
- var value = Number.parseInt(normalized, 16);
679
+ var hex = normalizeColor(color);
680
+ if (!hex) return 'rgba(0, 0, 0, 0)';
681
+ var value = Number.parseInt(hex.slice(1), 16);
472
682
  var red = value >> 16 & 255;
473
683
  var green = value >> 8 & 255;
474
684
  var blue = value & 255;
@@ -549,6 +759,26 @@ var CosmicRenderer = /*#__PURE__*/function () {
549
759
  this.options.dprCap = cap;
550
760
  this.resize();
551
761
  }
762
+ }, {
763
+ key: "setMouseColor",
764
+ value: function setMouseColor(enabled) {
765
+ this.options.mouseColor = enabled !== false;
766
+ if (this.options.mouseColor) {
767
+ if (this.onPointerMove) return this;
768
+ _assertClassBrand(_CosmicRenderer_brand, this, _bindEvents).call(this);
769
+ return this;
770
+ }
771
+ if (this.onPointerMove) {
772
+ var target = this.eventTarget;
773
+ target.removeEventListener('pointermove', this.onPointerMove);
774
+ target.removeEventListener('pointerdown', this.onPointerMove);
775
+ target.removeEventListener('pointerleave', this.onPointerLeave);
776
+ this.onPointerMove = null;
777
+ this.onPointerLeave = null;
778
+ }
779
+ this.motionTarget = 0;
780
+ return this;
781
+ }
552
782
  }, {
553
783
  key: "randomize",
554
784
  value: function randomize() {
@@ -697,6 +927,8 @@ var FallbackRenderer = /*#__PURE__*/function () {
697
927
  var _this$canvas = this.canvas,
698
928
  width = _this$canvas.width,
699
929
  height = _this$canvas.height;
930
+ var t = time * (this.preset.speed || 1);
931
+ var phase = (this.preset.seed || 0) * 0.7;
700
932
  var gradient = ctx.createLinearGradient(0, 0, width, height);
701
933
  gradient.addColorStop(0, this.preset.colors[0]);
702
934
  gradient.addColorStop(0.38, this.preset.colors[1]);
@@ -706,8 +938,8 @@ var FallbackRenderer = /*#__PURE__*/function () {
706
938
  ctx.fillRect(0, 0, width, height);
707
939
  ctx.globalCompositeOperation = 'screen';
708
940
  for (var index = 0; index < 6; index += 1) {
709
- var x = (0.5 + 0.45 * Math.sin(time * 0.32 + index * 1.7)) * width;
710
- var y = (0.5 + 0.4 * Math.cos(time * 0.25 + index)) * height;
941
+ var x = (0.5 + 0.45 * Math.sin(t * 0.32 + index * 1.7 + phase)) * width;
942
+ var y = (0.5 + 0.4 * Math.cos(t * 0.25 + index + phase)) * height;
711
943
  var radius = Math.max(width, height) * (0.08 + index % 3 * 0.04);
712
944
  var glow = ctx.createRadialGradient(x, y, 0, x, y, radius);
713
945
  glow.addColorStop(0, rgb(this.preset.colors[(index + 1) % 4], 0.24));
@@ -731,7 +963,12 @@ var FallbackRenderer = /*#__PURE__*/function () {
731
963
  }
732
964
  }, {
733
965
  key: "randomize",
734
- value: function randomize() {}
966
+ value: function randomize() {
967
+ if (this.preset) this.preset.seed = Math.random() * 100;
968
+ }
969
+ }, {
970
+ key: "setMouseColor",
971
+ value: function setMouseColor() {}
735
972
  }, {
736
973
  key: "dispose",
737
974
  value: function dispose() {}
@@ -842,16 +1079,34 @@ function createVisibilityGuard(element) {
842
1079
  };
843
1080
  }
844
1081
 
845
- function prefersReducedMotion$1() {
1082
+ /**
1083
+ * Run a callback asynchronously, right after the current task and before the
1084
+ * next paint. Used for mount-time events (ready / error) so listeners that
1085
+ * are attached after create() still receive them. Falls back for legacy
1086
+ * browsers that lack queueMicrotask / Promise.
1087
+ */
1088
+ function nextTick(fn) {
1089
+ if (typeof queueMicrotask === 'function') {
1090
+ queueMicrotask(fn);
1091
+ } else if (typeof Promise !== 'undefined' && typeof Promise.resolve === 'function') {
1092
+ Promise.resolve().then(fn);
1093
+ } else {
1094
+ setTimeout(fn, 0);
1095
+ }
1096
+ }
1097
+
1098
+ function prefersReducedMotion$2() {
846
1099
  return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
847
1100
  }
848
1101
 
849
1102
  /**
850
- * Mount a cosmic (nebula) capsule into `container`.
851
- *
852
- * Options: preset (id/code/name or object), width, height (number=px or
853
- * string with px/%/vw/vh/em/rem), colors, seed, speed, quality,
854
- * respectReducedMotion, copy, cssVars.
1103
+ * Mount a cosmic (nebula) capsule into `container`.
1104
+ *
1105
+ * Options: preset (literary name), width, height (number=px or string with
1106
+ * px/%/vw/vh/em/rem), colors, seed, speed, textRatio (0-100, text region
1107
+ * width in percent), text (HTML string or DOM nodes for the text slot),
1108
+ * colorContent (HTML string or DOM nodes for the color slot), quality,
1109
+ * renderer, respectReducedMotion, mouseColor, cssVars.
855
1110
  */
856
1111
  function createCapsule(container) {
857
1112
  var _options$preset;
@@ -861,51 +1116,71 @@ function createCapsule(container) {
861
1116
  }
862
1117
  var preset = _objectSpread2({}, getPreset('capsule', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '初光'));
863
1118
  var merged = normalizeOptions(DEFAULTS.capsule, preset, options);
864
- var copy = _objectSpread2(_objectSpread2({}, COPY), merged.copy || {});
1119
+ var normalizedColors = merged.colors.map(normalizeColor);
1120
+ if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
1121
+ preset.seed = merged.seed;
1122
+ preset.speed = merged.speed;
1123
+ var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
865
1124
  var root = document.createElement('div');
866
1125
  root.className = 'hj-capsule-root hj-capsule-cosmic';
867
1126
  root.dataset.group = preset.group;
868
1127
  root.dataset.mode = 'nebula';
869
1128
  root.dataset.theme = preset.theme || 'light';
870
- root.setAttribute('aria-label', copy.capsuleAria.replace('{name}', preset.name));
871
- var copyEnabled = copy.enabled !== false && merged.showCopy !== false;
872
- var copyText = function copyText(key, fallback) {
873
- var value = copy[key];
874
- return value === undefined ? fallback : value;
1129
+ root.setAttribute('role', 'img');
1130
+ var updateAria = function updateAria() {
1131
+ root.setAttribute('aria-label', customLabel || COPY.capsuleAria.replace('{name}', preset.name));
875
1132
  };
876
- function buildCopyHtml() {
877
- var codeText = copyText('code', preset.code);
878
- var nameText = copyText('name', preset.name);
879
- var subtitleText = copyText('subtitle', preset.subtitle);
880
- var stateText = copyText('state', 'LIVE COSMIC STUDY');
881
- var html = '';
882
- if (codeText) html += "<span class=\"hj-capsule-code\">".concat(codeText, "</span>");
883
- if (nameText) html += "<span class=\"hj-capsule-name\">".concat(nameText, "</span>");
884
- if (subtitleText) html += "<span class=\"hj-capsule-brand\">".concat(subtitleText, "</span>");
885
- if (stateText) html += "<span class=\"hj-capsule-state\">".concat(stateText, "</span>");
886
- return html;
887
- }
888
- var copyLayer = document.createElement('div');
889
- copyLayer.className = 'hj-capsule-copy';
890
- var renderCopy = function renderCopy() {
891
- if (copyEnabled) copyLayer.innerHTML = buildCopyHtml();
892
- };
893
- renderCopy();
894
- var isHexColor = function isHexColor(value) {
895
- return typeof value === 'string' && /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(value);
1133
+ updateAria();
1134
+
1135
+ // Slot containers are always present but transparent by default: without
1136
+ // content they are invisible, so "no slot" behaves like the old
1137
+ // showCopy=false. They only provide geometry — no typography, padding or
1138
+ // background is imposed on user content (see docs: 插槽 CSS 约定).
1139
+ var fillContent = function fillContent(layer, content) {
1140
+ layer.innerHTML = '';
1141
+ if (content == null) return;
1142
+ if (typeof content === 'string') {
1143
+ layer.innerHTML = content;
1144
+ return;
1145
+ }
1146
+ var nodes = Array.isArray(content) ? content : [content];
1147
+ var _iterator = _createForOfIteratorHelper(nodes),
1148
+ _step;
1149
+ try {
1150
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1151
+ var node = _step.value;
1152
+ if (node && typeof node.nodeType === 'number') layer.appendChild(node);
1153
+ }
1154
+ } catch (err) {
1155
+ _iterator.e(err);
1156
+ } finally {
1157
+ _iterator.f();
1158
+ }
896
1159
  };
897
- if (copy.background) {
898
- root.style.setProperty('--hj-copy-bg', isHexColor(copy.background) ? "linear-gradient(90deg, ".concat(copy.background, " 0%, ").concat(copy.background, " 74%, ").concat(hexToRgba(copy.background, 0.97), " 84%, ").concat(hexToRgba(copy.background, 0), " 100%)") : copy.background);
899
- }
900
- if (copy.color) root.style.setProperty('--hj-copy-color', copy.color);
1160
+ var textLayer = document.createElement('div');
1161
+ textLayer.className = 'hj-capsule-text hj-capsule-copy';
1162
+ var visualLayer = document.createElement('div');
1163
+ visualLayer.className = 'hj-capsule-visual';
1164
+ fillContent(textLayer, options.text);
1165
+ fillContent(visualLayer, options.colorContent);
901
1166
  var canvas = document.createElement('canvas');
902
1167
  canvas.className = 'hj-capsule-canvas';
903
1168
  canvas.setAttribute('aria-hidden', 'true');
904
- if (copyEnabled) root.appendChild(copyLayer);
1169
+ root.appendChild(textLayer);
1170
+ root.appendChild(visualLayer);
905
1171
  root.appendChild(canvas);
906
1172
  container.appendChild(root);
907
1173
  var emitter = createEmitter();
908
- var paused = merged.respectReducedMotion && prefersReducedMotion$1();
1174
+ var paused = merged.respectReducedMotion && prefersReducedMotion$2();
1175
+ var disposed = false;
1176
+ var dirty = {
1177
+ preset: false,
1178
+ seed: false,
1179
+ speed: false,
1180
+ colors: false,
1181
+ textRatio: false,
1182
+ cssVars: false
1183
+ };
909
1184
  var renderer;
910
1185
  var useWebgl = merged.renderer !== 'canvas2d';
911
1186
  if (useWebgl) {
@@ -915,8 +1190,11 @@ function createCapsule(container) {
915
1190
  });
916
1191
  } catch (error) {
917
1192
  renderer = new FallbackRenderer(canvas, merged);
918
- emitter.emit('error', {
919
- message: String(error && error.message ? error.message : error)
1193
+ nextTick(function () {
1194
+ if (disposed) return;
1195
+ emitter.emit('error', {
1196
+ message: String(error && error.message ? error.message : error)
1197
+ });
920
1198
  });
921
1199
  }
922
1200
  } else {
@@ -930,6 +1208,9 @@ function createCapsule(container) {
930
1208
  var name = _Object$keys[_i];
931
1209
  root.style.setProperty(name, vars[name]);
932
1210
  }
1211
+ if (merged.textRatio !== undefined) {
1212
+ root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
1213
+ }
933
1214
  renderer.resize();
934
1215
  };
935
1216
  applySize();
@@ -979,13 +1260,16 @@ function createCapsule(container) {
979
1260
  }, function () {
980
1261
  return paused;
981
1262
  });
982
- emitter.emit('ready', {
983
- preset: _objectSpread2({}, preset)
1263
+ nextTick(function () {
1264
+ if (disposed) return;
1265
+ emitter.emit('ready', {
1266
+ preset: _objectSpread2({}, preset)
1267
+ });
984
1268
  });
985
- var syncCopy = function syncCopy() {
1269
+ var syncTheme = function syncTheme() {
986
1270
  root.dataset.mode = 'nebula';
987
1271
  root.dataset.theme = preset.theme || 'light';
988
- renderCopy();
1272
+ updateAria();
989
1273
  };
990
1274
  return {
991
1275
  element: root,
@@ -995,9 +1279,12 @@ function createCapsule(container) {
995
1279
  off: emitter.off,
996
1280
  setPreset: function setPreset(ref) {
997
1281
  var next = getPreset('capsule', ref);
1282
+ dirty.preset = true;
998
1283
  Object.assign(preset, next);
999
- renderer.setPreset(next);
1000
- syncCopy();
1284
+ var nextColors = preset.colors.map(normalizeColor);
1285
+ if (nextColors.every(Boolean)) preset.colors = nextColors;
1286
+ renderer.setPreset(_objectSpread2({}, preset));
1287
+ syncTheme();
1001
1288
  renderer.resize();
1002
1289
  emitter.emit('presetchange', {
1003
1290
  preset: _objectSpread2({}, next)
@@ -1005,16 +1292,21 @@ function createCapsule(container) {
1005
1292
  return this;
1006
1293
  },
1007
1294
  setColors: function setColors(colors) {
1008
- if (!Array.isArray(colors) || colors.length !== 4) return this;
1009
- preset.colors = colors;
1295
+ var next = Array.isArray(colors) ? colors.map(normalizeColor) : [];
1296
+ if (next.length !== 4 || next.some(function (color) {
1297
+ return !color;
1298
+ })) return this;
1299
+ dirty.colors = true;
1300
+ preset.colors = next;
1010
1301
  renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
1011
- colors: colors
1302
+ colors: next
1012
1303
  }));
1013
1304
  return this;
1014
1305
  },
1015
1306
  setSeed: function setSeed(seed) {
1016
1307
  var value = Number(seed);
1017
1308
  if (!Number.isFinite(value)) return this;
1309
+ dirty.seed = true;
1018
1310
  preset.seed = value;
1019
1311
  renderer.setPreset(_objectSpread2({}, preset));
1020
1312
  return this;
@@ -1022,10 +1314,42 @@ function createCapsule(container) {
1022
1314
  setSpeed: function setSpeed(speed) {
1023
1315
  var value = Number(speed);
1024
1316
  if (!Number.isFinite(value)) return this;
1317
+ dirty.speed = true;
1025
1318
  preset.speed = value;
1026
1319
  renderer.setPreset(_objectSpread2({}, preset));
1027
1320
  return this;
1028
1321
  },
1322
+ setText: function setText(content) {
1323
+ fillContent(textLayer, content);
1324
+ return this;
1325
+ },
1326
+ setColorContent: function setColorContent(content) {
1327
+ fillContent(visualLayer, content);
1328
+ return this;
1329
+ },
1330
+ setTextRatio: function setTextRatio(ratio) {
1331
+ var value = Number(ratio);
1332
+ if (!Number.isFinite(value) || value < 0 || value > 100) return this;
1333
+ dirty.textRatio = true;
1334
+ merged.textRatio = value;
1335
+ root.style.setProperty('--hj-text-width', "".concat(value, "%"));
1336
+ return this;
1337
+ },
1338
+ setCssVars: function setCssVars(vars) {
1339
+ if (!vars || _typeof(vars) !== 'object') return this;
1340
+ dirty.cssVars = true;
1341
+ merged.cssVars = _objectSpread2(_objectSpread2({}, merged.cssVars || {}), vars);
1342
+ for (var _i2 = 0, _Object$keys2 = Object.keys(vars); _i2 < _Object$keys2.length; _i2++) {
1343
+ var name = _Object$keys2[_i2];
1344
+ root.style.setProperty(name, vars[name]);
1345
+ }
1346
+ return this;
1347
+ },
1348
+ setLabel: function setLabel(label) {
1349
+ customLabel = typeof label === 'string' && label ? label : null;
1350
+ updateAria();
1351
+ return this;
1352
+ },
1029
1353
  setSize: function setSize(width, height) {
1030
1354
  if (width !== undefined) merged.width = width;
1031
1355
  if (height !== undefined) merged.height = height;
@@ -1033,7 +1357,7 @@ function createCapsule(container) {
1033
1357
  return this;
1034
1358
  },
1035
1359
  randomize: function randomize() {
1036
- renderer.randomize();
1360
+ this.setSeed(Math.random() * 100);
1037
1361
  return this;
1038
1362
  },
1039
1363
  pause: function pause() {
@@ -1050,12 +1374,16 @@ function createCapsule(container) {
1050
1374
  return this;
1051
1375
  },
1052
1376
  dispose: function dispose() {
1377
+ disposed = true;
1053
1378
  unsubscribe();
1054
1379
  visibility.dispose();
1055
1380
  if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', renderer.resize);
1056
1381
  renderer.dispose();
1057
1382
  root.remove();
1058
- }
1383
+ },
1384
+ textRatio: merged.textRatio,
1385
+ cssVars: merged.cssVars,
1386
+ dirty: dirty
1059
1387
  };
1060
1388
  }
1061
1389
 
@@ -1497,7 +1825,7 @@ function interpolate(template, values) {
1497
1825
  return values[key] !== undefined ? values[key] : '';
1498
1826
  });
1499
1827
  }
1500
- function prefersReducedMotion() {
1828
+ function prefersReducedMotion$1() {
1501
1829
  return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
1502
1830
  }
1503
1831
  var FLOW_PROFILES = {
@@ -1559,7 +1887,8 @@ var FLOW_PROFILES = {
1559
1887
  };
1560
1888
  var ProgressCapsuleController = /*#__PURE__*/function () {
1561
1889
  function ProgressCapsuleController(_ref) {
1562
- var _options$min,
1890
+ var _options$valueSuffix,
1891
+ _options$min,
1563
1892
  _options$max,
1564
1893
  _options$value,
1565
1894
  _this = this;
@@ -1569,7 +1898,8 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1569
1898
  preset = _ref.preset,
1570
1899
  emitter = _ref.emitter,
1571
1900
  options = _ref.options,
1572
- copy = _ref.copy;
1901
+ copy = _ref.copy,
1902
+ dirty = _ref.dirty;
1573
1903
  _classCallCheck(this, ProgressCapsuleController);
1574
1904
  this.root = root;
1575
1905
  this.canvas = canvas;
@@ -1578,6 +1908,8 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1578
1908
  this.emitter = emitter;
1579
1909
  this.options = options;
1580
1910
  this.copy = copy;
1911
+ this.dirty = dirty;
1912
+ this.valueSuffix = (_options$valueSuffix = options.valueSuffix) !== null && _options$valueSuffix !== void 0 ? _options$valueSuffix : copy.valueSuffix;
1581
1913
  this.profile = preset.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
1582
1914
  this.min = (_options$min = options.min) !== null && _options$min !== void 0 ? _options$min : 0;
1583
1915
  this.max = (_options$max = options.max) !== null && _options$max !== void 0 ? _options$max : 100;
@@ -1617,12 +1949,24 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1617
1949
  var rounded = Math.round(this.value);
1618
1950
  this.root.style.setProperty('--progress', this.value.toFixed(2));
1619
1951
  this.root.setAttribute('aria-valuenow', String(rounded));
1620
- this.root.setAttribute('aria-valuetext', "".concat(rounded).concat(this.copy.valueSuffix));
1621
- this.valueElement.textContent = "".concat(rounded).concat(this.copy.valueSuffix);
1622
- if (!this.suppressEvents) this.emitter.emit('change', {
1623
- value: this.value,
1624
- source: source
1625
- });
1952
+ this.root.setAttribute('aria-valuetext', "".concat(rounded).concat(this.valueSuffix));
1953
+ if (this.valueElement) this.valueElement.textContent = "".concat(rounded).concat(this.valueSuffix);
1954
+ if (!this.suppressEvents) {
1955
+ if (this.dirty) this.dirty.value = true;
1956
+ this.emitter.emit('change', {
1957
+ value: this.value,
1958
+ source: source
1959
+ });
1960
+ }
1961
+ }
1962
+ }, {
1963
+ key: "setValueSuffix",
1964
+ value: function setValueSuffix(suffix) {
1965
+ this.valueSuffix = String(suffix == null ? '' : suffix);
1966
+ var rounded = Math.round(this.value);
1967
+ if (this.valueElement) this.valueElement.textContent = "".concat(rounded).concat(this.valueSuffix);
1968
+ this.root.setAttribute('aria-valuetext', "".concat(rounded).concat(this.valueSuffix));
1969
+ return this;
1626
1970
  }
1627
1971
  }, {
1628
1972
  key: "resizeCanvas",
@@ -1797,7 +2141,8 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1797
2141
  var width = this.width;
1798
2142
  var height = this.height;
1799
2143
  if (!ctx || width <= 0 || height <= 0) return;
1800
- var shoreline = width * (this.value / 100);
2144
+ var range = Math.max(this.max - this.min, 1);
2145
+ var shoreline = width * Math.min(Math.max((this.value - this.min) / range, 0), 1);
1801
2146
  var time = this.flowTime;
1802
2147
  var _this$preset$colors = _slicedToArray(this.preset.colors, 4),
1803
2148
  dark = _this$preset$colors[0],
@@ -1912,7 +2257,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1912
2257
  value: function updateFromPointer(event) {
1913
2258
  var bounds = this.root.getBoundingClientRect();
1914
2259
  var ratio = bounds.width > 0 ? (event.clientX - bounds.left) / bounds.width : 0;
1915
- this.setProgress(ratio * 100, 'drag');
2260
+ this.setProgress(this.min + ratio * (this.max - this.min), 'drag');
1916
2261
  }
1917
2262
  }, {
1918
2263
  key: "beginDrag",
@@ -1920,6 +2265,8 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1920
2265
  if (event.button !== undefined && event.button !== 0) return;
1921
2266
  event.preventDefault();
1922
2267
  this.dragging = true;
2268
+ this.pendingPointer = null;
2269
+ this._dragRaf = 0;
1923
2270
  this.root.classList.add('is-dragging');
1924
2271
  try {
1925
2272
  var _this$root$setPointer, _this$root;
@@ -1933,15 +2280,31 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1933
2280
  }, {
1934
2281
  key: "moveDrag",
1935
2282
  value: function moveDrag(event) {
2283
+ var _this2 = this;
1936
2284
  if (!this.dragging) return;
1937
2285
  event.preventDefault();
1938
- this.updateFromPointer(event);
2286
+ // rAF 合并:一帧最多一次 setProgress/change,视觉仍每帧更新。
2287
+ this.pendingPointer = event;
2288
+ if (this._dragRaf) return;
2289
+ this._dragRaf = requestAnimationFrame(function () {
2290
+ _this2._dragRaf = 0;
2291
+ var pending = _this2.pendingPointer;
2292
+ _this2.pendingPointer = null;
2293
+ if (pending) _this2.updateFromPointer(pending);
2294
+ });
1939
2295
  }
1940
2296
  }, {
1941
2297
  key: "endDrag",
1942
2298
  value: function endDrag(event) {
1943
2299
  if (!this.dragging) return;
1944
2300
  this.dragging = false;
2301
+ if (this._dragRaf) {
2302
+ cancelAnimationFrame(this._dragRaf);
2303
+ this._dragRaf = 0;
2304
+ }
2305
+ var pending = this.pendingPointer;
2306
+ this.pendingPointer = null;
2307
+ if (pending) this.updateFromPointer(pending);
1945
2308
  this.root.classList.remove('is-dragging');
1946
2309
  try {
1947
2310
  var _this$root$hasPointer, _this$root2;
@@ -1956,19 +2319,19 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1956
2319
  }, {
1957
2320
  key: "bindEvents",
1958
2321
  value: function bindEvents() {
1959
- var _this2 = this;
2322
+ var _this3 = this;
1960
2323
  if (this.options.draggable !== false) {
1961
2324
  this.handlers.pointerdown = function (event) {
1962
- return _this2.beginDrag(event);
2325
+ return _this3.beginDrag(event);
1963
2326
  };
1964
2327
  this.handlers.pointermove = function (event) {
1965
- return _this2.moveDrag(event);
2328
+ return _this3.moveDrag(event);
1966
2329
  };
1967
2330
  this.handlers.pointerup = function (event) {
1968
- return _this2.endDrag(event);
2331
+ return _this3.endDrag(event);
1969
2332
  };
1970
2333
  this.handlers.pointercancel = function (event) {
1971
- return _this2.endDrag(event);
2334
+ return _this3.endDrag(event);
1972
2335
  };
1973
2336
  this.root.addEventListener('pointerdown', this.handlers.pointerdown);
1974
2337
  this.root.addEventListener('pointermove', this.handlers.pointermove);
@@ -1977,23 +2340,24 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
1977
2340
  }
1978
2341
  if (this.options.keyboard !== false) {
1979
2342
  this.handlers.keydown = function (event) {
2343
+ var step = (_this3.max - _this3.min) * 0.02;
1980
2344
  var actions = {
1981
- ArrowLeft: -2,
1982
- ArrowDown: -2,
1983
- ArrowRight: 2,
1984
- ArrowUp: 2,
1985
- PageDown: -10,
1986
- PageUp: 10
2345
+ ArrowLeft: -step,
2346
+ ArrowDown: -step,
2347
+ ArrowRight: step,
2348
+ ArrowUp: step,
2349
+ PageDown: -step * 5,
2350
+ PageUp: step * 5
1987
2351
  };
1988
2352
  if (event.key === 'Home') {
1989
2353
  event.preventDefault();
1990
- _this2.setProgress(_this2.min, 'keyboard');
2354
+ _this3.setProgress(_this3.min, 'keyboard');
1991
2355
  } else if (event.key === 'End') {
1992
2356
  event.preventDefault();
1993
- _this2.setProgress(_this2.max, 'keyboard');
2357
+ _this3.setProgress(_this3.max, 'keyboard');
1994
2358
  } else if (actions[event.key]) {
1995
2359
  event.preventDefault();
1996
- _this2.setProgress(_this2.value + actions[event.key], 'keyboard');
2360
+ _this3.setProgress(_this3.value + actions[event.key], 'keyboard');
1997
2361
  } else {
1998
2362
  return;
1999
2363
  }
@@ -2030,6 +2394,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2030
2394
  }, {
2031
2395
  key: "dispose",
2032
2396
  value: function dispose() {
2397
+ if (this._dragRaf) cancelAnimationFrame(this._dragRaf);
2033
2398
  if (this.resizeObserver) this.resizeObserver.disconnect();else window.removeEventListener('resize', this.resizeCanvas);
2034
2399
  for (var _i = 0, _Object$keys = Object.keys(this.handlers); _i < _Object$keys.length; _i++) {
2035
2400
  var name = _Object$keys[_i];
@@ -2042,11 +2407,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2042
2407
  }();
2043
2408
 
2044
2409
  /**
2045
- * Mount a fluid progress capsule into `container`.
2046
- *
2047
- * Options: preset (id/code/name or object), width, height, value, min, max,
2048
- * draggable, keyboard, colors, edgeStyle, quality,
2049
- * respectReducedMotion, copy, cssVars.
2410
+ * Mount a fluid progress capsule into `container`.
2411
+ *
2412
+ * Options: preset (id/code/name or object), width, height, value, min, max,
2413
+ * draggable, keyboard, colors, edgeStyle, textRatio (0-100, text region
2414
+ * width in percent), text (HTML string or DOM nodes for the text slot),
2415
+ * colorContent (HTML string or DOM nodes for the color slot),
2416
+ * showValue (show/hide the right-side percentage), quality,
2417
+ * respectReducedMotion, cssVars.
2050
2418
  */
2051
2419
  function createProgressCapsule(container) {
2052
2420
  var _options$preset, _merged$min, _merged$max;
@@ -2056,62 +2424,91 @@ function createProgressCapsule(container) {
2056
2424
  }
2057
2425
  var preset = _objectSpread2({}, getPreset('progress', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '星火'));
2058
2426
  var merged = normalizeOptions(DEFAULTS.progress, preset, options);
2059
- var copy = _objectSpread2(_objectSpread2({}, COPY), merged.copy || {});
2427
+ var normalizedColors = merged.colors.map(normalizeColor);
2428
+ if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
2429
+ preset.edgeStyle = merged.edgeStyle;
2430
+ var copy = COPY;
2431
+ var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
2432
+ // Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
2433
+ // 这里统一按 true 处理。
2434
+ var disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
2435
+ var effectiveDraggable = disabled ? false : merged.draggable !== false;
2436
+ var effectiveKeyboard = disabled ? false : merged.keyboard !== false;
2437
+ var dirty = {
2438
+ preset: false,
2439
+ colors: false,
2440
+ textRatio: false,
2441
+ cssVars: false,
2442
+ edgeStyle: false,
2443
+ value: false
2444
+ };
2060
2445
  var root = document.createElement('div');
2061
2446
  root.className = 'hj-capsule-root hj-progress-root';
2062
2447
  root.setAttribute('role', 'slider');
2063
2448
  root.setAttribute('tabindex', '0');
2064
- root.setAttribute('data-draggable', String(merged.draggable !== false));
2449
+ root.setAttribute('data-draggable', String(effectiveDraggable));
2450
+ if (disabled) {
2451
+ root.setAttribute('aria-disabled', 'true');
2452
+ root.classList.add('is-disabled');
2453
+ }
2065
2454
  root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
2066
2455
  root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
2067
2456
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
2068
- root.setAttribute('aria-label', interpolate(copy.progressAria, {
2069
- brand: copy.brandName,
2070
- code: preset.code,
2071
- name: preset.name
2072
- }));
2073
- if (merged.keyboard === false) root.setAttribute('tabindex', '-1');
2457
+ var updateAria = function updateAria() {
2458
+ root.setAttribute('aria-label', customLabel || interpolate(copy.progressAria, {
2459
+ brand: copy.brandName,
2460
+ code: preset.code,
2461
+ name: preset.name
2462
+ }));
2463
+ };
2464
+ updateAria();
2465
+ if (!effectiveKeyboard) root.setAttribute('tabindex', '-1');
2074
2466
  var canvas = document.createElement('canvas');
2075
2467
  canvas.className = 'hj-progress-canvas';
2076
2468
  canvas.setAttribute('aria-hidden', 'true');
2077
- var copyEnabled = copy.enabled !== false && merged.showCopy !== false;
2078
- var copyText = function copyText(key, fallback) {
2079
- var value = copy[key];
2080
- return value === undefined ? fallback : value;
2081
- };
2082
- function buildCopyHtml() {
2083
- var html = '';
2084
- var brandText = copy.brandName || '';
2085
- var subtitleText = copyText('subtitle', preset.subtitle);
2086
- if (brandText) html += "<span class=\"hj-progress-name\">".concat(brandText, "</span>");
2087
- if (subtitleText) html += "<span class=\"hj-progress-subtitle\">".concat(subtitleText, "</span>");
2088
- return html;
2089
- }
2090
- var copyLayer = document.createElement('div');
2091
- copyLayer.className = 'hj-progress-copy';
2092
- var renderCopy = function renderCopy() {
2093
- if (copyEnabled) copyLayer.innerHTML = buildCopyHtml();
2469
+
2470
+ // Slot containers are always present but transparent by default; they only
2471
+ // provide geometry, never typography/padding/background (docs: 插槽 CSS 约定).
2472
+ var fillContent = function fillContent(layer, content) {
2473
+ layer.innerHTML = '';
2474
+ if (content == null) return;
2475
+ if (typeof content === 'string') {
2476
+ layer.innerHTML = content;
2477
+ return;
2478
+ }
2479
+ var nodes = Array.isArray(content) ? content : [content];
2480
+ var _iterator2 = _createForOfIteratorHelper(nodes),
2481
+ _step2;
2482
+ try {
2483
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
2484
+ var node = _step2.value;
2485
+ if (node && typeof node.nodeType === 'number') layer.appendChild(node);
2486
+ }
2487
+ } catch (err) {
2488
+ _iterator2.e(err);
2489
+ } finally {
2490
+ _iterator2.f();
2491
+ }
2094
2492
  };
2095
- renderCopy();
2096
- if (copy.background) {
2097
- root.style.setProperty('--hj-progress-copy-bg', copy.background);
2098
- root.style.setProperty('--hj-progress-copy-pad', '6px 12px');
2493
+ var textLayer = document.createElement('div');
2494
+ textLayer.className = 'hj-progress-text hj-progress-copy';
2495
+ var visualLayer = document.createElement('div');
2496
+ visualLayer.className = 'hj-progress-visual';
2497
+ fillContent(textLayer, options.text);
2498
+ fillContent(visualLayer, options.colorContent);
2499
+ var valueElement = merged.showValue === false ? null : document.createElement('div');
2500
+ if (valueElement) {
2501
+ valueElement.className = 'hj-progress-value';
2502
+ valueElement.setAttribute('aria-hidden', 'true');
2099
2503
  }
2100
- if (copy.color) root.style.setProperty('--hj-progress-copy-color', copy.color);
2101
- var valueElement = document.createElement('div');
2102
- valueElement.className = 'hj-progress-value';
2103
- valueElement.setAttribute('aria-hidden', 'true');
2104
- var dragLabel = document.createElement('span');
2105
- dragLabel.className = 'hj-progress-drag-label';
2106
- dragLabel.setAttribute('aria-hidden', 'true');
2107
- dragLabel.textContent = copy.dragLabel;
2108
2504
  root.appendChild(canvas);
2109
- if (copyEnabled) root.appendChild(copyLayer);
2110
- root.appendChild(valueElement);
2111
- root.appendChild(dragLabel);
2505
+ root.appendChild(textLayer);
2506
+ root.appendChild(visualLayer);
2507
+ if (valueElement) root.appendChild(valueElement);
2112
2508
  container.appendChild(root);
2113
2509
  var emitter = createEmitter();
2114
- var paused = merged.respectReducedMotion && prefersReducedMotion();
2510
+ var paused = merged.respectReducedMotion && prefersReducedMotion$1();
2511
+ var disposed = false;
2115
2512
  var applySize = function applySize() {
2116
2513
  root.style.width = parseSize(merged.width);
2117
2514
  root.style.height = parseSize(merged.height);
@@ -2120,6 +2517,9 @@ function createProgressCapsule(container) {
2120
2517
  var name = _Object$keys2[_i2];
2121
2518
  root.style.setProperty(name, vars[name]);
2122
2519
  }
2520
+ if (merged.textRatio !== undefined) {
2521
+ root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
2522
+ }
2123
2523
  };
2124
2524
  applySize();
2125
2525
  var controller = new ProgressCapsuleController({
@@ -2128,8 +2528,12 @@ function createProgressCapsule(container) {
2128
2528
  valueElement: valueElement,
2129
2529
  preset: preset,
2130
2530
  emitter: emitter,
2131
- options: merged,
2132
- copy: copy
2531
+ options: _objectSpread2(_objectSpread2({}, merged), {}, {
2532
+ draggable: effectiveDraggable,
2533
+ keyboard: effectiveKeyboard
2534
+ }),
2535
+ copy: copy,
2536
+ dirty: dirty
2133
2537
  });
2134
2538
  var overlay = null;
2135
2539
  if (merged.renderer !== 'canvas2d') {
@@ -2142,7 +2546,14 @@ function createProgressCapsule(container) {
2142
2546
  }
2143
2547
  });
2144
2548
  }
2145
- if (overlay) controller.webglActive = true;
2549
+ if (overlay) controller.webglActive = true;else if (merged.renderer !== 'canvas2d') {
2550
+ nextTick(function () {
2551
+ if (disposed) return;
2552
+ emitter.emit('error', {
2553
+ message: 'WebGL2 unavailable, using Canvas2D fallback'
2554
+ });
2555
+ });
2556
+ }
2146
2557
  var visibility = createVisibilityGuard(root);
2147
2558
  var flowTime = 0;
2148
2559
  var unsubscribe = subscribeScheduler(function (delta, now) {
@@ -2155,16 +2566,14 @@ function createProgressCapsule(container) {
2155
2566
  }, function () {
2156
2567
  return paused;
2157
2568
  });
2158
- emitter.emit('ready', {
2159
- preset: _objectSpread2({}, preset)
2569
+ nextTick(function () {
2570
+ if (disposed) return;
2571
+ emitter.emit('ready', {
2572
+ preset: _objectSpread2({}, preset)
2573
+ });
2160
2574
  });
2161
2575
  var syncDom = function syncDom() {
2162
- root.setAttribute('aria-label', interpolate(copy.progressAria, {
2163
- brand: copy.brandName,
2164
- code: preset.code,
2165
- name: preset.name
2166
- }));
2167
- renderCopy();
2576
+ updateAria();
2168
2577
  };
2169
2578
  return {
2170
2579
  element: root,
@@ -2186,8 +2595,11 @@ function createProgressCapsule(container) {
2186
2595
  },
2187
2596
  setPreset: function setPreset(ref) {
2188
2597
  var next = getPreset('progress', ref);
2598
+ dirty.preset = true;
2189
2599
  Object.assign(preset, next);
2190
- controller.preset = next;
2600
+ var nextColors = preset.colors.map(normalizeColor);
2601
+ if (nextColors.every(Boolean)) preset.colors = nextColors;
2602
+ controller.preset = preset;
2191
2603
  controller.profile = next.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[next.id] || FLOW_PROFILES['visual-training'];
2192
2604
  controller.flowTime = stringSeed(next.id) * 31;
2193
2605
  controller.seed = stringSeed("".concat(next.id, "-reference")) * Math.PI * 2;
@@ -2197,7 +2609,7 @@ function createProgressCapsule(container) {
2197
2609
  overlay = attachProgressFlowOverlay({
2198
2610
  root: root,
2199
2611
  canvas: canvas,
2200
- preset: next,
2612
+ preset: preset,
2201
2613
  getProgress: function getProgress() {
2202
2614
  return controller.value;
2203
2615
  }
@@ -2206,13 +2618,14 @@ function createProgressCapsule(container) {
2206
2618
  controller.webglActive = Boolean(overlay);
2207
2619
  controller.resizeCanvas();
2208
2620
  emitter.emit('presetchange', {
2209
- preset: _objectSpread2({}, next)
2621
+ preset: _objectSpread2({}, preset)
2210
2622
  });
2211
2623
  return this;
2212
2624
  },
2213
2625
  setEdgeStyle: function setEdgeStyle(edgeStyle) {
2214
2626
  var value = String(edgeStyle || '').toLowerCase();
2215
2627
  if (value !== 'flow' && value !== 'tide') return this;
2628
+ dirty.edgeStyle = true;
2216
2629
  preset.edgeStyle = value;
2217
2630
  controller.profile = value === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
2218
2631
  if (overlay) {
@@ -2230,10 +2643,49 @@ function createProgressCapsule(container) {
2230
2643
  controller.resizeCanvas();
2231
2644
  return this;
2232
2645
  },
2646
+ setText: function setText(content) {
2647
+ fillContent(textLayer, content);
2648
+ return this;
2649
+ },
2650
+ setColorContent: function setColorContent(content) {
2651
+ fillContent(visualLayer, content);
2652
+ return this;
2653
+ },
2654
+ setTextRatio: function setTextRatio(ratio) {
2655
+ var value = Number(ratio);
2656
+ if (!Number.isFinite(value) || value < 0 || value > 100) return this;
2657
+ dirty.textRatio = true;
2658
+ merged.textRatio = value;
2659
+ root.style.setProperty('--hj-text-width', "".concat(value, "%"));
2660
+ return this;
2661
+ },
2662
+ setCssVars: function setCssVars(vars) {
2663
+ if (!vars || _typeof(vars) !== 'object') return this;
2664
+ dirty.cssVars = true;
2665
+ merged.cssVars = _objectSpread2(_objectSpread2({}, merged.cssVars || {}), vars);
2666
+ for (var _i3 = 0, _Object$keys3 = Object.keys(vars); _i3 < _Object$keys3.length; _i3++) {
2667
+ var name = _Object$keys3[_i3];
2668
+ root.style.setProperty(name, vars[name]);
2669
+ }
2670
+ return this;
2671
+ },
2672
+ setLabel: function setLabel(label) {
2673
+ _readOnlyError("customLabel");
2674
+ updateAria();
2675
+ return this;
2676
+ },
2677
+ setValueSuffix: function setValueSuffix(suffix) {
2678
+ controller.setValueSuffix(suffix);
2679
+ return this;
2680
+ },
2233
2681
  setColors: function setColors(colors) {
2234
- if (!Array.isArray(colors) || colors.length !== 4) return this;
2235
- controller.setColors(colors);
2236
- if (overlay) overlay.setColors(colors);
2682
+ var next = Array.isArray(colors) ? colors.map(normalizeColor) : [];
2683
+ if (next.length !== 4 || next.some(function (color) {
2684
+ return !color;
2685
+ })) return this;
2686
+ dirty.colors = true;
2687
+ controller.setColors(next);
2688
+ if (overlay) overlay.setColors(next);
2237
2689
  controller.resizeCanvas();
2238
2690
  return this;
2239
2691
  },
@@ -2263,12 +2715,223 @@ function createProgressCapsule(container) {
2263
2715
  return this;
2264
2716
  },
2265
2717
  dispose: function dispose() {
2718
+ disposed = true;
2266
2719
  unsubscribe();
2267
2720
  visibility.dispose();
2268
2721
  if (overlay) overlay.dispose();
2269
2722
  controller.dispose();
2270
2723
  root.remove();
2724
+ },
2725
+ textRatio: merged.textRatio,
2726
+ cssVars: merged.cssVars,
2727
+ dirty: dirty
2728
+ };
2729
+ }
2730
+
2731
+ function prefersReducedMotion() {
2732
+ return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
2733
+ }
2734
+
2735
+ /**
2736
+ * Mount the cosmic (nebula) material as a background layer inside `host`.
2737
+ *
2738
+ * The layer is absolutely positioned and defaults to `z-index: -1`, so it
2739
+ * paints behind the host's in-flow content: text/buttons/images inside the
2740
+ * host sit on top with zero extra CSS. Host gets `position: relative;
2741
+ * isolation: isolate` automatically so the layer can never escape its box
2742
+ * (or break stacking outside it).
2743
+ *
2744
+ * Options: preset (id/code/name or object), colors, seed, speed, quality,
2745
+ * renderer, mouseColor, respectReducedMotion, opacity (0-1), fallbackColor
2746
+ * (true=preset base color, a hex string, or false to disable).
2747
+ */
2748
+ function createColorBackground(host) {
2749
+ var _options$preset;
2750
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2751
+ if (!host || typeof host.appendChild !== 'function') {
2752
+ throw new Error('createColorBackground: host element is required');
2753
+ }
2754
+ var preset = _objectSpread2({}, getPreset('capsule', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '初光'));
2755
+ var merged = normalizeOptions({
2756
+ quality: DEFAULTS.capsule.quality,
2757
+ renderer: DEFAULTS.capsule.renderer,
2758
+ respectReducedMotion: DEFAULTS.capsule.respectReducedMotion,
2759
+ mouseColor: true,
2760
+ opacity: 1,
2761
+ fallbackColor: true
2762
+ }, preset, options);
2763
+ var normalizedColors = merged.colors.map(normalizeColor);
2764
+ if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
2765
+ preset.seed = merged.seed;
2766
+ preset.speed = merged.speed;
2767
+ var computed = getComputedStyle(host);
2768
+ if (computed.position === 'static' || computed.position === '') {
2769
+ host.style.position = 'relative';
2770
+ }
2771
+ host.style.isolation = 'isolate';
2772
+ var layer = document.createElement('div');
2773
+ layer.className = 'dlc-color-layer';
2774
+ var syncLayerVars = function syncLayerVars() {
2775
+ layer.style.setProperty('--dlc-color-opacity', String(merged.opacity));
2776
+ var fallback = merged.fallbackColor === false || merged.fallbackColor == null ? 'transparent' : typeof merged.fallbackColor === 'string' ? merged.fallbackColor : preset.colors[0];
2777
+ layer.style.setProperty('--dlc-color-bg', fallback);
2778
+ };
2779
+ syncLayerVars();
2780
+ var canvas = document.createElement('canvas');
2781
+ canvas.className = 'dlc-color-canvas';
2782
+ canvas.setAttribute('aria-hidden', 'true');
2783
+ layer.appendChild(canvas);
2784
+ host.appendChild(layer);
2785
+ var emitter = createEmitter();
2786
+ var paused = merged.respectReducedMotion && prefersReducedMotion();
2787
+ var disposed = false;
2788
+ var dirty = {
2789
+ preset: false,
2790
+ seed: false,
2791
+ speed: false,
2792
+ colors: false,
2793
+ opacity: false,
2794
+ fallbackColor: false,
2795
+ mouseColor: false
2796
+ };
2797
+ var renderer;
2798
+ var useWebgl = merged.renderer !== 'canvas2d';
2799
+ if (useWebgl) {
2800
+ try {
2801
+ renderer = new CosmicRenderer(canvas, merged, {
2802
+ dprCap: dprCapFor(merged.quality),
2803
+ mouseColor: merged.mouseColor !== false,
2804
+ eventTarget: host
2805
+ });
2806
+ } catch (error) {
2807
+ renderer = new FallbackRenderer(canvas, merged);
2808
+ nextTick(function () {
2809
+ if (disposed) return;
2810
+ emitter.emit('error', {
2811
+ message: String(error && error.message ? error.message : error)
2812
+ });
2813
+ });
2271
2814
  }
2815
+ } else {
2816
+ renderer = new FallbackRenderer(canvas, merged);
2817
+ }
2818
+ var resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(function () {
2819
+ return renderer.resize();
2820
+ }) : null;
2821
+ if (resizeObserver) resizeObserver.observe(host);else window.addEventListener('resize', renderer.resize);
2822
+ var visibility = createVisibilityGuard(layer);
2823
+ var animationTime = 0;
2824
+ var unsubscribe = subscribeScheduler(function (delta) {
2825
+ animationTime += delta;
2826
+ if (visibility.isVisible()) renderer.draw(animationTime);
2827
+ }, function () {
2828
+ return paused;
2829
+ });
2830
+ nextTick(function () {
2831
+ if (disposed) return;
2832
+ emitter.emit('ready', {
2833
+ preset: _objectSpread2({}, preset)
2834
+ });
2835
+ });
2836
+ return {
2837
+ element: host,
2838
+ layer: layer,
2839
+ canvas: canvas,
2840
+ preset: preset,
2841
+ on: emitter.on,
2842
+ off: emitter.off,
2843
+ setPreset: function setPreset(ref) {
2844
+ var next = getPreset('capsule', ref);
2845
+ dirty.preset = true;
2846
+ Object.assign(preset, next);
2847
+ var nextColors = preset.colors.map(normalizeColor);
2848
+ if (nextColors.every(Boolean)) preset.colors = nextColors;
2849
+ renderer.setPreset(_objectSpread2({}, preset));
2850
+ renderer.resize();
2851
+ syncLayerVars();
2852
+ emitter.emit('presetchange', {
2853
+ preset: _objectSpread2({}, preset)
2854
+ });
2855
+ return this;
2856
+ },
2857
+ setColors: function setColors(colors) {
2858
+ var next = Array.isArray(colors) ? colors.map(normalizeColor) : [];
2859
+ if (next.length !== 4 || next.some(function (color) {
2860
+ return !color;
2861
+ })) return this;
2862
+ dirty.colors = true;
2863
+ preset.colors = next;
2864
+ renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
2865
+ colors: next
2866
+ }));
2867
+ syncLayerVars();
2868
+ return this;
2869
+ },
2870
+ setSeed: function setSeed(seed) {
2871
+ var value = Number(seed);
2872
+ if (!Number.isFinite(value)) return this;
2873
+ dirty.seed = true;
2874
+ preset.seed = value;
2875
+ renderer.setPreset(_objectSpread2({}, preset));
2876
+ return this;
2877
+ },
2878
+ setSpeed: function setSpeed(speed) {
2879
+ var value = Number(speed);
2880
+ if (!Number.isFinite(value)) return this;
2881
+ dirty.speed = true;
2882
+ preset.speed = value;
2883
+ renderer.setPreset(_objectSpread2({}, preset));
2884
+ return this;
2885
+ },
2886
+ setFallbackColor: function setFallbackColor(value) {
2887
+ dirty.fallbackColor = true;
2888
+ merged.fallbackColor = value;
2889
+ syncLayerVars();
2890
+ return this;
2891
+ },
2892
+ setMouseColor: function setMouseColor(value) {
2893
+ dirty.mouseColor = true;
2894
+ merged.mouseColor = value !== false;
2895
+ if (typeof renderer.setMouseColor === 'function') renderer.setMouseColor(merged.mouseColor);
2896
+ return this;
2897
+ },
2898
+ setQuality: function setQuality(quality) {
2899
+ merged.quality = quality;
2900
+ if (typeof renderer.setDprCap === 'function') renderer.setDprCap(dprCapFor(quality));
2901
+ return this;
2902
+ },
2903
+ setOpacity: function setOpacity(value) {
2904
+ var opacity = Number(value);
2905
+ if (!Number.isFinite(opacity)) return this;
2906
+ dirty.opacity = true;
2907
+ merged.opacity = Math.min(1, Math.max(0, opacity));
2908
+ layer.style.setProperty('--dlc-color-opacity', String(merged.opacity));
2909
+ return this;
2910
+ },
2911
+ randomize: function randomize() {
2912
+ this.setSeed(Math.random() * 100);
2913
+ return this;
2914
+ },
2915
+ pause: function pause() {
2916
+ paused = true;
2917
+ return this;
2918
+ },
2919
+ resume: function resume() {
2920
+ paused = false;
2921
+ return this;
2922
+ },
2923
+ dispose: function dispose() {
2924
+ disposed = true;
2925
+ unsubscribe();
2926
+ visibility.dispose();
2927
+ if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', renderer.resize);
2928
+ renderer.dispose();
2929
+ layer.remove();
2930
+ },
2931
+ opacity: merged.opacity,
2932
+ fallbackColor: merged.fallbackColor,
2933
+ mouseColor: merged.mouseColor,
2934
+ dirty: dirty
2272
2935
  };
2273
2936
  }
2274
2937
 
@@ -2280,6 +2943,7 @@ function createProgressCapsule(container) {
2280
2943
 
2281
2944
  var CAPSULE_EVENTS = ['ready', 'error', 'click', 'pointerdown', 'pointerup', 'dblclick', 'pointerenter', 'pointerleave', 'presetchange'];
2282
2945
  var PROGRESS_EVENTS = ['ready', 'error', 'change', 'dragstart', 'dragend', 'presetchange'];
2946
+ var COLOR_EVENTS = ['ready', 'error', 'presetchange'];
2283
2947
  function hookEvents(controller, events, emit) {
2284
2948
  var _iterator = _createForOfIteratorHelper(events),
2285
2949
  _step;
@@ -2310,15 +2974,18 @@ function makeWrapper(_ref) {
2310
2974
  var internalMethods = {
2311
2975
  mountController: function mountController() {
2312
2976
  var _this = this;
2313
- this.controller = create(this.$el, this.$props);
2977
+ var extraState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2978
+ this.controller = create(this.$el, _objectSpread2(_objectSpread2({}, this.$props), extraState));
2314
2979
  hookEvents(this.controller, events, function (event, payload) {
2315
2980
  return _this.$emit(event, payload);
2316
2981
  });
2982
+ this.moveSlots();
2983
+ this.applyAttrs();
2317
2984
  },
2318
2985
  recreate: function recreate() {
2986
+ var extraState = this.runtimeState();
2319
2987
  if (this.controller) this.controller.dispose();
2320
- if (this.$el) this.$el.innerHTML = '';
2321
- this.mountController();
2988
+ this.mountController(extraState);
2322
2989
  },
2323
2990
  scheduleRecreate: function scheduleRecreate() {
2324
2991
  var _this2 = this;
@@ -2328,6 +2995,52 @@ function makeWrapper(_ref) {
2328
2995
  _this2._recreateQueued = false;
2329
2996
  _this2.recreate();
2330
2997
  });
2998
+ },
2999
+ moveSlots: function moveSlots() {
3000
+ if (!this.controller || !this.controller.element || !this.$el) return;
3001
+ var root = this.controller.element;
3002
+ var textLayer = root.querySelector('.hj-capsule-text, .hj-progress-text');
3003
+ var visualLayer = root.querySelector('.hj-capsule-visual, .hj-progress-visual');
3004
+ var move = function move(wrapper, layer) {
3005
+ if (!wrapper || !layer) return;
3006
+ for (var _i = 0, _Array$from = Array.from(wrapper.childNodes); _i < _Array$from.length; _i++) {
3007
+ var node = _Array$from[_i];
3008
+ layer.appendChild(node);
3009
+ }
3010
+ };
3011
+ var refs = this.$refs || {};
3012
+ move(refs.slotText, textLayer);
3013
+ move(refs.slotColor, visualLayer);
3014
+ },
3015
+ applyAttrs: function applyAttrs() {
3016
+ if (!this.controller || !this.controller.element || !this.$attrs) return;
3017
+ var root = this.controller.element;
3018
+ for (var _i2 = 0, _Object$keys = Object.keys(this.$attrs); _i2 < _Object$keys.length; _i2++) {
3019
+ var key = _Object$keys[_i2];
3020
+ if (key === 'class' || key === 'style') continue;
3021
+ var value = this.$attrs[key];
3022
+ if (value == null || value === false) root.removeAttribute(key);else root.setAttribute(key, String(value));
3023
+ }
3024
+ },
3025
+ runtimeState: function runtimeState() {
3026
+ var controller = this.controller;
3027
+ if (!controller || !controller.dirty) return {};
3028
+ var dirty = controller.dirty;
3029
+ var state = {};
3030
+ if (dirty.preset && controller.preset) state.preset = controller.preset.name;
3031
+ if (dirty.seed && controller.preset && controller.preset.seed !== undefined) state.seed = controller.preset.seed;
3032
+ if (dirty.speed && controller.preset && controller.preset.speed !== undefined) state.speed = controller.preset.speed;
3033
+ if (dirty.colors && controller.preset && Array.isArray(controller.preset.colors)) {
3034
+ state.colors = _toConsumableArray(controller.preset.colors);
3035
+ }
3036
+ if (dirty.textRatio && controller.textRatio !== undefined) state.textRatio = controller.textRatio;
3037
+ if (dirty.cssVars && controller.cssVars) state.cssVars = _objectSpread2({}, controller.cssVars);
3038
+ if (dirty.value && typeof controller.getValue === 'function') state.value = controller.getValue();
3039
+ if (dirty.edgeStyle && controller.preset) state.edgeStyle = controller.preset.edgeStyle;
3040
+ if (dirty.opacity) state.opacity = controller.opacity;
3041
+ if (dirty.fallbackColor) state.fallbackColor = controller.fallbackColor;
3042
+ if (dirty.mouseColor) state.mouseColor = controller.mouseColor;
3043
+ return state;
2331
3044
  }
2332
3045
  };
2333
3046
  return {
@@ -2335,6 +3048,7 @@ function makeWrapper(_ref) {
2335
3048
  props: props,
2336
3049
  emits: events,
2337
3050
  render: render,
3051
+ inheritAttrs: false,
2338
3052
  mounted: function mounted() {
2339
3053
  this.mountController();
2340
3054
  },
@@ -2344,6 +3058,10 @@ function makeWrapper(_ref) {
2344
3058
  beforeDestroy: function beforeDestroy() {
2345
3059
  if (this.controller) this.controller.dispose();
2346
3060
  },
3061
+ updated: function updated() {
3062
+ this.moveSlots();
3063
+ this.applyAttrs();
3064
+ },
2347
3065
  watch: _objectSpread2({
2348
3066
  preset: function preset(value) {
2349
3067
  if (value && this.controller) this.controller.setPreset(value);
@@ -2367,7 +3085,7 @@ function makeWrapper(_ref) {
2367
3085
  function makeCapsuleWrapper(createCapsule, render) {
2368
3086
  return makeWrapper({
2369
3087
  name: 'CosmicCapsule',
2370
- props: ['preset', 'width', 'height', 'colors', 'seed', 'speed', 'mouseColor', 'renderer', 'quality', 'respectReducedMotion', 'copy', 'cssVars'],
3088
+ props: ['preset', 'width', 'height', 'colors', 'seed', 'speed', 'textRatio', 'label', 'mouseColor', 'renderer', 'quality', 'respectReducedMotion', 'cssVars'],
2371
3089
  events: CAPSULE_EVENTS,
2372
3090
  create: createCapsule,
2373
3091
  render: render,
@@ -2384,6 +3102,15 @@ function makeCapsuleWrapper(createCapsule, render) {
2384
3102
  this.controller.setSpeed(speed);
2385
3103
  }
2386
3104
  },
3105
+ textRatio: function textRatio(value) {
3106
+ if (value !== undefined && this.controller) this.controller.setTextRatio(Number(value));
3107
+ },
3108
+ cssVars: function cssVars(value) {
3109
+ if (value && this.controller) this.controller.setCssVars(value);
3110
+ },
3111
+ label: function label(value) {
3112
+ if (this.controller) this.controller.setLabel(value);
3113
+ },
2387
3114
  mouseColor: function mouseColor() {
2388
3115
  this.scheduleRecreate();
2389
3116
  },
@@ -2410,6 +3137,21 @@ function makeCapsuleWrapper(createCapsule, render) {
2410
3137
  setColors: function setColors(colors) {
2411
3138
  return this.controller && this.controller.setColors(colors);
2412
3139
  },
3140
+ setText: function setText(content) {
3141
+ return this.controller && this.controller.setText(content);
3142
+ },
3143
+ setColorContent: function setColorContent(content) {
3144
+ return this.controller && this.controller.setColorContent(content);
3145
+ },
3146
+ setTextRatio: function setTextRatio(ratio) {
3147
+ return this.controller && this.controller.setTextRatio(ratio);
3148
+ },
3149
+ setCssVars: function setCssVars(vars) {
3150
+ return this.controller && this.controller.setCssVars(vars);
3151
+ },
3152
+ setLabel: function setLabel(label) {
3153
+ return this.controller && this.controller.setLabel(label);
3154
+ },
2413
3155
  setQuality: function setQuality(quality) {
2414
3156
  return this.controller && this.controller.setQuality(quality);
2415
3157
  },
@@ -2422,7 +3164,7 @@ function makeCapsuleWrapper(createCapsule, render) {
2422
3164
  function makeProgressWrapper(createProgressCapsule, render) {
2423
3165
  return makeWrapper({
2424
3166
  name: 'ProgressCapsule',
2425
- props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'edgeStyle', 'colors', 'quality', 'renderer', 'respectReducedMotion', 'copy', 'cssVars'],
3167
+ props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'disabled', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
2426
3168
  events: PROGRESS_EVENTS,
2427
3169
  create: createProgressCapsule,
2428
3170
  render: render,
@@ -2439,6 +3181,24 @@ function makeProgressWrapper(createProgressCapsule, render) {
2439
3181
  edgeStyle: function edgeStyle(value) {
2440
3182
  if (value && this.controller) this.controller.setEdgeStyle(value);
2441
3183
  },
3184
+ textRatio: function textRatio(value) {
3185
+ if (value !== undefined && this.controller) this.controller.setTextRatio(Number(value));
3186
+ },
3187
+ cssVars: function cssVars(value) {
3188
+ if (value && this.controller) this.controller.setCssVars(value);
3189
+ },
3190
+ label: function label(value) {
3191
+ if (this.controller) this.controller.setLabel(value);
3192
+ },
3193
+ valueSuffix: function valueSuffix(value) {
3194
+ if (value !== undefined && this.controller) this.controller.setValueSuffix(value);
3195
+ },
3196
+ showValue: function showValue() {
3197
+ this.scheduleRecreate();
3198
+ },
3199
+ disabled: function disabled() {
3200
+ this.scheduleRecreate();
3201
+ },
2442
3202
  draggable: function draggable() {
2443
3203
  this.scheduleRecreate();
2444
3204
  },
@@ -2477,9 +3237,99 @@ function makeProgressWrapper(createProgressCapsule, render) {
2477
3237
  setColors: function setColors(colors) {
2478
3238
  return this.controller && this.controller.setColors(colors);
2479
3239
  },
3240
+ setText: function setText(content) {
3241
+ return this.controller && this.controller.setText(content);
3242
+ },
3243
+ setColorContent: function setColorContent(content) {
3244
+ return this.controller && this.controller.setColorContent(content);
3245
+ },
3246
+ setTextRatio: function setTextRatio(ratio) {
3247
+ return this.controller && this.controller.setTextRatio(ratio);
3248
+ },
3249
+ setCssVars: function setCssVars(vars) {
3250
+ return this.controller && this.controller.setCssVars(vars);
3251
+ },
3252
+ setLabel: function setLabel(label) {
3253
+ return this.controller && this.controller.setLabel(label);
3254
+ },
3255
+ setValueSuffix: function setValueSuffix(suffix) {
3256
+ return this.controller && this.controller.setValueSuffix(suffix);
3257
+ },
3258
+ setQuality: function setQuality(quality) {
3259
+ return this.controller && this.controller.setQuality(quality);
3260
+ },
3261
+ getController: function getController() {
3262
+ return this.controller;
3263
+ }
3264
+ }
3265
+ });
3266
+ }
3267
+ function makeColorWrapper(createColorBackground, render) {
3268
+ return makeWrapper({
3269
+ name: 'ColorBackground',
3270
+ props: ['preset', 'colors', 'seed', 'speed', 'quality', 'renderer', 'mouseColor', 'respectReducedMotion', 'opacity', 'fallbackColor'],
3271
+ events: COLOR_EVENTS,
3272
+ create: createColorBackground,
3273
+ render: render,
3274
+ watch: {
3275
+ seed: function seed(value) {
3276
+ var seed = Number(value);
3277
+ if (this.controller && Number.isFinite(seed)) this.controller.setSeed(seed);
3278
+ },
3279
+ speed: function speed(value) {
3280
+ var speed = Number(value);
3281
+ if (this.controller && Number.isFinite(speed)) this.controller.setSpeed(speed);
3282
+ },
3283
+ opacity: function opacity(value) {
3284
+ if (value !== undefined && this.controller) this.controller.setOpacity(Number(value));
3285
+ },
3286
+ fallbackColor: function fallbackColor(value) {
3287
+ if (this.controller) this.controller.setFallbackColor(value);
3288
+ },
3289
+ mouseColor: function mouseColor(value) {
3290
+ if (this.controller) this.controller.setMouseColor(value);
3291
+ },
3292
+ renderer: function renderer() {
3293
+ this.scheduleRecreate();
3294
+ },
3295
+ respectReducedMotion: function respectReducedMotion() {
3296
+ this.scheduleRecreate();
3297
+ }
3298
+ },
3299
+ methods: {
3300
+ setPreset: function setPreset(preset) {
3301
+ return this.controller && this.controller.setPreset(preset);
3302
+ },
3303
+ setColors: function setColors(colors) {
3304
+ return this.controller && this.controller.setColors(colors);
3305
+ },
3306
+ setSeed: function setSeed(seed) {
3307
+ return this.controller && this.controller.setSeed(seed);
3308
+ },
3309
+ setSpeed: function setSpeed(speed) {
3310
+ return this.controller && this.controller.setSpeed(speed);
3311
+ },
2480
3312
  setQuality: function setQuality(quality) {
2481
3313
  return this.controller && this.controller.setQuality(quality);
2482
3314
  },
3315
+ setOpacity: function setOpacity(value) {
3316
+ return this.controller && this.controller.setOpacity(value);
3317
+ },
3318
+ setFallbackColor: function setFallbackColor(value) {
3319
+ return this.controller && this.controller.setFallbackColor(value);
3320
+ },
3321
+ setMouseColor: function setMouseColor(value) {
3322
+ return this.controller && this.controller.setMouseColor(value);
3323
+ },
3324
+ randomize: function randomize() {
3325
+ return this.controller && this.controller.randomize();
3326
+ },
3327
+ pause: function pause() {
3328
+ return this.controller && this.controller.pause();
3329
+ },
3330
+ resume: function resume() {
3331
+ return this.controller && this.controller.resume();
3332
+ },
2483
3333
  getController: function getController() {
2484
3334
  return this.controller;
2485
3335
  }
@@ -2487,14 +3337,31 @@ function makeProgressWrapper(createProgressCapsule, render) {
2487
3337
  });
2488
3338
  }
2489
3339
 
2490
- // Vue2 passes `h` (createElement) as the first argument to render.
3340
+ // Vue2 passes `h` (createElement) as the first argument to render. Slot
3341
+ // content is rendered into two marker wrappers, then moved into the
3342
+ // component's slot containers by the wrapper (moveSlots).
2491
3343
  var render = function render(h) {
2492
3344
  return h('div', {
2493
3345
  class: 'hj-vue-host'
2494
- });
3346
+ }, [h('div', {
3347
+ class: 'hj-vue-slot-text',
3348
+ ref: 'slotText'
3349
+ }, this.$slots.default), h('div', {
3350
+ class: 'hj-vue-slot-color',
3351
+ ref: 'slotColor'
3352
+ }, this.$slots.color)]);
3353
+ };
3354
+
3355
+ // Color 的宿主内容就是组件内容:直接放在 host 里,浮在背景层上方。
3356
+ var renderColor = function renderColor(h) {
3357
+ return h('div', {
3358
+ class: 'hj-vue-host'
3359
+ }, this.$slots.default);
2495
3360
  };
2496
3361
  var CosmicCapsule = makeCapsuleWrapper(createCapsule, render);
2497
3362
  var ProgressCapsule = makeProgressWrapper(createProgressCapsule, render);
3363
+ var ColorBackground = makeColorWrapper(createColorBackground, renderColor);
2498
3364
 
3365
+ exports.ColorBackground = ColorBackground;
2499
3366
  exports.CosmicCapsule = CosmicCapsule;
2500
3367
  exports.ProgressCapsule = ProgressCapsule;