@5even7/dlc-ui 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -42
- package/LICENSE +21 -21
- package/README.md +258 -255
- package/dist/capsule.cjs +307 -71
- package/dist/capsule.mjs +828 -604
- package/dist/color.cjs +338 -82
- package/dist/color.mjs +879 -631
- package/dist/index.cjs +997 -253
- package/dist/index.mjs +2704 -1976
- package/dist/index.umd.js +997 -253
- package/dist/index.umd.min.js +1 -1
- package/dist/progress.cjs +632 -172
- package/dist/progress.mjs +1827 -1379
- package/dist/vue2.cjs +1141 -266
- package/dist/vue2.mjs +2893 -2056
- package/dist/vue3.cjs +1141 -266
- package/dist/vue3.mjs +2893 -2056
- package/package.json +118 -118
- package/styles/base.css +32 -32
- package/styles/color.css +18 -18
- package/styles/progress.css +53 -50
- package/types/capsule.d.ts +15 -13
- package/types/color.d.ts +15 -13
- package/types/index.d.ts +204 -116
- package/types/progress.d.ts +16 -14
- package/types/vue3.d.ts +38 -22
package/dist/color.cjs
CHANGED
|
@@ -182,9 +182,9 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
/**
|
|
186
|
-
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
187
|
-
* future events (hover, click, custom) without breaking changes.
|
|
185
|
+
/**
|
|
186
|
+
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
187
|
+
* future events (hover, click, custom) without breaking changes.
|
|
188
188
|
*/
|
|
189
189
|
function createEmitter() {
|
|
190
190
|
// Plain object storage (no Map/Set) so the legacy build has no API
|
|
@@ -254,11 +254,17 @@ function dprCapFor(quality) {
|
|
|
254
254
|
var tier = QUALITY_TIERS[quality] || QUALITY_TIERS.medium;
|
|
255
255
|
return tier.dpr;
|
|
256
256
|
}
|
|
257
|
+
function effectiveDprCap(quality) {
|
|
258
|
+
var renderScale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
259
|
+
var scale = Number(renderScale);
|
|
260
|
+
var normalizedScale = Number.isFinite(scale) ? Math.min(1, Math.max(0.25, scale)) : 1;
|
|
261
|
+
return Math.max(0.5, dprCapFor(quality) * normalizedScale);
|
|
262
|
+
}
|
|
257
263
|
|
|
258
|
-
/**
|
|
259
|
-
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
260
|
-
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
261
|
-
* change.
|
|
264
|
+
/**
|
|
265
|
+
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
266
|
+
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
267
|
+
* change.
|
|
262
268
|
*/
|
|
263
269
|
function normalizeOptions(defaults, preset, user) {
|
|
264
270
|
// undefined means "not provided" (e.g. Vue $props with unset props):
|
|
@@ -276,9 +282,9 @@ function normalizeOptions(defaults, preset, user) {
|
|
|
276
282
|
return _objectSpread2(_objectSpread2(_objectSpread2({}, defaults), presetOptions), userOptions);
|
|
277
283
|
}
|
|
278
284
|
|
|
279
|
-
/**
|
|
280
|
-
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
281
|
-
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
285
|
+
/**
|
|
286
|
+
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
287
|
+
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
282
288
|
*/
|
|
283
289
|
var PALETTES = {
|
|
284
290
|
original: ['#FFF3EA', '#F5B27A', '#F67BC6', '#A978E8'],
|
|
@@ -289,9 +295,9 @@ var PALETTES = {
|
|
|
289
295
|
plus: ['#FFF0E6', '#F6C26B', '#F98A64', '#E86D74']
|
|
290
296
|
};
|
|
291
297
|
|
|
292
|
-
/**
|
|
293
|
-
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
294
|
-
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
298
|
+
/**
|
|
299
|
+
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
300
|
+
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
295
301
|
*/
|
|
296
302
|
var CAPSULE_PRESETS = [{
|
|
297
303
|
id: 'original',
|
|
@@ -379,6 +385,15 @@ var PROGRESS_PRESETS = [{
|
|
|
379
385
|
initialProgress: 30,
|
|
380
386
|
edgeStyle: 'tide',
|
|
381
387
|
colors: ['#0A2239', '#2E9BFF', '#7FE3FF', '#EAF9FF']
|
|
388
|
+
}, {
|
|
389
|
+
id: 'botanic-lab',
|
|
390
|
+
code: 'NC-14',
|
|
391
|
+
name: '森息',
|
|
392
|
+
subtitle: 'MOSS CULTURE / ROOTING',
|
|
393
|
+
group: 'progress',
|
|
394
|
+
initialProgress: 46,
|
|
395
|
+
edgeStyle: 'flow',
|
|
396
|
+
colors: ['#102A23', '#287A58', '#9BD65B', '#F2FFC4']
|
|
382
397
|
}];
|
|
383
398
|
|
|
384
399
|
[].concat(_toConsumableArray(CAPSULE_PRESETS), _toConsumableArray(PROGRESS_PRESETS));
|
|
@@ -407,6 +422,7 @@ var DEFAULTS = {
|
|
|
407
422
|
capsule: {
|
|
408
423
|
quality: 'auto',
|
|
409
424
|
renderer: 'auto',
|
|
425
|
+
fps: 60,
|
|
410
426
|
respectReducedMotion: true}};
|
|
411
427
|
|
|
412
428
|
/**
|
|
@@ -665,7 +681,7 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
665
681
|
alpha: false,
|
|
666
682
|
antialias: false,
|
|
667
683
|
depth: false,
|
|
668
|
-
powerPreference: 'high-performance',
|
|
684
|
+
powerPreference: this.options.powerPreference || 'high-performance',
|
|
669
685
|
preserveDrawingBuffer: false
|
|
670
686
|
});
|
|
671
687
|
if (!this.gl) throw new Error('WebGL2 is not available');
|
|
@@ -676,16 +692,19 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
676
692
|
this.motion = 0;
|
|
677
693
|
this.motionTarget = 0;
|
|
678
694
|
this.timeOffset = preset.seed * 0.73;
|
|
695
|
+
this.colors = preset.colors.map(hexToRgb01);
|
|
679
696
|
this.visible = true;
|
|
680
697
|
this.disposed = false;
|
|
681
698
|
_assertClassBrand(_CosmicRenderer_brand, this, _setupGeometry).call(this);
|
|
682
699
|
_assertClassBrand(_CosmicRenderer_brand, this, _bindEvents).call(this);
|
|
700
|
+
_assertClassBrand(_CosmicRenderer_brand, this, _bindContextEvents).call(this);
|
|
683
701
|
this.resize();
|
|
684
702
|
}
|
|
685
703
|
return _createClass(CosmicRenderer, [{
|
|
686
704
|
key: "setPreset",
|
|
687
705
|
value: function setPreset(preset) {
|
|
688
706
|
this.preset = _objectSpread2({}, preset);
|
|
707
|
+
this.colors = preset.colors.map(hexToRgb01);
|
|
689
708
|
this.timeOffset = preset.seed * 0.73;
|
|
690
709
|
}
|
|
691
710
|
}, {
|
|
@@ -730,15 +749,14 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
730
749
|
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
731
750
|
this.canvas.width = width;
|
|
732
751
|
this.canvas.height = height;
|
|
733
|
-
this.gl.viewport(0, 0, width, height);
|
|
734
752
|
}
|
|
753
|
+
this.gl.viewport(0, 0, width, height);
|
|
735
754
|
}
|
|
736
755
|
}, {
|
|
737
756
|
key: "draw",
|
|
738
757
|
value: function draw(elapsedSeconds) {
|
|
739
758
|
var paused = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
740
759
|
if (this.disposed || !this.visible) return;
|
|
741
|
-
this.resize();
|
|
742
760
|
var gl = this.gl;
|
|
743
761
|
this.pointer[0] += (this.pointerTarget[0] - this.pointer[0]) * 0.08;
|
|
744
762
|
this.pointer[1] += (this.pointerTarget[1] - this.pointer[1]) * 0.08;
|
|
@@ -747,16 +765,15 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
747
765
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
748
766
|
gl.enableVertexAttribArray(this.locations.position);
|
|
749
767
|
gl.vertexAttribPointer(this.locations.position, 2, gl.FLOAT, false, 0, 0);
|
|
750
|
-
var colors = this.preset.colors.map(hexToRgb01);
|
|
751
768
|
gl.uniform2f(this.locations.resolution, this.canvas.width, this.canvas.height);
|
|
752
769
|
gl.uniform1f(this.locations.time, this.timeOffset + (paused ? 0 : elapsedSeconds * this.preset.speed));
|
|
753
770
|
gl.uniform1f(this.locations.seed, this.preset.seed);
|
|
754
771
|
gl.uniform1f(this.locations.motion, this.motion);
|
|
755
772
|
gl.uniform2f(this.locations.pointer, this.pointer[0], this.pointer[1]);
|
|
756
|
-
gl.uniform3fv(this.locations.colorA, colors[0]);
|
|
757
|
-
gl.uniform3fv(this.locations.colorB, colors[1]);
|
|
758
|
-
gl.uniform3fv(this.locations.colorC, colors[2]);
|
|
759
|
-
gl.uniform3fv(this.locations.colorD, colors[3]);
|
|
773
|
+
gl.uniform3fv(this.locations.colorA, this.colors[0]);
|
|
774
|
+
gl.uniform3fv(this.locations.colorB, this.colors[1]);
|
|
775
|
+
gl.uniform3fv(this.locations.colorC, this.colors[2]);
|
|
776
|
+
gl.uniform3fv(this.locations.colorD, this.colors[3]);
|
|
760
777
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
761
778
|
}
|
|
762
779
|
}, {
|
|
@@ -767,6 +784,8 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
767
784
|
target.removeEventListener('pointermove', this.onPointerMove);
|
|
768
785
|
target.removeEventListener('pointerdown', this.onPointerMove);
|
|
769
786
|
target.removeEventListener('pointerleave', this.onPointerLeave);
|
|
787
|
+
this.canvas.removeEventListener('webglcontextlost', this.onContextLost, false);
|
|
788
|
+
this.canvas.removeEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
770
789
|
this.gl.deleteBuffer(this.buffer);
|
|
771
790
|
this.gl.deleteProgram(this.program);
|
|
772
791
|
var lose = this.gl.getExtension('WEBGL_lose_context');
|
|
@@ -823,6 +842,26 @@ function _bindEvents() {
|
|
|
823
842
|
passive: true
|
|
824
843
|
});
|
|
825
844
|
}
|
|
845
|
+
function _bindContextEvents() {
|
|
846
|
+
var _this3 = this;
|
|
847
|
+
this.onContextLost = function (event) {
|
|
848
|
+
event.preventDefault();
|
|
849
|
+
if (_this3.disposed) return;
|
|
850
|
+
_this3.visible = false;
|
|
851
|
+
if (typeof _this3.options.onContextLost === 'function') _this3.options.onContextLost(event);
|
|
852
|
+
};
|
|
853
|
+
this.onContextRestored = function () {
|
|
854
|
+
if (_this3.disposed) return;
|
|
855
|
+
_this3.program = createProgram(_this3.gl);
|
|
856
|
+
_this3.locations = _assertClassBrand(_CosmicRenderer_brand, _this3, _getLocations).call(_this3);
|
|
857
|
+
_assertClassBrand(_CosmicRenderer_brand, _this3, _setupGeometry).call(_this3);
|
|
858
|
+
_this3.visible = true;
|
|
859
|
+
_this3.resize();
|
|
860
|
+
if (typeof _this3.options.onContextRestored === 'function') _this3.options.onContextRestored();
|
|
861
|
+
};
|
|
862
|
+
this.canvas.addEventListener('webglcontextlost', this.onContextLost, false);
|
|
863
|
+
this.canvas.addEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
864
|
+
}
|
|
826
865
|
|
|
827
866
|
function rgb(color) {
|
|
828
867
|
var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
@@ -837,18 +876,20 @@ function rgb(color) {
|
|
|
837
876
|
}
|
|
838
877
|
var FallbackRenderer = /*#__PURE__*/function () {
|
|
839
878
|
function FallbackRenderer(canvas, preset) {
|
|
879
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
840
880
|
_classCallCheck(this, FallbackRenderer);
|
|
841
881
|
this.canvas = canvas;
|
|
842
882
|
this.preset = preset;
|
|
843
883
|
this.context = canvas.getContext('2d');
|
|
844
884
|
this.visible = true;
|
|
845
885
|
this.timePhase = 0;
|
|
886
|
+
this.dprCap = options.dprCap || 1.5;
|
|
846
887
|
}
|
|
847
888
|
return _createClass(FallbackRenderer, [{
|
|
848
889
|
key: "resize",
|
|
849
890
|
value: function resize() {
|
|
850
891
|
var rect = this.canvas.getBoundingClientRect();
|
|
851
|
-
var dpr = Math.min(window.devicePixelRatio || 1,
|
|
892
|
+
var dpr = Math.min(window.devicePixelRatio || 1, this.dprCap);
|
|
852
893
|
var width = Math.max(2, Math.round(rect.width * dpr));
|
|
853
894
|
var height = Math.max(2, Math.round(rect.height * dpr));
|
|
854
895
|
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
@@ -889,7 +930,6 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
889
930
|
key: "draw",
|
|
890
931
|
value: function draw(time) {
|
|
891
932
|
if (!this.visible) return;
|
|
892
|
-
this.resize();
|
|
893
933
|
this.drawNebula(time);
|
|
894
934
|
}
|
|
895
935
|
}, {
|
|
@@ -897,6 +937,12 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
897
937
|
value: function setPreset(preset) {
|
|
898
938
|
this.preset = preset;
|
|
899
939
|
}
|
|
940
|
+
}, {
|
|
941
|
+
key: "setDprCap",
|
|
942
|
+
value: function setDprCap(cap) {
|
|
943
|
+
this.dprCap = cap;
|
|
944
|
+
this.resize();
|
|
945
|
+
}
|
|
900
946
|
}, {
|
|
901
947
|
key: "randomize",
|
|
902
948
|
value: function randomize() {
|
|
@@ -914,10 +960,10 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
914
960
|
}]);
|
|
915
961
|
}();
|
|
916
962
|
|
|
917
|
-
/**
|
|
918
|
-
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
919
|
-
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
920
|
-
* original demo), which avoids jank from many competing rAF loops.
|
|
963
|
+
/**
|
|
964
|
+
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
965
|
+
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
966
|
+
* original demo), which avoids jank from many competing rAF loops.
|
|
921
967
|
*/
|
|
922
968
|
var subscribers = [];
|
|
923
969
|
var running = false;
|
|
@@ -925,11 +971,7 @@ var rafId = 0;
|
|
|
925
971
|
var last = 0;
|
|
926
972
|
function tick(now) {
|
|
927
973
|
if (!running) return;
|
|
928
|
-
var
|
|
929
|
-
last = now;
|
|
930
|
-
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
931
|
-
// subscriber can never kill the whole animation loop.
|
|
932
|
-
rafId = requestAnimationFrame(tick);
|
|
974
|
+
var activeItems = [];
|
|
933
975
|
{
|
|
934
976
|
var _iterator = _createForOfIteratorHelper(subscribers.slice()),
|
|
935
977
|
_step;
|
|
@@ -937,10 +979,8 @@ function tick(now) {
|
|
|
937
979
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
938
980
|
var item = _step.value;
|
|
939
981
|
try {
|
|
940
|
-
if (!item.isPaused())
|
|
941
|
-
} catch (
|
|
942
|
-
console.warn('[dlc-ui] frame error:', error);
|
|
943
|
-
}
|
|
982
|
+
if (!item.isPaused()) activeItems.push(item);
|
|
983
|
+
} catch (_unused) {}
|
|
944
984
|
}
|
|
945
985
|
} catch (err) {
|
|
946
986
|
_iterator.e(err);
|
|
@@ -948,6 +988,25 @@ function tick(now) {
|
|
|
948
988
|
_iterator.f();
|
|
949
989
|
}
|
|
950
990
|
}
|
|
991
|
+
if (activeItems.length === 0) {
|
|
992
|
+
running = false;
|
|
993
|
+
rafId = 0;
|
|
994
|
+
last = 0;
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
var delta = last ? Math.min((now - last) / 1000, 0.05) : 0;
|
|
998
|
+
last = now;
|
|
999
|
+
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
1000
|
+
// subscriber can never kill the whole animation loop.
|
|
1001
|
+
rafId = requestAnimationFrame(tick);
|
|
1002
|
+
for (var _i = 0, _activeItems = activeItems; _i < _activeItems.length; _i++) {
|
|
1003
|
+
var _item = _activeItems[_i];
|
|
1004
|
+
try {
|
|
1005
|
+
_item.onFrame(delta, now);
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
console.warn('[dlc-ui] frame error:', error);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
951
1010
|
if (subscribers.length === 0) {
|
|
952
1011
|
cancelAnimationFrame(rafId);
|
|
953
1012
|
running = false;
|
|
@@ -960,6 +1019,9 @@ function start() {
|
|
|
960
1019
|
last = 0;
|
|
961
1020
|
rafId = requestAnimationFrame(tick);
|
|
962
1021
|
}
|
|
1022
|
+
function wakeScheduler() {
|
|
1023
|
+
start();
|
|
1024
|
+
}
|
|
963
1025
|
function subscribeScheduler(onFrame, isPaused) {
|
|
964
1026
|
var item = {
|
|
965
1027
|
onFrame: onFrame,
|
|
@@ -978,11 +1040,12 @@ function subscribeScheduler(onFrame, isPaused) {
|
|
|
978
1040
|
};
|
|
979
1041
|
}
|
|
980
1042
|
|
|
981
|
-
/**
|
|
982
|
-
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
983
|
-
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
1043
|
+
/**
|
|
1044
|
+
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
1045
|
+
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
984
1046
|
*/
|
|
985
1047
|
function createVisibilityGuard(element) {
|
|
1048
|
+
var onChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
986
1049
|
var intersecting = true;
|
|
987
1050
|
var pageVisible = typeof document === 'undefined' || !document.hidden;
|
|
988
1051
|
var disposed = false;
|
|
@@ -992,6 +1055,7 @@ function createVisibilityGuard(element) {
|
|
|
992
1055
|
intersecting = entries.some(function (entry) {
|
|
993
1056
|
return entry.isIntersecting;
|
|
994
1057
|
});
|
|
1058
|
+
if (typeof onChange === 'function') onChange();
|
|
995
1059
|
}, {
|
|
996
1060
|
rootMargin: '180px'
|
|
997
1061
|
});
|
|
@@ -999,6 +1063,7 @@ function createVisibilityGuard(element) {
|
|
|
999
1063
|
}
|
|
1000
1064
|
var onVisibilityChange = function onVisibilityChange() {
|
|
1001
1065
|
pageVisible = typeof document !== 'undefined' && !document.hidden;
|
|
1066
|
+
if (typeof onChange === 'function') onChange();
|
|
1002
1067
|
};
|
|
1003
1068
|
if (typeof document !== 'undefined') {
|
|
1004
1069
|
document.addEventListener('visibilitychange', onVisibilityChange);
|
|
@@ -1034,22 +1099,100 @@ function nextTick(fn) {
|
|
|
1034
1099
|
}
|
|
1035
1100
|
}
|
|
1036
1101
|
|
|
1037
|
-
function
|
|
1038
|
-
|
|
1102
|
+
function normalizeFps(value) {
|
|
1103
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 60;
|
|
1104
|
+
var fps = Number(value);
|
|
1105
|
+
if (!Number.isFinite(fps)) return fallback;
|
|
1106
|
+
return Math.min(60, Math.max(1, fps));
|
|
1107
|
+
}
|
|
1108
|
+
function createFrameGate() {
|
|
1109
|
+
var initialFps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 60;
|
|
1110
|
+
var fps = normalizeFps(initialFps);
|
|
1111
|
+
var elapsed = 0;
|
|
1112
|
+
return {
|
|
1113
|
+
shouldDraw: function shouldDraw(delta) {
|
|
1114
|
+
elapsed += delta;
|
|
1115
|
+
var interval = 1 / fps;
|
|
1116
|
+
if (elapsed + 0.0001 < interval) return false;
|
|
1117
|
+
elapsed %= interval;
|
|
1118
|
+
return true;
|
|
1119
|
+
},
|
|
1120
|
+
setFps: function setFps(value) {
|
|
1121
|
+
fps = normalizeFps(value, fps);
|
|
1122
|
+
elapsed = 0;
|
|
1123
|
+
return fps;
|
|
1124
|
+
},
|
|
1125
|
+
getFps: function getFps() {
|
|
1126
|
+
return fps;
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
function createReducedMotionPreference(enabled, onChange) {
|
|
1131
|
+
var query = enabled && typeof matchMedia !== 'undefined' ? matchMedia('(prefers-reduced-motion: reduce)') : null;
|
|
1132
|
+
var notify = function notify() {
|
|
1133
|
+
if (typeof onChange === 'function') onChange(Boolean(query && query.matches));
|
|
1134
|
+
};
|
|
1135
|
+
if (query) {
|
|
1136
|
+
if (typeof query.addEventListener === 'function') query.addEventListener('change', notify);else if (typeof query.addListener === 'function') query.addListener(notify);
|
|
1137
|
+
}
|
|
1138
|
+
return {
|
|
1139
|
+
matches: function matches() {
|
|
1140
|
+
return Boolean(query && query.matches);
|
|
1141
|
+
},
|
|
1142
|
+
dispose: function dispose() {
|
|
1143
|
+
if (!query) return;
|
|
1144
|
+
if (typeof query.removeEventListener === 'function') query.removeEventListener('change', notify);else if (typeof query.removeListener === 'function') query.removeListener(notify);
|
|
1145
|
+
}
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
function toFiniteNumber(value) {
|
|
1150
|
+
if (value == null || typeof value === 'boolean') return null;
|
|
1151
|
+
if (typeof value === 'string' && value.trim() === '') return null;
|
|
1152
|
+
var number = Number(value);
|
|
1153
|
+
return Number.isFinite(number) ? number : null;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
var HOST_STYLES = new WeakMap();
|
|
1157
|
+
function acquireHostStyles(host) {
|
|
1158
|
+
var active = HOST_STYLES.get(host);
|
|
1159
|
+
if (active) {
|
|
1160
|
+
active.count += 1;
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
var state = {
|
|
1164
|
+
count: 1,
|
|
1165
|
+
position: host.style.position,
|
|
1166
|
+
isolation: host.style.isolation
|
|
1167
|
+
};
|
|
1168
|
+
var computed = getComputedStyle(host);
|
|
1169
|
+
if (computed.position === 'static' || computed.position === '') host.style.position = 'relative';
|
|
1170
|
+
host.style.isolation = 'isolate';
|
|
1171
|
+
HOST_STYLES.set(host, state);
|
|
1172
|
+
}
|
|
1173
|
+
function releaseHostStyles(host) {
|
|
1174
|
+
var state = HOST_STYLES.get(host);
|
|
1175
|
+
if (!state) return;
|
|
1176
|
+
state.count -= 1;
|
|
1177
|
+
if (state.count > 0) return;
|
|
1178
|
+
host.style.position = state.position;
|
|
1179
|
+
host.style.isolation = state.isolation;
|
|
1180
|
+
HOST_STYLES.delete(host);
|
|
1039
1181
|
}
|
|
1040
1182
|
|
|
1041
|
-
/**
|
|
1042
|
-
* Mount the cosmic (nebula) material as a background layer inside `host`.
|
|
1043
|
-
*
|
|
1044
|
-
* The layer is absolutely positioned and defaults to `z-index: -1`, so it
|
|
1045
|
-
* paints behind the host's in-flow content: text/buttons/images inside the
|
|
1046
|
-
* host sit on top with zero extra CSS. Host gets `position: relative;
|
|
1047
|
-
* isolation: isolate` automatically so the layer can never escape its box
|
|
1048
|
-
* (or break stacking outside it).
|
|
1049
|
-
*
|
|
1183
|
+
/**
|
|
1184
|
+
* Mount the cosmic (nebula) material as a background layer inside `host`.
|
|
1185
|
+
*
|
|
1186
|
+
* The layer is absolutely positioned and defaults to `z-index: -1`, so it
|
|
1187
|
+
* paints behind the host's in-flow content: text/buttons/images inside the
|
|
1188
|
+
* host sit on top with zero extra CSS. Host gets `position: relative;
|
|
1189
|
+
* isolation: isolate` automatically so the layer can never escape its box
|
|
1190
|
+
* (or break stacking outside it).
|
|
1191
|
+
*
|
|
1050
1192
|
* Options: preset (literary name), colors, seed, speed, quality,
|
|
1051
|
-
* renderer,
|
|
1052
|
-
*
|
|
1193
|
+
* renderer, renderScale, powerPreference, fps, paused/static, mouseColor,
|
|
1194
|
+
* respectReducedMotion, opacity (0-1), fallbackColor (true=preset base
|
|
1195
|
+
* color, a hex string, or false to disable).
|
|
1053
1196
|
*/
|
|
1054
1197
|
function createColorBackground(host) {
|
|
1055
1198
|
var _options$preset;
|
|
@@ -1063,18 +1206,29 @@ function createColorBackground(host) {
|
|
|
1063
1206
|
renderer: DEFAULTS.capsule.renderer,
|
|
1064
1207
|
respectReducedMotion: DEFAULTS.capsule.respectReducedMotion,
|
|
1065
1208
|
mouseColor: true,
|
|
1209
|
+
renderScale: 1,
|
|
1210
|
+
powerPreference: 'high-performance',
|
|
1211
|
+
fps: DEFAULTS.capsule.fps,
|
|
1212
|
+
paused: false,
|
|
1213
|
+
static: false,
|
|
1066
1214
|
opacity: 1,
|
|
1067
1215
|
fallbackColor: true
|
|
1068
1216
|
}, preset, options);
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
preset.
|
|
1072
|
-
|
|
1073
|
-
var
|
|
1074
|
-
if (
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1217
|
+
merged.opacity = Number.isFinite(Number(merged.opacity)) ? Math.min(1, Math.max(0, Number(merged.opacity))) : 1;
|
|
1218
|
+
var normalizedColors = Array.isArray(merged.colors) ? merged.colors.map(normalizeColor) : [];
|
|
1219
|
+
if (normalizedColors.length === 4 && normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
1220
|
+
var initialSeed = toFiniteNumber(merged.seed);
|
|
1221
|
+
var initialSpeed = toFiniteNumber(merged.speed);
|
|
1222
|
+
if (initialSeed !== null) preset.seed = initialSeed;
|
|
1223
|
+
if (initialSpeed !== null) preset.speed = initialSpeed;
|
|
1224
|
+
merged.colors = _toConsumableArray(preset.colors);
|
|
1225
|
+
merged.seed = preset.seed;
|
|
1226
|
+
merged.speed = preset.speed;
|
|
1227
|
+
var optionColors = Array.isArray(options.colors) ? options.colors.map(normalizeColor) : [];
|
|
1228
|
+
var colorOverride = optionColors.length === 4 && optionColors.every(Boolean) ? _toConsumableArray(optionColors) : null;
|
|
1229
|
+
var seedOverride = options.seed !== undefined ? toFiniteNumber(options.seed) : null;
|
|
1230
|
+
var speedOverride = options.speed !== undefined ? toFiniteNumber(options.speed) : null;
|
|
1231
|
+
acquireHostStyles(host);
|
|
1078
1232
|
var layer = document.createElement('div');
|
|
1079
1233
|
layer.className = 'dlc-color-layer';
|
|
1080
1234
|
var syncLayerVars = function syncLayerVars() {
|
|
@@ -1089,8 +1243,12 @@ function createColorBackground(host) {
|
|
|
1089
1243
|
layer.appendChild(canvas);
|
|
1090
1244
|
host.appendChild(layer);
|
|
1091
1245
|
var emitter = createEmitter();
|
|
1092
|
-
var
|
|
1246
|
+
var manuallyPaused = merged.paused === true;
|
|
1247
|
+
var reducedPaused = false;
|
|
1248
|
+
var staticMode = merged.static === true;
|
|
1249
|
+
var contextLost = false;
|
|
1093
1250
|
var disposed = false;
|
|
1251
|
+
var renderOnce = function renderOnce() {};
|
|
1094
1252
|
var dirty = {
|
|
1095
1253
|
preset: false,
|
|
1096
1254
|
seed: false,
|
|
@@ -1098,19 +1256,37 @@ function createColorBackground(host) {
|
|
|
1098
1256
|
colors: false,
|
|
1099
1257
|
opacity: false,
|
|
1100
1258
|
fallbackColor: false,
|
|
1101
|
-
mouseColor: false
|
|
1259
|
+
mouseColor: false,
|
|
1260
|
+
quality: false,
|
|
1261
|
+
renderScale: false,
|
|
1262
|
+
paused: false,
|
|
1263
|
+
static: false,
|
|
1264
|
+
fps: false
|
|
1102
1265
|
};
|
|
1103
1266
|
var renderer;
|
|
1104
1267
|
var useWebgl = merged.renderer !== 'canvas2d';
|
|
1105
1268
|
if (useWebgl) {
|
|
1106
1269
|
try {
|
|
1107
1270
|
renderer = new CosmicRenderer(canvas, merged, {
|
|
1108
|
-
dprCap:
|
|
1271
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
1109
1272
|
mouseColor: merged.mouseColor !== false,
|
|
1110
|
-
eventTarget: host
|
|
1273
|
+
eventTarget: host,
|
|
1274
|
+
powerPreference: merged.powerPreference,
|
|
1275
|
+
onContextLost: function onContextLost() {
|
|
1276
|
+
contextLost = true;
|
|
1277
|
+
emitter.emit('contextlost', {});
|
|
1278
|
+
},
|
|
1279
|
+
onContextRestored: function onContextRestored() {
|
|
1280
|
+
contextLost = false;
|
|
1281
|
+
emitter.emit('contextrestored', {});
|
|
1282
|
+
renderOnce();
|
|
1283
|
+
wakeScheduler();
|
|
1284
|
+
}
|
|
1111
1285
|
});
|
|
1112
1286
|
} catch (error) {
|
|
1113
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
1287
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
1288
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
1289
|
+
});
|
|
1114
1290
|
nextTick(function () {
|
|
1115
1291
|
if (disposed) return;
|
|
1116
1292
|
emitter.emit('error', {
|
|
@@ -1119,19 +1295,37 @@ function createColorBackground(host) {
|
|
|
1119
1295
|
});
|
|
1120
1296
|
}
|
|
1121
1297
|
} else {
|
|
1122
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
1298
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
1299
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
1300
|
+
});
|
|
1123
1301
|
}
|
|
1124
|
-
|
|
1125
|
-
return renderer.resize();
|
|
1126
|
-
}) : null;
|
|
1127
|
-
if (resizeObserver) resizeObserver.observe(host);else window.addEventListener('resize', renderer.resize);
|
|
1128
|
-
var visibility = createVisibilityGuard(layer);
|
|
1302
|
+
renderer.resize();
|
|
1129
1303
|
var animationTime = 0;
|
|
1304
|
+
var frameGate = createFrameGate(merged.fps);
|
|
1305
|
+
renderOnce = function renderOnce() {
|
|
1306
|
+
return renderer.draw(animationTime);
|
|
1307
|
+
};
|
|
1308
|
+
var resize = function resize() {
|
|
1309
|
+
renderer.resize();
|
|
1310
|
+
if (manuallyPaused || reducedPaused || staticMode) renderOnce();
|
|
1311
|
+
};
|
|
1312
|
+
var resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(resize) : null;
|
|
1313
|
+
if (resizeObserver) resizeObserver.observe(host);else window.addEventListener('resize', resize);
|
|
1314
|
+
var visibility = createVisibilityGuard(layer, wakeScheduler);
|
|
1315
|
+
var motionPreference = createReducedMotionPreference(merged.respectReducedMotion, function (matches) {
|
|
1316
|
+
reducedPaused = matches;
|
|
1317
|
+
if (matches) renderOnce();else wakeScheduler();
|
|
1318
|
+
});
|
|
1319
|
+
reducedPaused = motionPreference.matches();
|
|
1320
|
+
var isMotionPaused = function isMotionPaused() {
|
|
1321
|
+
return manuallyPaused || reducedPaused || staticMode || contextLost;
|
|
1322
|
+
};
|
|
1323
|
+
renderOnce();
|
|
1130
1324
|
var unsubscribe = subscribeScheduler(function (delta) {
|
|
1131
1325
|
animationTime += delta;
|
|
1132
|
-
if (
|
|
1326
|
+
if (frameGate.shouldDraw(delta)) renderer.draw(animationTime);
|
|
1133
1327
|
}, function () {
|
|
1134
|
-
return
|
|
1328
|
+
return isMotionPaused() || !visibility.isVisible();
|
|
1135
1329
|
});
|
|
1136
1330
|
nextTick(function () {
|
|
1137
1331
|
if (disposed) return;
|
|
@@ -1150,11 +1344,15 @@ function createColorBackground(host) {
|
|
|
1150
1344
|
var next = getPreset('capsule', ref);
|
|
1151
1345
|
dirty.preset = true;
|
|
1152
1346
|
Object.assign(preset, next);
|
|
1347
|
+
if (colorOverride) preset.colors = _toConsumableArray(colorOverride);
|
|
1348
|
+
if (seedOverride !== null) preset.seed = seedOverride;
|
|
1349
|
+
if (speedOverride !== null) preset.speed = speedOverride;
|
|
1153
1350
|
var nextColors = preset.colors.map(normalizeColor);
|
|
1154
1351
|
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
1155
1352
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1156
1353
|
renderer.resize();
|
|
1157
1354
|
syncLayerVars();
|
|
1355
|
+
if (isMotionPaused()) renderOnce();
|
|
1158
1356
|
emitter.emit('presetchange', {
|
|
1159
1357
|
preset: _objectSpread2({}, preset)
|
|
1160
1358
|
});
|
|
@@ -1166,27 +1364,33 @@ function createColorBackground(host) {
|
|
|
1166
1364
|
return !color;
|
|
1167
1365
|
})) return this;
|
|
1168
1366
|
dirty.colors = true;
|
|
1367
|
+
colorOverride = _toConsumableArray(next);
|
|
1169
1368
|
preset.colors = next;
|
|
1170
1369
|
renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
|
|
1171
1370
|
colors: next
|
|
1172
1371
|
}));
|
|
1173
1372
|
syncLayerVars();
|
|
1373
|
+
if (isMotionPaused()) renderOnce();
|
|
1174
1374
|
return this;
|
|
1175
1375
|
},
|
|
1176
1376
|
setSeed: function setSeed(seed) {
|
|
1177
|
-
var value =
|
|
1178
|
-
if (
|
|
1377
|
+
var value = toFiniteNumber(seed);
|
|
1378
|
+
if (value === null) return this;
|
|
1179
1379
|
dirty.seed = true;
|
|
1380
|
+
seedOverride = value;
|
|
1180
1381
|
preset.seed = value;
|
|
1181
1382
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1383
|
+
if (isMotionPaused()) renderOnce();
|
|
1182
1384
|
return this;
|
|
1183
1385
|
},
|
|
1184
1386
|
setSpeed: function setSpeed(speed) {
|
|
1185
|
-
var value =
|
|
1186
|
-
if (
|
|
1387
|
+
var value = toFiniteNumber(speed);
|
|
1388
|
+
if (value === null) return this;
|
|
1187
1389
|
dirty.speed = true;
|
|
1390
|
+
speedOverride = value;
|
|
1188
1391
|
preset.speed = value;
|
|
1189
1392
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1393
|
+
if (isMotionPaused()) renderOnce();
|
|
1190
1394
|
return this;
|
|
1191
1395
|
},
|
|
1192
1396
|
setFallbackColor: function setFallbackColor(value) {
|
|
@@ -1202,8 +1406,23 @@ function createColorBackground(host) {
|
|
|
1202
1406
|
return this;
|
|
1203
1407
|
},
|
|
1204
1408
|
setQuality: function setQuality(quality) {
|
|
1409
|
+
dirty.quality = true;
|
|
1205
1410
|
merged.quality = quality;
|
|
1206
|
-
if (typeof renderer.setDprCap === 'function')
|
|
1411
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
1412
|
+
renderer.setDprCap(effectiveDprCap(quality, merged.renderScale));
|
|
1413
|
+
}
|
|
1414
|
+
if (isMotionPaused()) renderOnce();
|
|
1415
|
+
return this;
|
|
1416
|
+
},
|
|
1417
|
+
setRenderScale: function setRenderScale(renderScale) {
|
|
1418
|
+
var value = Number(renderScale);
|
|
1419
|
+
if (!Number.isFinite(value)) return this;
|
|
1420
|
+
dirty.renderScale = true;
|
|
1421
|
+
merged.renderScale = Math.min(1, Math.max(0.25, value));
|
|
1422
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
1423
|
+
renderer.setDprCap(effectiveDprCap(merged.quality, merged.renderScale));
|
|
1424
|
+
}
|
|
1425
|
+
if (isMotionPaused()) renderOnce();
|
|
1207
1426
|
return this;
|
|
1208
1427
|
},
|
|
1209
1428
|
setOpacity: function setOpacity(value) {
|
|
@@ -1219,20 +1438,42 @@ function createColorBackground(host) {
|
|
|
1219
1438
|
return this;
|
|
1220
1439
|
},
|
|
1221
1440
|
pause: function pause() {
|
|
1222
|
-
paused = true;
|
|
1441
|
+
dirty.paused = true;
|
|
1442
|
+
manuallyPaused = true;
|
|
1443
|
+
renderOnce();
|
|
1223
1444
|
return this;
|
|
1224
1445
|
},
|
|
1225
1446
|
resume: function resume() {
|
|
1226
|
-
paused =
|
|
1447
|
+
dirty.paused = true;
|
|
1448
|
+
manuallyPaused = false;
|
|
1449
|
+
wakeScheduler();
|
|
1450
|
+
return this;
|
|
1451
|
+
},
|
|
1452
|
+
setPaused: function setPaused(value) {
|
|
1453
|
+
return value ? this.pause() : this.resume();
|
|
1454
|
+
},
|
|
1455
|
+
setStatic: function setStatic(value) {
|
|
1456
|
+
dirty.static = true;
|
|
1457
|
+
staticMode = value === true;
|
|
1458
|
+
merged.static = staticMode;
|
|
1459
|
+
if (staticMode) renderOnce();else wakeScheduler();
|
|
1460
|
+
return this;
|
|
1461
|
+
},
|
|
1462
|
+
setFps: function setFps(fps) {
|
|
1463
|
+
dirty.fps = true;
|
|
1464
|
+
merged.fps = frameGate.setFps(fps);
|
|
1465
|
+
wakeScheduler();
|
|
1227
1466
|
return this;
|
|
1228
1467
|
},
|
|
1229
1468
|
dispose: function dispose() {
|
|
1230
1469
|
disposed = true;
|
|
1231
1470
|
unsubscribe();
|
|
1232
1471
|
visibility.dispose();
|
|
1233
|
-
|
|
1472
|
+
motionPreference.dispose();
|
|
1473
|
+
if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', resize);
|
|
1234
1474
|
renderer.dispose();
|
|
1235
1475
|
layer.remove();
|
|
1476
|
+
releaseHostStyles(host);
|
|
1236
1477
|
},
|
|
1237
1478
|
get opacity() {
|
|
1238
1479
|
return merged.opacity;
|
|
@@ -1243,6 +1484,21 @@ function createColorBackground(host) {
|
|
|
1243
1484
|
get mouseColor() {
|
|
1244
1485
|
return merged.mouseColor;
|
|
1245
1486
|
},
|
|
1487
|
+
get quality() {
|
|
1488
|
+
return merged.quality;
|
|
1489
|
+
},
|
|
1490
|
+
get renderScale() {
|
|
1491
|
+
return merged.renderScale;
|
|
1492
|
+
},
|
|
1493
|
+
get paused() {
|
|
1494
|
+
return manuallyPaused;
|
|
1495
|
+
},
|
|
1496
|
+
get static() {
|
|
1497
|
+
return staticMode;
|
|
1498
|
+
},
|
|
1499
|
+
get fps() {
|
|
1500
|
+
return frameGate.getFps();
|
|
1501
|
+
},
|
|
1246
1502
|
dirty: dirty
|
|
1247
1503
|
};
|
|
1248
1504
|
}
|