@5even7/dlc-ui 0.2.0 → 0.2.2

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