@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/capsule.cjs CHANGED
@@ -428,34 +428,225 @@ var DEFAULTS = {
428
428
  renderer: 'auto',
429
429
  respectReducedMotion: true,
430
430
  mouseColor: true,
431
- showCopy: true
431
+ textRatio: 39
432
432
  }};
433
433
 
434
- /**
435
- * All user-facing copy lives here so wording/brand changes never require a
436
- * global search. Templates use {brand} {code} {name} placeholders.
434
+ /**
435
+ * Internal accessibility labels and small UI text. Since the copy API was
436
+ * removed (slots own the text area), these are no longer user-overridable.
437
+ * Templates use {brand} {code} {name} placeholders.
437
438
  */
438
439
  var COPY = {
439
- brandName: '画境观屿',
440
- dragLabel: 'DRAG',
441
- valueSuffix: '%',
442
- progressAria: '{brand} {code} 加载进度',
443
440
  capsuleAria: '打开 {name} 沉浸预览'
444
441
  };
445
442
 
446
- function hexToRgb01(hex) {
447
- var normalized = hex.replace('#', '');
448
- var value = Number.parseInt(normalized, 16);
449
- return [(value >> 16 & 255) / 255, (value >> 8 & 255) / 255, (value & 255) / 255];
443
+ /**
444
+ * Color helpers. `normalizeColor` converts any supported CSS color
445
+ * (hex / named / rgb() / rgba()) into a 6-digit hex string, so renderers can
446
+ * keep working with #rrggbb only. rgba() alpha is intentionally dropped:
447
+ * the WebGL shader has no per-color alpha channel, and the component is
448
+ * opaque by design — use component-level `opacity` for transparency.
449
+ */
450
+
451
+ var NAMED_COLORS = {
452
+ aliceblue: '#f0f8ff',
453
+ antiquewhite: '#faebd7',
454
+ aqua: '#00ffff',
455
+ aquamarine: '#7fffd4',
456
+ azure: '#f0ffff',
457
+ beige: '#f5f5dc',
458
+ bisque: '#ffe4c4',
459
+ black: '#000000',
460
+ blanchedalmond: '#ffebcd',
461
+ blue: '#0000ff',
462
+ blueviolet: '#8a2be2',
463
+ brown: '#a52a2a',
464
+ burlywood: '#deb887',
465
+ cadetblue: '#5f9ea0',
466
+ chartreuse: '#7fff00',
467
+ chocolate: '#d2691e',
468
+ coral: '#ff7f50',
469
+ cornflowerblue: '#6495ed',
470
+ cornsilk: '#fff8dc',
471
+ crimson: '#dc143c',
472
+ cyan: '#00ffff',
473
+ darkblue: '#00008b',
474
+ darkcyan: '#008b8b',
475
+ darkgoldenrod: '#b8860b',
476
+ darkgray: '#a9a9a9',
477
+ darkgreen: '#006400',
478
+ darkgrey: '#a9a9a9',
479
+ darkkhaki: '#bdb76b',
480
+ darkmagenta: '#8b008b',
481
+ darkolivegreen: '#556b2f',
482
+ darkorange: '#ff8c00',
483
+ darkorchid: '#9932cc',
484
+ darkred: '#8b0000',
485
+ darksalmon: '#e9967a',
486
+ darkseagreen: '#8fbc8f',
487
+ darkslateblue: '#483d8b',
488
+ darkslategray: '#2f4f4f',
489
+ darkslategrey: '#2f4f4f',
490
+ darkturquoise: '#00ced1',
491
+ darkviolet: '#9400d3',
492
+ deeppink: '#ff1493',
493
+ deepskyblue: '#00bfff',
494
+ dimgray: '#696969',
495
+ dimgrey: '#696969',
496
+ dodgerblue: '#1e90ff',
497
+ firebrick: '#b22222',
498
+ floralwhite: '#fffaf0',
499
+ forestgreen: '#228b22',
500
+ fuchsia: '#ff00ff',
501
+ gainsboro: '#dcdcdc',
502
+ ghostwhite: '#f8f8ff',
503
+ gold: '#ffd700',
504
+ goldenrod: '#daa520',
505
+ gray: '#808080',
506
+ green: '#008000',
507
+ greenyellow: '#adff2f',
508
+ grey: '#808080',
509
+ honeydew: '#f0fff0',
510
+ hotpink: '#ff69b4',
511
+ indianred: '#cd5c5c',
512
+ indigo: '#4b0082',
513
+ ivory: '#fffff0',
514
+ khaki: '#f0e68c',
515
+ lavender: '#e6e6fa',
516
+ lavenderblush: '#fff0f5',
517
+ lawngreen: '#7cfc00',
518
+ lemonchiffon: '#fffacd',
519
+ lightblue: '#add8e6',
520
+ lightcoral: '#f08080',
521
+ lightcyan: '#e0ffff',
522
+ lightgoldenrodyellow: '#fafad2',
523
+ lightgray: '#d3d3d3',
524
+ lightgreen: '#90ee90',
525
+ lightgrey: '#d3d3d3',
526
+ lightpink: '#ffb6c1',
527
+ lightsalmon: '#ffa07a',
528
+ lightseagreen: '#20b2aa',
529
+ lightskyblue: '#87cefa',
530
+ lightslategray: '#778899',
531
+ lightslategrey: '#778899',
532
+ lightsteelblue: '#b0c4de',
533
+ lightyellow: '#ffffe0',
534
+ lime: '#00ff00',
535
+ limegreen: '#32cd32',
536
+ linen: '#faf0e6',
537
+ magenta: '#ff00ff',
538
+ maroon: '#800000',
539
+ mediumaquamarine: '#66cdaa',
540
+ mediumblue: '#0000cd',
541
+ mediumorchid: '#ba55d3',
542
+ mediumpurple: '#9370db',
543
+ mediumseagreen: '#3cb371',
544
+ mediumslateblue: '#7b68ee',
545
+ mediumspringgreen: '#00fa9a',
546
+ mediumturquoise: '#48d1cc',
547
+ mediumvioletred: '#c71585',
548
+ midnightblue: '#191970',
549
+ mintcream: '#f5fffa',
550
+ mistyrose: '#ffe4e1',
551
+ moccasin: '#ffe4b5',
552
+ navajowhite: '#ffdead',
553
+ navy: '#000080',
554
+ oldlace: '#fdf5e6',
555
+ olive: '#808000',
556
+ olivedrab: '#6b8e23',
557
+ orange: '#ffa500',
558
+ orangered: '#ff4500',
559
+ orchid: '#da70d6',
560
+ palegoldenrod: '#eee8aa',
561
+ palegreen: '#98fb98',
562
+ paleturquoise: '#afeeee',
563
+ palevioletred: '#db7093',
564
+ papayawhip: '#ffefd5',
565
+ peachpuff: '#ffdab9',
566
+ peru: '#cd853f',
567
+ pink: '#ffc0cb',
568
+ plum: '#dda0dd',
569
+ powderblue: '#b0e0e6',
570
+ purple: '#800080',
571
+ rebeccapurple: '#663399',
572
+ red: '#ff0000',
573
+ rosybrown: '#bc8f8f',
574
+ royalblue: '#4169e1',
575
+ saddlebrown: '#8b4513',
576
+ salmon: '#fa8072',
577
+ sandybrown: '#f4a460',
578
+ seagreen: '#2e8b57',
579
+ seashell: '#fff5ee',
580
+ sienna: '#a0522d',
581
+ silver: '#c0c0c0',
582
+ skyblue: '#87ceeb',
583
+ slateblue: '#6a5acd',
584
+ slategray: '#708090',
585
+ slategrey: '#708090',
586
+ snow: '#fffafa',
587
+ springgreen: '#00ff7f',
588
+ steelblue: '#4682b4',
589
+ tan: '#d2b48c',
590
+ teal: '#008080',
591
+ thistle: '#d8bfd8',
592
+ tomato: '#ff6347',
593
+ turquoise: '#40e0d0',
594
+ violet: '#ee82ee',
595
+ wheat: '#f5deb3',
596
+ white: '#ffffff',
597
+ whitesmoke: '#f5f5f5',
598
+ yellow: '#ffff00',
599
+ yellowgreen: '#9acd32'
600
+ };
601
+ function clampChannel(value) {
602
+ return Math.min(255, Math.max(0, Math.round(value)));
450
603
  }
451
- function hexToRgba(hex) {
452
- var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
453
- var normalized = hex.replace('#', '');
454
- var value = Number.parseInt(normalized, 16);
455
- var red = value >> 16 & 255;
456
- var green = value >> 8 & 255;
457
- var blue = value & 255;
458
- return "rgba(".concat(red, ", ").concat(green, ", ").concat(blue, ", ").concat(alpha, ")");
604
+ function normalizeRgbArgs(args) {
605
+ var parts = args.split(/[,\s/]+/).filter(Boolean);
606
+ if (parts.length < 3) return null;
607
+ var to255 = function to255(value) {
608
+ if (typeof value !== 'string' || !value) return null;
609
+ if (value.endsWith('%')) return clampChannel(parseFloat(value) / 100 * 255);
610
+ var number = Number(value);
611
+ return Number.isFinite(number) ? clampChannel(number) : null;
612
+ };
613
+ var red = to255(parts[0]);
614
+ var green = to255(parts[1]);
615
+ var blue = to255(parts[2]);
616
+ if (red === null || green === null || blue === null) return null;
617
+ return "#".concat([red, green, blue].map(function (n) {
618
+ return n.toString(16).padStart(2, '0');
619
+ }).join(''));
620
+ }
621
+
622
+ /**
623
+ * Convert any supported CSS color into `#rrggbb`. Returns null when the
624
+ * value cannot be parsed. Supports: #rgb / #rrggbb (case-insensitive),
625
+ * CSS named colors, rgb() / rgba() with comma or modern space syntax,
626
+ * including percentages. Alpha in rgba() is ignored.
627
+ */
628
+ function normalizeColor(value) {
629
+ if (typeof value !== 'string') return null;
630
+ var input = value.trim();
631
+ if (!input) return null;
632
+ var lower = input.toLowerCase();
633
+ if (NAMED_COLORS[lower]) return NAMED_COLORS[lower];
634
+ if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(input)) {
635
+ var hex = input.slice(1).toLowerCase();
636
+ if (hex.length === 3) return "#".concat(hex.split('').map(function (c) {
637
+ return c + c;
638
+ }).join(''));
639
+ return "#".concat(hex);
640
+ }
641
+ var match = input.match(/^rgba?\((.*)\)$/i);
642
+ if (match) return normalizeRgbArgs(match[1]);
643
+ return null;
644
+ }
645
+ function hexToRgb01(color) {
646
+ var hex = normalizeColor(color);
647
+ if (!hex) return [0, 0, 0];
648
+ var value = Number.parseInt(hex.slice(1), 16);
649
+ return [(value >> 16 & 255) / 255, (value >> 8 & 255) / 255, (value & 255) / 255];
459
650
  }
460
651
 
461
652
  var VERTEX_SHADER = "#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}";
@@ -532,6 +723,26 @@ var CosmicRenderer = /*#__PURE__*/function () {
532
723
  this.options.dprCap = cap;
533
724
  this.resize();
534
725
  }
726
+ }, {
727
+ key: "setMouseColor",
728
+ value: function setMouseColor(enabled) {
729
+ this.options.mouseColor = enabled !== false;
730
+ if (this.options.mouseColor) {
731
+ if (this.onPointerMove) return this;
732
+ _assertClassBrand(_CosmicRenderer_brand, this, _bindEvents).call(this);
733
+ return this;
734
+ }
735
+ if (this.onPointerMove) {
736
+ var target = this.eventTarget;
737
+ target.removeEventListener('pointermove', this.onPointerMove);
738
+ target.removeEventListener('pointerdown', this.onPointerMove);
739
+ target.removeEventListener('pointerleave', this.onPointerLeave);
740
+ this.onPointerMove = null;
741
+ this.onPointerLeave = null;
742
+ }
743
+ this.motionTarget = 0;
744
+ return this;
745
+ }
535
746
  }, {
536
747
  key: "randomize",
537
748
  value: function randomize() {
@@ -680,6 +891,8 @@ var FallbackRenderer = /*#__PURE__*/function () {
680
891
  var _this$canvas = this.canvas,
681
892
  width = _this$canvas.width,
682
893
  height = _this$canvas.height;
894
+ var t = time * (this.preset.speed || 1);
895
+ var phase = (this.preset.seed || 0) * 0.7;
683
896
  var gradient = ctx.createLinearGradient(0, 0, width, height);
684
897
  gradient.addColorStop(0, this.preset.colors[0]);
685
898
  gradient.addColorStop(0.38, this.preset.colors[1]);
@@ -689,8 +902,8 @@ var FallbackRenderer = /*#__PURE__*/function () {
689
902
  ctx.fillRect(0, 0, width, height);
690
903
  ctx.globalCompositeOperation = 'screen';
691
904
  for (var index = 0; index < 6; index += 1) {
692
- var x = (0.5 + 0.45 * Math.sin(time * 0.32 + index * 1.7)) * width;
693
- var y = (0.5 + 0.4 * Math.cos(time * 0.25 + index)) * height;
905
+ var x = (0.5 + 0.45 * Math.sin(t * 0.32 + index * 1.7 + phase)) * width;
906
+ var y = (0.5 + 0.4 * Math.cos(t * 0.25 + index + phase)) * height;
694
907
  var radius = Math.max(width, height) * (0.08 + index % 3 * 0.04);
695
908
  var glow = ctx.createRadialGradient(x, y, 0, x, y, radius);
696
909
  glow.addColorStop(0, rgb(this.preset.colors[(index + 1) % 4], 0.24));
@@ -714,7 +927,12 @@ var FallbackRenderer = /*#__PURE__*/function () {
714
927
  }
715
928
  }, {
716
929
  key: "randomize",
717
- value: function randomize() {}
930
+ value: function randomize() {
931
+ if (this.preset) this.preset.seed = Math.random() * 100;
932
+ }
933
+ }, {
934
+ key: "setMouseColor",
935
+ value: function setMouseColor() {}
718
936
  }, {
719
937
  key: "dispose",
720
938
  value: function dispose() {}
@@ -825,16 +1043,34 @@ function createVisibilityGuard(element) {
825
1043
  };
826
1044
  }
827
1045
 
1046
+ /**
1047
+ * Run a callback asynchronously, right after the current task and before the
1048
+ * next paint. Used for mount-time events (ready / error) so listeners that
1049
+ * are attached after create() still receive them. Falls back for legacy
1050
+ * browsers that lack queueMicrotask / Promise.
1051
+ */
1052
+ function nextTick(fn) {
1053
+ if (typeof queueMicrotask === 'function') {
1054
+ queueMicrotask(fn);
1055
+ } else if (typeof Promise !== 'undefined' && typeof Promise.resolve === 'function') {
1056
+ Promise.resolve().then(fn);
1057
+ } else {
1058
+ setTimeout(fn, 0);
1059
+ }
1060
+ }
1061
+
828
1062
  function prefersReducedMotion() {
829
1063
  return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
830
1064
  }
831
1065
 
832
1066
  /**
833
- * Mount a cosmic (nebula) capsule into `container`.
834
- *
835
- * Options: preset (id/code/name or object), width, height (number=px or
836
- * string with px/%/vw/vh/em/rem), colors, seed, speed, quality,
837
- * respectReducedMotion, copy, cssVars.
1067
+ * Mount a cosmic (nebula) capsule into `container`.
1068
+ *
1069
+ * Options: preset (literary name), width, height (number=px or string with
1070
+ * px/%/vw/vh/em/rem), colors, seed, speed, textRatio (0-100, text region
1071
+ * width in percent), text (HTML string or DOM nodes for the text slot),
1072
+ * colorContent (HTML string or DOM nodes for the color slot), quality,
1073
+ * renderer, respectReducedMotion, mouseColor, cssVars.
838
1074
  */
839
1075
  function createCapsule(container) {
840
1076
  var _options$preset;
@@ -844,51 +1080,71 @@ function createCapsule(container) {
844
1080
  }
845
1081
  var preset = _objectSpread2({}, getPreset('capsule', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '初光'));
846
1082
  var merged = normalizeOptions(DEFAULTS.capsule, preset, options);
847
- var copy = _objectSpread2(_objectSpread2({}, COPY), merged.copy || {});
1083
+ var normalizedColors = merged.colors.map(normalizeColor);
1084
+ if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
1085
+ preset.seed = merged.seed;
1086
+ preset.speed = merged.speed;
1087
+ var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
848
1088
  var root = document.createElement('div');
849
1089
  root.className = 'hj-capsule-root hj-capsule-cosmic';
850
1090
  root.dataset.group = preset.group;
851
1091
  root.dataset.mode = 'nebula';
852
1092
  root.dataset.theme = preset.theme || 'light';
853
- root.setAttribute('aria-label', copy.capsuleAria.replace('{name}', preset.name));
854
- var copyEnabled = copy.enabled !== false && merged.showCopy !== false;
855
- var copyText = function copyText(key, fallback) {
856
- var value = copy[key];
857
- return value === undefined ? fallback : value;
858
- };
859
- function buildCopyHtml() {
860
- var codeText = copyText('code', preset.code);
861
- var nameText = copyText('name', preset.name);
862
- var subtitleText = copyText('subtitle', preset.subtitle);
863
- var stateText = copyText('state', 'LIVE COSMIC STUDY');
864
- var html = '';
865
- if (codeText) html += "<span class=\"hj-capsule-code\">".concat(codeText, "</span>");
866
- if (nameText) html += "<span class=\"hj-capsule-name\">".concat(nameText, "</span>");
867
- if (subtitleText) html += "<span class=\"hj-capsule-brand\">".concat(subtitleText, "</span>");
868
- if (stateText) html += "<span class=\"hj-capsule-state\">".concat(stateText, "</span>");
869
- return html;
870
- }
871
- var copyLayer = document.createElement('div');
872
- copyLayer.className = 'hj-capsule-copy';
873
- var renderCopy = function renderCopy() {
874
- if (copyEnabled) copyLayer.innerHTML = buildCopyHtml();
1093
+ root.setAttribute('role', 'img');
1094
+ var updateAria = function updateAria() {
1095
+ root.setAttribute('aria-label', customLabel || COPY.capsuleAria.replace('{name}', preset.name));
875
1096
  };
876
- renderCopy();
877
- var isHexColor = function isHexColor(value) {
878
- return typeof value === 'string' && /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(value);
1097
+ updateAria();
1098
+
1099
+ // Slot containers are always present but transparent by default: without
1100
+ // content they are invisible, so "no slot" behaves like the old
1101
+ // showCopy=false. They only provide geometry — no typography, padding or
1102
+ // background is imposed on user content (see docs: 插槽 CSS 约定).
1103
+ var fillContent = function fillContent(layer, content) {
1104
+ layer.innerHTML = '';
1105
+ if (content == null) return;
1106
+ if (typeof content === 'string') {
1107
+ layer.innerHTML = content;
1108
+ return;
1109
+ }
1110
+ var nodes = Array.isArray(content) ? content : [content];
1111
+ var _iterator = _createForOfIteratorHelper(nodes),
1112
+ _step;
1113
+ try {
1114
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1115
+ var node = _step.value;
1116
+ if (node && typeof node.nodeType === 'number') layer.appendChild(node);
1117
+ }
1118
+ } catch (err) {
1119
+ _iterator.e(err);
1120
+ } finally {
1121
+ _iterator.f();
1122
+ }
879
1123
  };
880
- if (copy.background) {
881
- 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);
882
- }
883
- if (copy.color) root.style.setProperty('--hj-copy-color', copy.color);
1124
+ var textLayer = document.createElement('div');
1125
+ textLayer.className = 'hj-capsule-text hj-capsule-copy';
1126
+ var visualLayer = document.createElement('div');
1127
+ visualLayer.className = 'hj-capsule-visual';
1128
+ fillContent(textLayer, options.text);
1129
+ fillContent(visualLayer, options.colorContent);
884
1130
  var canvas = document.createElement('canvas');
885
1131
  canvas.className = 'hj-capsule-canvas';
886
1132
  canvas.setAttribute('aria-hidden', 'true');
887
- if (copyEnabled) root.appendChild(copyLayer);
1133
+ root.appendChild(textLayer);
1134
+ root.appendChild(visualLayer);
888
1135
  root.appendChild(canvas);
889
1136
  container.appendChild(root);
890
1137
  var emitter = createEmitter();
891
1138
  var paused = merged.respectReducedMotion && prefersReducedMotion();
1139
+ var disposed = false;
1140
+ var dirty = {
1141
+ preset: false,
1142
+ seed: false,
1143
+ speed: false,
1144
+ colors: false,
1145
+ textRatio: false,
1146
+ cssVars: false
1147
+ };
892
1148
  var renderer;
893
1149
  var useWebgl = merged.renderer !== 'canvas2d';
894
1150
  if (useWebgl) {
@@ -898,8 +1154,11 @@ function createCapsule(container) {
898
1154
  });
899
1155
  } catch (error) {
900
1156
  renderer = new FallbackRenderer(canvas, merged);
901
- emitter.emit('error', {
902
- message: String(error && error.message ? error.message : error)
1157
+ nextTick(function () {
1158
+ if (disposed) return;
1159
+ emitter.emit('error', {
1160
+ message: String(error && error.message ? error.message : error)
1161
+ });
903
1162
  });
904
1163
  }
905
1164
  } else {
@@ -913,6 +1172,9 @@ function createCapsule(container) {
913
1172
  var name = _Object$keys[_i];
914
1173
  root.style.setProperty(name, vars[name]);
915
1174
  }
1175
+ if (merged.textRatio !== undefined) {
1176
+ root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
1177
+ }
916
1178
  renderer.resize();
917
1179
  };
918
1180
  applySize();
@@ -962,13 +1224,16 @@ function createCapsule(container) {
962
1224
  }, function () {
963
1225
  return paused;
964
1226
  });
965
- emitter.emit('ready', {
966
- preset: _objectSpread2({}, preset)
1227
+ nextTick(function () {
1228
+ if (disposed) return;
1229
+ emitter.emit('ready', {
1230
+ preset: _objectSpread2({}, preset)
1231
+ });
967
1232
  });
968
- var syncCopy = function syncCopy() {
1233
+ var syncTheme = function syncTheme() {
969
1234
  root.dataset.mode = 'nebula';
970
1235
  root.dataset.theme = preset.theme || 'light';
971
- renderCopy();
1236
+ updateAria();
972
1237
  };
973
1238
  return {
974
1239
  element: root,
@@ -978,9 +1243,12 @@ function createCapsule(container) {
978
1243
  off: emitter.off,
979
1244
  setPreset: function setPreset(ref) {
980
1245
  var next = getPreset('capsule', ref);
1246
+ dirty.preset = true;
981
1247
  Object.assign(preset, next);
982
- renderer.setPreset(next);
983
- syncCopy();
1248
+ var nextColors = preset.colors.map(normalizeColor);
1249
+ if (nextColors.every(Boolean)) preset.colors = nextColors;
1250
+ renderer.setPreset(_objectSpread2({}, preset));
1251
+ syncTheme();
984
1252
  renderer.resize();
985
1253
  emitter.emit('presetchange', {
986
1254
  preset: _objectSpread2({}, next)
@@ -988,16 +1256,21 @@ function createCapsule(container) {
988
1256
  return this;
989
1257
  },
990
1258
  setColors: function setColors(colors) {
991
- if (!Array.isArray(colors) || colors.length !== 4) return this;
992
- preset.colors = colors;
1259
+ var next = Array.isArray(colors) ? colors.map(normalizeColor) : [];
1260
+ if (next.length !== 4 || next.some(function (color) {
1261
+ return !color;
1262
+ })) return this;
1263
+ dirty.colors = true;
1264
+ preset.colors = next;
993
1265
  renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
994
- colors: colors
1266
+ colors: next
995
1267
  }));
996
1268
  return this;
997
1269
  },
998
1270
  setSeed: function setSeed(seed) {
999
1271
  var value = Number(seed);
1000
1272
  if (!Number.isFinite(value)) return this;
1273
+ dirty.seed = true;
1001
1274
  preset.seed = value;
1002
1275
  renderer.setPreset(_objectSpread2({}, preset));
1003
1276
  return this;
@@ -1005,10 +1278,42 @@ function createCapsule(container) {
1005
1278
  setSpeed: function setSpeed(speed) {
1006
1279
  var value = Number(speed);
1007
1280
  if (!Number.isFinite(value)) return this;
1281
+ dirty.speed = true;
1008
1282
  preset.speed = value;
1009
1283
  renderer.setPreset(_objectSpread2({}, preset));
1010
1284
  return this;
1011
1285
  },
1286
+ setText: function setText(content) {
1287
+ fillContent(textLayer, content);
1288
+ return this;
1289
+ },
1290
+ setColorContent: function setColorContent(content) {
1291
+ fillContent(visualLayer, content);
1292
+ return this;
1293
+ },
1294
+ setTextRatio: function setTextRatio(ratio) {
1295
+ var value = Number(ratio);
1296
+ if (!Number.isFinite(value) || value < 0 || value > 100) return this;
1297
+ dirty.textRatio = true;
1298
+ merged.textRatio = value;
1299
+ root.style.setProperty('--hj-text-width', "".concat(value, "%"));
1300
+ return this;
1301
+ },
1302
+ setCssVars: function setCssVars(vars) {
1303
+ if (!vars || _typeof(vars) !== 'object') return this;
1304
+ dirty.cssVars = true;
1305
+ merged.cssVars = _objectSpread2(_objectSpread2({}, merged.cssVars || {}), vars);
1306
+ for (var _i2 = 0, _Object$keys2 = Object.keys(vars); _i2 < _Object$keys2.length; _i2++) {
1307
+ var name = _Object$keys2[_i2];
1308
+ root.style.setProperty(name, vars[name]);
1309
+ }
1310
+ return this;
1311
+ },
1312
+ setLabel: function setLabel(label) {
1313
+ customLabel = typeof label === 'string' && label ? label : null;
1314
+ updateAria();
1315
+ return this;
1316
+ },
1012
1317
  setSize: function setSize(width, height) {
1013
1318
  if (width !== undefined) merged.width = width;
1014
1319
  if (height !== undefined) merged.height = height;
@@ -1016,7 +1321,7 @@ function createCapsule(container) {
1016
1321
  return this;
1017
1322
  },
1018
1323
  randomize: function randomize() {
1019
- renderer.randomize();
1324
+ this.setSeed(Math.random() * 100);
1020
1325
  return this;
1021
1326
  },
1022
1327
  pause: function pause() {
@@ -1033,12 +1338,16 @@ function createCapsule(container) {
1033
1338
  return this;
1034
1339
  },
1035
1340
  dispose: function dispose() {
1341
+ disposed = true;
1036
1342
  unsubscribe();
1037
1343
  visibility.dispose();
1038
1344
  if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', renderer.resize);
1039
1345
  renderer.dispose();
1040
1346
  root.remove();
1041
- }
1347
+ },
1348
+ textRatio: merged.textRatio,
1349
+ cssVars: merged.cssVars,
1350
+ dirty: dirty
1042
1351
  };
1043
1352
  }
1044
1353