@5even7/dlc-ui 0.2.10 → 0.2.12
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 +50 -42
- package/LICENSE +21 -21
- package/README.md +257 -257
- package/dist/capsule.cjs +298 -71
- package/dist/capsule.mjs +828 -604
- package/dist/color.cjs +330 -83
- package/dist/color.mjs +880 -632
- package/dist/index.cjs +982 -255
- package/dist/index.mjs +2708 -1987
- package/dist/index.umd.js +982 -255
- package/dist/index.umd.min.js +1 -1
- package/dist/progress.cjs +616 -173
- package/dist/progress.mjs +1827 -1386
- package/dist/vue2.cjs +1126 -268
- package/dist/vue2.mjs +2897 -2067
- package/dist/vue3.cjs +1126 -268
- package/dist/vue3.mjs +2897 -2067
- package/package.json +122 -121
- package/styles/base.css +32 -32
- package/styles/capsule.css +2 -0
- package/styles/color.css +18 -18
- package/styles/progress.css +55 -50
- package/types/capsule.d.ts +15 -13
- package/types/color.d.ts +15 -13
- package/types/index.d.ts +216 -127
- package/types/progress.d.ts +16 -14
- package/types/vue3.d.ts +38 -22
package/dist/vue2.cjs
CHANGED
|
@@ -187,9 +187,9 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
/**
|
|
191
|
-
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
192
|
-
* future events (hover, click, custom) without breaking changes.
|
|
190
|
+
/**
|
|
191
|
+
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
192
|
+
* future events (hover, click, custom) without breaking changes.
|
|
193
193
|
*/
|
|
194
194
|
function createEmitter() {
|
|
195
195
|
// Plain object storage (no Map/Set) so the legacy build has no API
|
|
@@ -239,9 +239,9 @@ function createEmitter() {
|
|
|
239
239
|
|
|
240
240
|
var UNIT_PATTERN = /^[\d.]+(?:px|%|vw|vh|vmin|vmax|em|rem)$/;
|
|
241
241
|
|
|
242
|
-
/**
|
|
243
|
-
* Normalize a size option to a CSS length string.
|
|
244
|
-
* Accepts numbers (treated as px) or strings with px/%, vw/vh/vmin/vmax, em/rem.
|
|
242
|
+
/**
|
|
243
|
+
* Normalize a size option to a CSS length string.
|
|
244
|
+
* Accepts numbers (treated as px) or strings with px/%, vw/vh/vmin/vmax, em/rem.
|
|
245
245
|
*/
|
|
246
246
|
function parseSize(value) {
|
|
247
247
|
if (typeof value === 'number') {
|
|
@@ -280,11 +280,17 @@ function dprCapFor(quality) {
|
|
|
280
280
|
var tier = QUALITY_TIERS[quality] || QUALITY_TIERS.medium;
|
|
281
281
|
return tier.dpr;
|
|
282
282
|
}
|
|
283
|
+
function effectiveDprCap(quality) {
|
|
284
|
+
var renderScale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
285
|
+
var scale = Number(renderScale);
|
|
286
|
+
var normalizedScale = Number.isFinite(scale) ? Math.min(1, Math.max(0.25, scale)) : 1;
|
|
287
|
+
return Math.max(0.5, dprCapFor(quality) * normalizedScale);
|
|
288
|
+
}
|
|
283
289
|
|
|
284
|
-
/**
|
|
285
|
-
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
286
|
-
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
287
|
-
* change.
|
|
290
|
+
/**
|
|
291
|
+
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
292
|
+
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
293
|
+
* change.
|
|
288
294
|
*/
|
|
289
295
|
function normalizeOptions(defaults, preset, user) {
|
|
290
296
|
// undefined means "not provided" (e.g. Vue $props with unset props):
|
|
@@ -302,9 +308,9 @@ function normalizeOptions(defaults, preset, user) {
|
|
|
302
308
|
return _objectSpread2(_objectSpread2(_objectSpread2({}, defaults), presetOptions), userOptions);
|
|
303
309
|
}
|
|
304
310
|
|
|
305
|
-
/**
|
|
306
|
-
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
307
|
-
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
311
|
+
/**
|
|
312
|
+
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
313
|
+
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
308
314
|
*/
|
|
309
315
|
var PALETTES$1 = {
|
|
310
316
|
original: ['#FFF3EA', '#F5B27A', '#F67BC6', '#A978E8'],
|
|
@@ -315,9 +321,9 @@ var PALETTES$1 = {
|
|
|
315
321
|
plus: ['#FFF0E6', '#F6C26B', '#F98A64', '#E86D74']
|
|
316
322
|
};
|
|
317
323
|
|
|
318
|
-
/**
|
|
319
|
-
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
320
|
-
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
324
|
+
/**
|
|
325
|
+
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
326
|
+
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
321
327
|
*/
|
|
322
328
|
var CAPSULE_PRESETS = [{
|
|
323
329
|
id: 'original',
|
|
@@ -435,6 +441,11 @@ var DEFAULTS = {
|
|
|
435
441
|
height: 160,
|
|
436
442
|
quality: 'auto',
|
|
437
443
|
renderer: 'auto',
|
|
444
|
+
renderScale: 1,
|
|
445
|
+
powerPreference: 'high-performance',
|
|
446
|
+
fps: 60,
|
|
447
|
+
paused: false,
|
|
448
|
+
static: false,
|
|
438
449
|
respectReducedMotion: true,
|
|
439
450
|
mouseColor: true,
|
|
440
451
|
textRatio: 39
|
|
@@ -444,13 +455,22 @@ var DEFAULTS = {
|
|
|
444
455
|
height: 104,
|
|
445
456
|
min: 0,
|
|
446
457
|
max: 100,
|
|
458
|
+
step: 'any',
|
|
447
459
|
draggable: true,
|
|
460
|
+
keyboard: true,
|
|
448
461
|
disabled: false,
|
|
449
462
|
readonly: false,
|
|
463
|
+
direction: 'ltr',
|
|
464
|
+
precision: 0,
|
|
450
465
|
valueSuffix: '%',
|
|
451
466
|
edgeStyle: 'flow',
|
|
452
467
|
quality: 'auto',
|
|
453
468
|
renderer: 'auto',
|
|
469
|
+
renderScale: 1,
|
|
470
|
+
powerPreference: 'high-performance',
|
|
471
|
+
fps: 60,
|
|
472
|
+
paused: false,
|
|
473
|
+
static: false,
|
|
454
474
|
textRatio: 54,
|
|
455
475
|
showValue: true,
|
|
456
476
|
respectReducedMotion: true
|
|
@@ -735,7 +755,7 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
735
755
|
alpha: false,
|
|
736
756
|
antialias: false,
|
|
737
757
|
depth: false,
|
|
738
|
-
powerPreference: 'high-performance',
|
|
758
|
+
powerPreference: this.options.powerPreference || 'high-performance',
|
|
739
759
|
preserveDrawingBuffer: false
|
|
740
760
|
});
|
|
741
761
|
if (!this.gl) throw new Error('WebGL2 is not available');
|
|
@@ -746,16 +766,19 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
746
766
|
this.motion = 0;
|
|
747
767
|
this.motionTarget = 0;
|
|
748
768
|
this.timeOffset = preset.seed * 0.73;
|
|
769
|
+
this.colors = preset.colors.map(hexToRgb01$1);
|
|
749
770
|
this.visible = true;
|
|
750
771
|
this.disposed = false;
|
|
751
772
|
_assertClassBrand(_CosmicRenderer_brand, this, _setupGeometry).call(this);
|
|
752
773
|
_assertClassBrand(_CosmicRenderer_brand, this, _bindEvents).call(this);
|
|
774
|
+
_assertClassBrand(_CosmicRenderer_brand, this, _bindContextEvents).call(this);
|
|
753
775
|
this.resize();
|
|
754
776
|
}
|
|
755
777
|
return _createClass(CosmicRenderer, [{
|
|
756
778
|
key: "setPreset",
|
|
757
779
|
value: function setPreset(preset) {
|
|
758
780
|
this.preset = _objectSpread2({}, preset);
|
|
781
|
+
this.colors = preset.colors.map(hexToRgb01$1);
|
|
759
782
|
this.timeOffset = preset.seed * 0.73;
|
|
760
783
|
}
|
|
761
784
|
}, {
|
|
@@ -800,15 +823,14 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
800
823
|
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
801
824
|
this.canvas.width = width;
|
|
802
825
|
this.canvas.height = height;
|
|
803
|
-
this.gl.viewport(0, 0, width, height);
|
|
804
826
|
}
|
|
827
|
+
this.gl.viewport(0, 0, width, height);
|
|
805
828
|
}
|
|
806
829
|
}, {
|
|
807
830
|
key: "draw",
|
|
808
831
|
value: function draw(elapsedSeconds) {
|
|
809
832
|
var paused = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
810
833
|
if (this.disposed || !this.visible) return;
|
|
811
|
-
this.resize();
|
|
812
834
|
var gl = this.gl;
|
|
813
835
|
this.pointer[0] += (this.pointerTarget[0] - this.pointer[0]) * 0.08;
|
|
814
836
|
this.pointer[1] += (this.pointerTarget[1] - this.pointer[1]) * 0.08;
|
|
@@ -817,16 +839,15 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
817
839
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
818
840
|
gl.enableVertexAttribArray(this.locations.position);
|
|
819
841
|
gl.vertexAttribPointer(this.locations.position, 2, gl.FLOAT, false, 0, 0);
|
|
820
|
-
var colors = this.preset.colors.map(hexToRgb01$1);
|
|
821
842
|
gl.uniform2f(this.locations.resolution, this.canvas.width, this.canvas.height);
|
|
822
843
|
gl.uniform1f(this.locations.time, this.timeOffset + (paused ? 0 : elapsedSeconds * this.preset.speed));
|
|
823
844
|
gl.uniform1f(this.locations.seed, this.preset.seed);
|
|
824
845
|
gl.uniform1f(this.locations.motion, this.motion);
|
|
825
846
|
gl.uniform2f(this.locations.pointer, this.pointer[0], this.pointer[1]);
|
|
826
|
-
gl.uniform3fv(this.locations.colorA, colors[0]);
|
|
827
|
-
gl.uniform3fv(this.locations.colorB, colors[1]);
|
|
828
|
-
gl.uniform3fv(this.locations.colorC, colors[2]);
|
|
829
|
-
gl.uniform3fv(this.locations.colorD, colors[3]);
|
|
847
|
+
gl.uniform3fv(this.locations.colorA, this.colors[0]);
|
|
848
|
+
gl.uniform3fv(this.locations.colorB, this.colors[1]);
|
|
849
|
+
gl.uniform3fv(this.locations.colorC, this.colors[2]);
|
|
850
|
+
gl.uniform3fv(this.locations.colorD, this.colors[3]);
|
|
830
851
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
831
852
|
}
|
|
832
853
|
}, {
|
|
@@ -837,6 +858,8 @@ var CosmicRenderer = /*#__PURE__*/function () {
|
|
|
837
858
|
target.removeEventListener('pointermove', this.onPointerMove);
|
|
838
859
|
target.removeEventListener('pointerdown', this.onPointerMove);
|
|
839
860
|
target.removeEventListener('pointerleave', this.onPointerLeave);
|
|
861
|
+
this.canvas.removeEventListener('webglcontextlost', this.onContextLost, false);
|
|
862
|
+
this.canvas.removeEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
840
863
|
this.gl.deleteBuffer(this.buffer);
|
|
841
864
|
this.gl.deleteProgram(this.program);
|
|
842
865
|
var lose = this.gl.getExtension('WEBGL_lose_context');
|
|
@@ -893,6 +916,26 @@ function _bindEvents() {
|
|
|
893
916
|
passive: true
|
|
894
917
|
});
|
|
895
918
|
}
|
|
919
|
+
function _bindContextEvents() {
|
|
920
|
+
var _this3 = this;
|
|
921
|
+
this.onContextLost = function (event) {
|
|
922
|
+
event.preventDefault();
|
|
923
|
+
if (_this3.disposed) return;
|
|
924
|
+
_this3.visible = false;
|
|
925
|
+
if (typeof _this3.options.onContextLost === 'function') _this3.options.onContextLost(event);
|
|
926
|
+
};
|
|
927
|
+
this.onContextRestored = function () {
|
|
928
|
+
if (_this3.disposed) return;
|
|
929
|
+
_this3.program = createProgram$1(_this3.gl);
|
|
930
|
+
_this3.locations = _assertClassBrand(_CosmicRenderer_brand, _this3, _getLocations).call(_this3);
|
|
931
|
+
_assertClassBrand(_CosmicRenderer_brand, _this3, _setupGeometry).call(_this3);
|
|
932
|
+
_this3.visible = true;
|
|
933
|
+
_this3.resize();
|
|
934
|
+
if (typeof _this3.options.onContextRestored === 'function') _this3.options.onContextRestored();
|
|
935
|
+
};
|
|
936
|
+
this.canvas.addEventListener('webglcontextlost', this.onContextLost, false);
|
|
937
|
+
this.canvas.addEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
938
|
+
}
|
|
896
939
|
|
|
897
940
|
function rgb(color) {
|
|
898
941
|
var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
@@ -907,18 +950,20 @@ function rgb(color) {
|
|
|
907
950
|
}
|
|
908
951
|
var FallbackRenderer = /*#__PURE__*/function () {
|
|
909
952
|
function FallbackRenderer(canvas, preset) {
|
|
953
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
910
954
|
_classCallCheck(this, FallbackRenderer);
|
|
911
955
|
this.canvas = canvas;
|
|
912
956
|
this.preset = preset;
|
|
913
957
|
this.context = canvas.getContext('2d');
|
|
914
958
|
this.visible = true;
|
|
915
959
|
this.timePhase = 0;
|
|
960
|
+
this.dprCap = options.dprCap || 1.5;
|
|
916
961
|
}
|
|
917
962
|
return _createClass(FallbackRenderer, [{
|
|
918
963
|
key: "resize",
|
|
919
964
|
value: function resize() {
|
|
920
965
|
var rect = this.canvas.getBoundingClientRect();
|
|
921
|
-
var dpr = Math.min(window.devicePixelRatio || 1,
|
|
966
|
+
var dpr = Math.min(window.devicePixelRatio || 1, this.dprCap);
|
|
922
967
|
var width = Math.max(2, Math.round(rect.width * dpr));
|
|
923
968
|
var height = Math.max(2, Math.round(rect.height * dpr));
|
|
924
969
|
if (this.canvas.width !== width || this.canvas.height !== height) {
|
|
@@ -959,7 +1004,6 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
959
1004
|
key: "draw",
|
|
960
1005
|
value: function draw(time) {
|
|
961
1006
|
if (!this.visible) return;
|
|
962
|
-
this.resize();
|
|
963
1007
|
this.drawNebula(time);
|
|
964
1008
|
}
|
|
965
1009
|
}, {
|
|
@@ -967,6 +1011,12 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
967
1011
|
value: function setPreset(preset) {
|
|
968
1012
|
this.preset = preset;
|
|
969
1013
|
}
|
|
1014
|
+
}, {
|
|
1015
|
+
key: "setDprCap",
|
|
1016
|
+
value: function setDprCap(cap) {
|
|
1017
|
+
this.dprCap = cap;
|
|
1018
|
+
this.resize();
|
|
1019
|
+
}
|
|
970
1020
|
}, {
|
|
971
1021
|
key: "randomize",
|
|
972
1022
|
value: function randomize() {
|
|
@@ -984,10 +1034,10 @@ var FallbackRenderer = /*#__PURE__*/function () {
|
|
|
984
1034
|
}]);
|
|
985
1035
|
}();
|
|
986
1036
|
|
|
987
|
-
/**
|
|
988
|
-
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
989
|
-
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
990
|
-
* original demo), which avoids jank from many competing rAF loops.
|
|
1037
|
+
/**
|
|
1038
|
+
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
1039
|
+
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
1040
|
+
* original demo), which avoids jank from many competing rAF loops.
|
|
991
1041
|
*/
|
|
992
1042
|
var subscribers = [];
|
|
993
1043
|
var running = false;
|
|
@@ -995,11 +1045,7 @@ var rafId = 0;
|
|
|
995
1045
|
var last = 0;
|
|
996
1046
|
function tick(now) {
|
|
997
1047
|
if (!running) return;
|
|
998
|
-
var
|
|
999
|
-
last = now;
|
|
1000
|
-
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
1001
|
-
// subscriber can never kill the whole animation loop.
|
|
1002
|
-
rafId = requestAnimationFrame(tick);
|
|
1048
|
+
var activeItems = [];
|
|
1003
1049
|
{
|
|
1004
1050
|
var _iterator = _createForOfIteratorHelper(subscribers.slice()),
|
|
1005
1051
|
_step;
|
|
@@ -1007,10 +1053,8 @@ function tick(now) {
|
|
|
1007
1053
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
1008
1054
|
var item = _step.value;
|
|
1009
1055
|
try {
|
|
1010
|
-
if (!item.isPaused())
|
|
1011
|
-
} catch (
|
|
1012
|
-
console.warn('[dlc-ui] frame error:', error);
|
|
1013
|
-
}
|
|
1056
|
+
if (!item.isPaused()) activeItems.push(item);
|
|
1057
|
+
} catch (_unused) {}
|
|
1014
1058
|
}
|
|
1015
1059
|
} catch (err) {
|
|
1016
1060
|
_iterator.e(err);
|
|
@@ -1018,6 +1062,25 @@ function tick(now) {
|
|
|
1018
1062
|
_iterator.f();
|
|
1019
1063
|
}
|
|
1020
1064
|
}
|
|
1065
|
+
if (activeItems.length === 0) {
|
|
1066
|
+
running = false;
|
|
1067
|
+
rafId = 0;
|
|
1068
|
+
last = 0;
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
var delta = last ? Math.min((now - last) / 1000, 0.05) : 0;
|
|
1072
|
+
last = now;
|
|
1073
|
+
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
1074
|
+
// subscriber can never kill the whole animation loop.
|
|
1075
|
+
rafId = requestAnimationFrame(tick);
|
|
1076
|
+
for (var _i = 0, _activeItems = activeItems; _i < _activeItems.length; _i++) {
|
|
1077
|
+
var _item = _activeItems[_i];
|
|
1078
|
+
try {
|
|
1079
|
+
_item.onFrame(delta, now);
|
|
1080
|
+
} catch (error) {
|
|
1081
|
+
console.warn('[dlc-ui] frame error:', error);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1021
1084
|
if (subscribers.length === 0) {
|
|
1022
1085
|
cancelAnimationFrame(rafId);
|
|
1023
1086
|
running = false;
|
|
@@ -1030,6 +1093,9 @@ function start() {
|
|
|
1030
1093
|
last = 0;
|
|
1031
1094
|
rafId = requestAnimationFrame(tick);
|
|
1032
1095
|
}
|
|
1096
|
+
function wakeScheduler() {
|
|
1097
|
+
start();
|
|
1098
|
+
}
|
|
1033
1099
|
function subscribeScheduler(onFrame, isPaused) {
|
|
1034
1100
|
var item = {
|
|
1035
1101
|
onFrame: onFrame,
|
|
@@ -1048,11 +1114,12 @@ function subscribeScheduler(onFrame, isPaused) {
|
|
|
1048
1114
|
};
|
|
1049
1115
|
}
|
|
1050
1116
|
|
|
1051
|
-
/**
|
|
1052
|
-
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
1053
|
-
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
1117
|
+
/**
|
|
1118
|
+
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
1119
|
+
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
1054
1120
|
*/
|
|
1055
1121
|
function createVisibilityGuard(element) {
|
|
1122
|
+
var onChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
1056
1123
|
var intersecting = true;
|
|
1057
1124
|
var pageVisible = typeof document === 'undefined' || !document.hidden;
|
|
1058
1125
|
var disposed = false;
|
|
@@ -1062,6 +1129,7 @@ function createVisibilityGuard(element) {
|
|
|
1062
1129
|
intersecting = entries.some(function (entry) {
|
|
1063
1130
|
return entry.isIntersecting;
|
|
1064
1131
|
});
|
|
1132
|
+
if (typeof onChange === 'function') onChange();
|
|
1065
1133
|
}, {
|
|
1066
1134
|
rootMargin: '180px'
|
|
1067
1135
|
});
|
|
@@ -1069,6 +1137,7 @@ function createVisibilityGuard(element) {
|
|
|
1069
1137
|
}
|
|
1070
1138
|
var onVisibilityChange = function onVisibilityChange() {
|
|
1071
1139
|
pageVisible = typeof document !== 'undefined' && !document.hidden;
|
|
1140
|
+
if (typeof onChange === 'function') onChange();
|
|
1072
1141
|
};
|
|
1073
1142
|
if (typeof document !== 'undefined') {
|
|
1074
1143
|
document.addEventListener('visibilitychange', onVisibilityChange);
|
|
@@ -1104,18 +1173,69 @@ function nextTick(fn) {
|
|
|
1104
1173
|
}
|
|
1105
1174
|
}
|
|
1106
1175
|
|
|
1107
|
-
function
|
|
1108
|
-
|
|
1176
|
+
function normalizeFps(value) {
|
|
1177
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 60;
|
|
1178
|
+
var fps = Number(value);
|
|
1179
|
+
if (!Number.isFinite(fps)) return fallback;
|
|
1180
|
+
return Math.min(60, Math.max(1, fps));
|
|
1181
|
+
}
|
|
1182
|
+
function createFrameGate() {
|
|
1183
|
+
var initialFps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 60;
|
|
1184
|
+
var fps = normalizeFps(initialFps);
|
|
1185
|
+
var elapsed = 0;
|
|
1186
|
+
return {
|
|
1187
|
+
shouldDraw: function shouldDraw(delta) {
|
|
1188
|
+
elapsed += delta;
|
|
1189
|
+
var interval = 1 / fps;
|
|
1190
|
+
if (elapsed + 0.0001 < interval) return false;
|
|
1191
|
+
elapsed %= interval;
|
|
1192
|
+
return true;
|
|
1193
|
+
},
|
|
1194
|
+
setFps: function setFps(value) {
|
|
1195
|
+
fps = normalizeFps(value, fps);
|
|
1196
|
+
elapsed = 0;
|
|
1197
|
+
return fps;
|
|
1198
|
+
},
|
|
1199
|
+
getFps: function getFps() {
|
|
1200
|
+
return fps;
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
function createReducedMotionPreference(enabled, onChange) {
|
|
1205
|
+
var query = enabled && typeof matchMedia !== 'undefined' ? matchMedia('(prefers-reduced-motion: reduce)') : null;
|
|
1206
|
+
var notify = function notify() {
|
|
1207
|
+
if (typeof onChange === 'function') onChange(Boolean(query && query.matches));
|
|
1208
|
+
};
|
|
1209
|
+
if (query) {
|
|
1210
|
+
if (typeof query.addEventListener === 'function') query.addEventListener('change', notify);else if (typeof query.addListener === 'function') query.addListener(notify);
|
|
1211
|
+
}
|
|
1212
|
+
return {
|
|
1213
|
+
matches: function matches() {
|
|
1214
|
+
return Boolean(query && query.matches);
|
|
1215
|
+
},
|
|
1216
|
+
dispose: function dispose() {
|
|
1217
|
+
if (!query) return;
|
|
1218
|
+
if (typeof query.removeEventListener === 'function') query.removeEventListener('change', notify);else if (typeof query.removeListener === 'function') query.removeListener(notify);
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
function toFiniteNumber(value) {
|
|
1224
|
+
if (value == null || typeof value === 'boolean') return null;
|
|
1225
|
+
if (typeof value === 'string' && value.trim() === '') return null;
|
|
1226
|
+
var number = Number(value);
|
|
1227
|
+
return Number.isFinite(number) ? number : null;
|
|
1109
1228
|
}
|
|
1110
1229
|
|
|
1111
|
-
/**
|
|
1230
|
+
/**
|
|
1112
1231
|
* Mount a cosmic (nebula) capsule into `container`.
|
|
1113
1232
|
*
|
|
1114
1233
|
* Options: preset (literary name), width, height (number=px or string with
|
|
1115
1234
|
* px/%/vw/vh/em/rem), colors, seed, speed, textRatio (0-100, text region
|
|
1116
1235
|
* width in percent), text (HTML string or DOM nodes for the text slot),
|
|
1117
1236
|
* colorContent (HTML string or DOM nodes for the color slot), quality,
|
|
1118
|
-
* renderer,
|
|
1237
|
+
* renderer, quality, renderScale, powerPreference, fps, paused/static,
|
|
1238
|
+
* respectReducedMotion, mouseColor, cssVars.
|
|
1119
1239
|
*/
|
|
1120
1240
|
function createCapsule(container) {
|
|
1121
1241
|
var _options$preset;
|
|
@@ -1125,10 +1245,19 @@ function createCapsule(container) {
|
|
|
1125
1245
|
}
|
|
1126
1246
|
var preset = _objectSpread2({}, getPreset('capsule', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '初光'));
|
|
1127
1247
|
var merged = normalizeOptions(DEFAULTS.capsule, preset, options);
|
|
1128
|
-
var normalizedColors = merged.colors.map(normalizeColor);
|
|
1129
|
-
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
1130
|
-
|
|
1131
|
-
|
|
1248
|
+
var normalizedColors = Array.isArray(merged.colors) ? merged.colors.map(normalizeColor) : [];
|
|
1249
|
+
if (normalizedColors.length === 4 && normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
1250
|
+
var initialSeed = toFiniteNumber(merged.seed);
|
|
1251
|
+
var initialSpeed = toFiniteNumber(merged.speed);
|
|
1252
|
+
if (initialSeed !== null) preset.seed = initialSeed;
|
|
1253
|
+
if (initialSpeed !== null) preset.speed = initialSpeed;
|
|
1254
|
+
merged.colors = _toConsumableArray(preset.colors);
|
|
1255
|
+
merged.seed = preset.seed;
|
|
1256
|
+
merged.speed = preset.speed;
|
|
1257
|
+
var optionColors = Array.isArray(options.colors) ? options.colors.map(normalizeColor) : [];
|
|
1258
|
+
var colorOverride = optionColors.length === 4 && optionColors.every(Boolean) ? _toConsumableArray(optionColors) : null;
|
|
1259
|
+
var seedOverride = options.seed !== undefined ? toFiniteNumber(options.seed) : null;
|
|
1260
|
+
var speedOverride = options.speed !== undefined ? toFiniteNumber(options.speed) : null;
|
|
1132
1261
|
var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
|
|
1133
1262
|
var root = document.createElement('div');
|
|
1134
1263
|
root.className = 'hj-capsule-root hj-capsule-cosmic';
|
|
@@ -1180,25 +1309,49 @@ function createCapsule(container) {
|
|
|
1180
1309
|
root.appendChild(canvas);
|
|
1181
1310
|
container.appendChild(root);
|
|
1182
1311
|
var emitter = createEmitter();
|
|
1183
|
-
var
|
|
1312
|
+
var manuallyPaused = merged.paused === true;
|
|
1313
|
+
var reducedPaused = false;
|
|
1314
|
+
var staticMode = merged.static === true;
|
|
1315
|
+
var contextLost = false;
|
|
1184
1316
|
var disposed = false;
|
|
1317
|
+
var renderOnce = function renderOnce() {};
|
|
1185
1318
|
var dirty = {
|
|
1186
1319
|
preset: false,
|
|
1187
1320
|
seed: false,
|
|
1188
1321
|
speed: false,
|
|
1189
1322
|
colors: false,
|
|
1190
1323
|
textRatio: false,
|
|
1191
|
-
cssVars: false
|
|
1324
|
+
cssVars: false,
|
|
1325
|
+
mouseColor: false,
|
|
1326
|
+
quality: false,
|
|
1327
|
+
renderScale: false,
|
|
1328
|
+
paused: false,
|
|
1329
|
+
static: false,
|
|
1330
|
+
fps: false
|
|
1192
1331
|
};
|
|
1193
1332
|
var renderer;
|
|
1194
1333
|
var useWebgl = merged.renderer !== 'canvas2d';
|
|
1195
1334
|
if (useWebgl) {
|
|
1196
1335
|
try {
|
|
1197
1336
|
renderer = new CosmicRenderer(canvas, merged, {
|
|
1198
|
-
dprCap:
|
|
1337
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
1338
|
+
mouseColor: merged.mouseColor !== false,
|
|
1339
|
+
powerPreference: merged.powerPreference,
|
|
1340
|
+
onContextLost: function onContextLost() {
|
|
1341
|
+
contextLost = true;
|
|
1342
|
+
emitter.emit('contextlost', {});
|
|
1343
|
+
},
|
|
1344
|
+
onContextRestored: function onContextRestored() {
|
|
1345
|
+
contextLost = false;
|
|
1346
|
+
emitter.emit('contextrestored', {});
|
|
1347
|
+
renderOnce();
|
|
1348
|
+
wakeScheduler();
|
|
1349
|
+
}
|
|
1199
1350
|
});
|
|
1200
1351
|
} catch (error) {
|
|
1201
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
1352
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
1353
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
1354
|
+
});
|
|
1202
1355
|
nextTick(function () {
|
|
1203
1356
|
if (disposed) return;
|
|
1204
1357
|
emitter.emit('error', {
|
|
@@ -1207,8 +1360,15 @@ function createCapsule(container) {
|
|
|
1207
1360
|
});
|
|
1208
1361
|
}
|
|
1209
1362
|
} else {
|
|
1210
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
1363
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
1364
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
1365
|
+
});
|
|
1211
1366
|
}
|
|
1367
|
+
var animationTime = 0;
|
|
1368
|
+
var frameGate = createFrameGate(merged.fps);
|
|
1369
|
+
renderOnce = function renderOnce() {
|
|
1370
|
+
return renderer.draw(animationTime);
|
|
1371
|
+
};
|
|
1212
1372
|
var applySize = function applySize() {
|
|
1213
1373
|
root.style.width = parseSize(merged.width);
|
|
1214
1374
|
root.style.height = parseSize(merged.height);
|
|
@@ -1226,11 +1386,21 @@ function createCapsule(container) {
|
|
|
1226
1386
|
renderer.resize();
|
|
1227
1387
|
};
|
|
1228
1388
|
applySize();
|
|
1229
|
-
var
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
var
|
|
1389
|
+
var resize = function resize() {
|
|
1390
|
+
renderer.resize();
|
|
1391
|
+
if (manuallyPaused || reducedPaused || staticMode) renderOnce();
|
|
1392
|
+
};
|
|
1393
|
+
var resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(resize) : null;
|
|
1394
|
+
if (resizeObserver) resizeObserver.observe(root);else window.addEventListener('resize', resize);
|
|
1395
|
+
var visibility = createVisibilityGuard(root, wakeScheduler);
|
|
1396
|
+
var motionPreference = createReducedMotionPreference(merged.respectReducedMotion, function (matches) {
|
|
1397
|
+
reducedPaused = matches;
|
|
1398
|
+
if (matches) renderOnce();else wakeScheduler();
|
|
1399
|
+
});
|
|
1400
|
+
reducedPaused = motionPreference.matches();
|
|
1401
|
+
var isMotionPaused = function isMotionPaused() {
|
|
1402
|
+
return manuallyPaused || reducedPaused || staticMode || contextLost;
|
|
1403
|
+
};
|
|
1234
1404
|
root.addEventListener('pointerenter', function () {
|
|
1235
1405
|
return emitter.emit('pointerenter', {
|
|
1236
1406
|
preset: _objectSpread2({}, preset)
|
|
@@ -1265,12 +1435,12 @@ function createCapsule(container) {
|
|
|
1265
1435
|
preset: _objectSpread2({}, preset)
|
|
1266
1436
|
});
|
|
1267
1437
|
});
|
|
1268
|
-
|
|
1438
|
+
renderOnce();
|
|
1269
1439
|
var unsubscribe = subscribeScheduler(function (delta) {
|
|
1270
1440
|
animationTime += delta;
|
|
1271
|
-
if (
|
|
1441
|
+
if (frameGate.shouldDraw(delta)) renderer.draw(animationTime);
|
|
1272
1442
|
}, function () {
|
|
1273
|
-
return
|
|
1443
|
+
return isMotionPaused() || !visibility.isVisible();
|
|
1274
1444
|
});
|
|
1275
1445
|
nextTick(function () {
|
|
1276
1446
|
if (disposed) return;
|
|
@@ -1293,11 +1463,15 @@ function createCapsule(container) {
|
|
|
1293
1463
|
var next = getPreset('capsule', ref);
|
|
1294
1464
|
dirty.preset = true;
|
|
1295
1465
|
Object.assign(preset, next);
|
|
1466
|
+
if (colorOverride) preset.colors = _toConsumableArray(colorOverride);
|
|
1467
|
+
if (seedOverride !== null) preset.seed = seedOverride;
|
|
1468
|
+
if (speedOverride !== null) preset.speed = speedOverride;
|
|
1296
1469
|
var nextColors = preset.colors.map(normalizeColor);
|
|
1297
1470
|
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
1298
1471
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1299
1472
|
syncTheme();
|
|
1300
1473
|
renderer.resize();
|
|
1474
|
+
if (isMotionPaused()) renderOnce();
|
|
1301
1475
|
emitter.emit('presetchange', {
|
|
1302
1476
|
preset: _objectSpread2({}, next)
|
|
1303
1477
|
});
|
|
@@ -1309,26 +1483,32 @@ function createCapsule(container) {
|
|
|
1309
1483
|
return !color;
|
|
1310
1484
|
})) return this;
|
|
1311
1485
|
dirty.colors = true;
|
|
1486
|
+
colorOverride = _toConsumableArray(next);
|
|
1312
1487
|
preset.colors = next;
|
|
1313
1488
|
renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
|
|
1314
1489
|
colors: next
|
|
1315
1490
|
}));
|
|
1491
|
+
if (isMotionPaused()) renderOnce();
|
|
1316
1492
|
return this;
|
|
1317
1493
|
},
|
|
1318
1494
|
setSeed: function setSeed(seed) {
|
|
1319
|
-
var value =
|
|
1320
|
-
if (
|
|
1495
|
+
var value = toFiniteNumber(seed);
|
|
1496
|
+
if (value === null) return this;
|
|
1321
1497
|
dirty.seed = true;
|
|
1498
|
+
seedOverride = value;
|
|
1322
1499
|
preset.seed = value;
|
|
1323
1500
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1501
|
+
if (isMotionPaused()) renderOnce();
|
|
1324
1502
|
return this;
|
|
1325
1503
|
},
|
|
1326
1504
|
setSpeed: function setSpeed(speed) {
|
|
1327
|
-
var value =
|
|
1328
|
-
if (
|
|
1505
|
+
var value = toFiniteNumber(speed);
|
|
1506
|
+
if (value === null) return this;
|
|
1329
1507
|
dirty.speed = true;
|
|
1508
|
+
speedOverride = value;
|
|
1330
1509
|
preset.speed = value;
|
|
1331
1510
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
1511
|
+
if (isMotionPaused()) renderOnce();
|
|
1332
1512
|
return this;
|
|
1333
1513
|
},
|
|
1334
1514
|
setText: function setText(content) {
|
|
@@ -1364,6 +1544,7 @@ function createCapsule(container) {
|
|
|
1364
1544
|
return this;
|
|
1365
1545
|
},
|
|
1366
1546
|
setMouseColor: function setMouseColor(value) {
|
|
1547
|
+
dirty.mouseColor = true;
|
|
1367
1548
|
merged.mouseColor = value !== false;
|
|
1368
1549
|
if (typeof renderer.setMouseColor === 'function') renderer.setMouseColor(merged.mouseColor);
|
|
1369
1550
|
return this;
|
|
@@ -1378,6 +1559,7 @@ function createCapsule(container) {
|
|
|
1378
1559
|
merged.height = height;
|
|
1379
1560
|
}
|
|
1380
1561
|
applySize();
|
|
1562
|
+
if (isMotionPaused()) renderOnce();
|
|
1381
1563
|
return this;
|
|
1382
1564
|
},
|
|
1383
1565
|
randomize: function randomize() {
|
|
@@ -1385,23 +1567,59 @@ function createCapsule(container) {
|
|
|
1385
1567
|
return this;
|
|
1386
1568
|
},
|
|
1387
1569
|
pause: function pause() {
|
|
1388
|
-
paused = true;
|
|
1570
|
+
dirty.paused = true;
|
|
1571
|
+
manuallyPaused = true;
|
|
1572
|
+
renderOnce();
|
|
1389
1573
|
return this;
|
|
1390
1574
|
},
|
|
1391
1575
|
resume: function resume() {
|
|
1392
|
-
paused =
|
|
1576
|
+
dirty.paused = true;
|
|
1577
|
+
manuallyPaused = false;
|
|
1578
|
+
wakeScheduler();
|
|
1579
|
+
return this;
|
|
1580
|
+
},
|
|
1581
|
+
setPaused: function setPaused(value) {
|
|
1582
|
+
return value ? this.pause() : this.resume();
|
|
1583
|
+
},
|
|
1584
|
+
setStatic: function setStatic(value) {
|
|
1585
|
+
dirty.static = true;
|
|
1586
|
+
staticMode = value === true;
|
|
1587
|
+
merged.static = staticMode;
|
|
1588
|
+
if (staticMode) renderOnce();else wakeScheduler();
|
|
1589
|
+
return this;
|
|
1590
|
+
},
|
|
1591
|
+
setFps: function setFps(fps) {
|
|
1592
|
+
dirty.fps = true;
|
|
1593
|
+
merged.fps = frameGate.setFps(fps);
|
|
1594
|
+
wakeScheduler();
|
|
1393
1595
|
return this;
|
|
1394
1596
|
},
|
|
1395
1597
|
setQuality: function setQuality(quality) {
|
|
1598
|
+
dirty.quality = true;
|
|
1396
1599
|
merged.quality = quality;
|
|
1397
|
-
if (typeof renderer.setDprCap === 'function')
|
|
1600
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
1601
|
+
renderer.setDprCap(effectiveDprCap(quality, merged.renderScale));
|
|
1602
|
+
}
|
|
1603
|
+
if (isMotionPaused()) renderOnce();
|
|
1604
|
+
return this;
|
|
1605
|
+
},
|
|
1606
|
+
setRenderScale: function setRenderScale(renderScale) {
|
|
1607
|
+
var value = Number(renderScale);
|
|
1608
|
+
if (!Number.isFinite(value)) return this;
|
|
1609
|
+
dirty.renderScale = true;
|
|
1610
|
+
merged.renderScale = Math.min(1, Math.max(0.25, value));
|
|
1611
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
1612
|
+
renderer.setDprCap(effectiveDprCap(merged.quality, merged.renderScale));
|
|
1613
|
+
}
|
|
1614
|
+
if (isMotionPaused()) renderOnce();
|
|
1398
1615
|
return this;
|
|
1399
1616
|
},
|
|
1400
1617
|
dispose: function dispose() {
|
|
1401
1618
|
disposed = true;
|
|
1402
1619
|
unsubscribe();
|
|
1403
1620
|
visibility.dispose();
|
|
1404
|
-
|
|
1621
|
+
motionPreference.dispose();
|
|
1622
|
+
if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', resize);
|
|
1405
1623
|
renderer.dispose();
|
|
1406
1624
|
root.remove();
|
|
1407
1625
|
},
|
|
@@ -1411,6 +1629,24 @@ function createCapsule(container) {
|
|
|
1411
1629
|
get cssVars() {
|
|
1412
1630
|
return merged.cssVars;
|
|
1413
1631
|
},
|
|
1632
|
+
get mouseColor() {
|
|
1633
|
+
return merged.mouseColor;
|
|
1634
|
+
},
|
|
1635
|
+
get quality() {
|
|
1636
|
+
return merged.quality;
|
|
1637
|
+
},
|
|
1638
|
+
get renderScale() {
|
|
1639
|
+
return merged.renderScale;
|
|
1640
|
+
},
|
|
1641
|
+
get paused() {
|
|
1642
|
+
return manuallyPaused;
|
|
1643
|
+
},
|
|
1644
|
+
get static() {
|
|
1645
|
+
return staticMode;
|
|
1646
|
+
},
|
|
1647
|
+
get fps() {
|
|
1648
|
+
return frameGate.getFps();
|
|
1649
|
+
},
|
|
1414
1650
|
dirty: dirty
|
|
1415
1651
|
};
|
|
1416
1652
|
}
|
|
@@ -1520,7 +1756,7 @@ var MOTION_SCALE_FACTORS = {
|
|
|
1520
1756
|
'tide': 1.18
|
|
1521
1757
|
};
|
|
1522
1758
|
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}";
|
|
1523
|
-
var FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\n\nin vec2 v_uv;\nout vec4 outColor;\n\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform float u_progress;\nuniform float u_seed;\nuniform float u_profile;\nuniform sampler2D u_motion;\nuniform sampler2D u_effect;\nuniform float u_hasEffect;\nuniform float u_effectFrames;\nuniform float u_motionDuration;\nuniform float u_motionScale;\nuniform vec3 u_dark;\nuniform vec3 u_accentA;\nuniform vec3 u_accentB;\nuniform vec3 u_glow;\n\nfloat hash21(vec2 p) {\n p = fract(p * vec2(123.34, 456.21));\n p += dot(p, p + 45.32 + u_seed * 11.7);\n return fract(p.x * p.y);\n}\n\nfloat noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n float a = hash21(i);\n float b = hash21(i + vec2(1.0, 0.0));\n float c = hash21(i + vec2(0.0, 1.0));\n float d = hash21(i + vec2(1.0, 1.0));\n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\nfloat fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.55;\n mat2 rotation = mat2(0.82, 0.57, -0.57, 0.82);\n for (int i = 0; i < 6; i++) {\n value += noise(p) * amplitude;\n p = rotation * p * 2.02 + 13.7;\n amplitude *= 0.48;\n }\n return value;\n}\n\nfloat gaussian(float value, float center, float width) {\n float delta = (value - center) / max(width, 0.0001);\n return exp(-delta * delta);\n}\n\nfloat profileMix(float model, float agent, float visual) {\n if (u_profile < 0.5) return model;\n if (u_profile < 1.5) return agent;\n return visual;\n}\n\nfloat motionSample(float y, float t) {\n float phase = fract(t / max(u_motionDuration, 0.001));\n float captured = texture(u_motion, vec2(phase, 1.0 - clamp(y, 0.0, 1.0))).r;\n return (captured * 2.0 - 1.0) * u_motionScale;\n}\n\nfloat edgeDisplacement(float y, float t) {\n return motionSample(y, t);\n}\n\nfloat flowDisplacement(float y, float t) {\n return (\n motionSample(y - 0.024, t) * 0.08 +\n motionSample(y - 0.012, t) * 0.18 +\n motionSample(y, t) * 0.48 +\n motionSample(y + 0.012, t) * 0.18 +\n motionSample(y + 0.024, t) * 0.08\n );\n}\n\nfloat ellipseRing(vec2 p, float radius, float width) {\n return gaussian(length(p), radius, width);\n}\n\nvoid main() {\n vec2 uv = v_uv;\n float t = u_time;\n float edge = u_progress + edgeDisplacement(uv.y, t);\n float flowEdge = u_progress + flowDisplacement(uv.y, t);\n float d = uv.x - edge;\n float fd = uv.x - flowEdge;\n\n vec3 rightBase = vec3(0.125, 0.129, 0.145);\n vec3 color = rightBase;\n\n float leftMask = 1.0 - smoothstep(-0.001, 0.002, d);\n color = mix(color, u_dark, leftMask * profileMix(0.96, 0.92, 0.96));\n\n vec2 flowP = vec2((fd + 0.10) * 6.2, uv.y * 1.95);\n float flowA = fbm(flowP + vec2(-t * 0.22, t * 0.27) + u_seed * 1.7);\n float flowB = fbm(flowP * 1.52 + vec2(t * 0.28, -t * 0.36) + 8.2 + u_seed);\n float flowC = fbm(flowP * 2.25 + vec2(-t * 0.41, t * 0.46) + 19.0);\n\n float farCenter = profileMix(-0.060, -0.079, -0.045) + (flowA - 0.5) * profileMix(0.018, 0.022, 0.014);\n float midCenter = profileMix(-0.039, -0.052, -0.030) + (flowB - 0.5) * profileMix(0.013, 0.016, 0.010);\n float hotCenter = profileMix(-0.026, -0.029, -0.023) + (flowC - 0.5) * 0.010;\n\n float farBand = gaussian(fd, farCenter, profileMix(0.035, 0.049, 0.030));\n float midBand = gaussian(fd, midCenter, profileMix(0.026, 0.034, 0.026));\n float hotBand = gaussian(fd, hotCenter, profileMix(0.023, 0.027, 0.026));\n float darkTrough = gaussian(fd, profileMix(-0.050, -0.058, -0.044) + (flowB - 0.5) * 0.010, profileMix(0.020, 0.025, 0.021));\n\n float ringY = 0.47 + sin(t * 0.58 + u_seed * 2.4) * 0.12;\n vec2 ringP = vec2((fd + 0.086) / 0.078, (uv.y - ringY) / 0.25);\n ringP += vec2((flowB - 0.5) * 0.08, (flowA - 0.5) * 0.06);\n float ringTexture = fbm(ringP * 2.15 + vec2(t * 0.18, -t * 0.14) + u_seed * 1.9);\n float ring = ellipseRing(ringP, 0.66, 0.32) * (0.30 + 0.64 * ringTexture);\n float ringCore = gaussian(length(ringP), 0.25, 0.25);\n float ringPulse = smoothstep(0.58, 0.90, 0.5 + 0.5 * sin(t * 0.82 + u_seed * 4.1));\n float modelRing = ring * ringPulse * (1.0 - step(0.5, u_profile));\n float visualRing = ring * 0.16 * step(1.5, u_profile) * ringPulse;\n\n float cloudGate = leftMask * smoothstep(-0.30, -0.008, fd);\n float textureA = smoothstep(0.24, 0.92, flowA * 0.72 + flowB * 0.42);\n float textureB = smoothstep(0.28, 0.94, flowB * 0.68 + flowC * 0.38);\n\n vec3 hotColor = u_accentB;\n color += u_accentA * farBand * cloudGate * (0.07 + textureA * profileMix(0.42, 0.24, 0.40));\n color += u_accentB * midBand * cloudGate * (0.15 + textureB * profileMix(0.70, 0.46, 0.68));\n color += hotColor * hotBand * cloudGate * profileMix(0.88, 0.62, 0.84);\n float modelMask = 1.0 - step(0.5, u_profile);\n color += u_accentA * (modelRing + visualRing) * cloudGate * profileMix(0.54, 0.0, 0.34);\n color *= 1.0 - darkTrough * profileMix(0.44, 0.24, 0.24) * cloudGate;\n color *= 1.0 - ringCore * modelMask * ringPulse * 0.44 * cloudGate;\n\n float broadHalo = exp(-abs(d) * 96.0);\n float innerHalo = exp(-abs(d) * 176.0);\n float colorCore = exp(-abs(d) * 360.0);\n float sharpCore = exp(-abs(d) * 760.0);\n float leftGate = 1.0 - smoothstep(-0.003, 0.005, d);\n\n color += u_accentA * broadHalo * leftGate * profileMix(0.09, 0.04, 0.06);\n color += hotColor * innerHalo * leftGate * profileMix(0.76, 0.72, 0.78);\n color += u_glow * colorCore * profileMix(0.72, 0.34, 0.24);\n\n float whiteStrength = profileMix(0.10, 0.0, 0.0);\n color += vec3(1.0, 0.99, 0.91) * sharpCore * whiteStrength;\n\n float rightCut = smoothstep(0.001, 0.006, d);\n color = mix(color, rightBase, rightCut);\n\n float effectX = (d * 1257.0 + 260.0) / 320.0;\n float atlasPhase = fract(t / 12.0) * u_effectFrames;\n float atlasFrameA = floor(atlasPhase);\n float atlasFrameB = mod(atlasFrameA + 1.0, u_effectFrames);\n float atlasMix = smoothstep(0.0, 1.0, fract(atlasPhase));\n float atlasXA = (atlasFrameA + clamp(effectX, 0.0, 1.0)) / u_effectFrames;\n float atlasXB = (atlasFrameB + clamp(effectX, 0.0, 1.0)) / u_effectFrames;\n vec3 referenceA = texture(u_effect, vec2(atlasXA, uv.y)).rgb;\n vec3 referenceB = texture(u_effect, vec2(atlasXB, uv.y)).rgb;\n vec3 referenceColor = mix(referenceA, referenceB, atlasMix);\n float stripMask = smoothstep(0.0, 0.018, effectX) * (1.0 - smoothstep(0.982, 1.0, effectX));\n float referenceLeft = 1.0 - smoothstep(-0.026, -0.012, d);\n color = mix(color,
|
|
1759
|
+
var FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\n\nin vec2 v_uv;\nout vec4 outColor;\n\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform float u_progress;\nuniform float u_seed;\nuniform float u_profile;\nuniform sampler2D u_motion;\nuniform sampler2D u_effect;\nuniform float u_hasEffect;\nuniform float u_effectFrames;\nuniform float u_motionDuration;\nuniform float u_motionScale;\nuniform vec3 u_dark;\nuniform vec3 u_accentA;\nuniform vec3 u_accentB;\nuniform vec3 u_glow;\n\nfloat hash21(vec2 p) {\n p = fract(p * vec2(123.34, 456.21));\n p += dot(p, p + 45.32 + u_seed * 11.7);\n return fract(p.x * p.y);\n}\n\nfloat noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n float a = hash21(i);\n float b = hash21(i + vec2(1.0, 0.0));\n float c = hash21(i + vec2(0.0, 1.0));\n float d = hash21(i + vec2(1.0, 1.0));\n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\nfloat fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.55;\n mat2 rotation = mat2(0.82, 0.57, -0.57, 0.82);\n for (int i = 0; i < 6; i++) {\n value += noise(p) * amplitude;\n p = rotation * p * 2.02 + 13.7;\n amplitude *= 0.48;\n }\n return value;\n}\n\nfloat gaussian(float value, float center, float width) {\n float delta = (value - center) / max(width, 0.0001);\n return exp(-delta * delta);\n}\n\nfloat profileMix(float model, float agent, float visual) {\n if (u_profile < 0.5) return model;\n if (u_profile < 1.5) return agent;\n return visual;\n}\n\nfloat motionSample(float y, float t) {\n float phase = fract(t / max(u_motionDuration, 0.001));\n float captured = texture(u_motion, vec2(phase, 1.0 - clamp(y, 0.0, 1.0))).r;\n return (captured * 2.0 - 1.0) * u_motionScale;\n}\n\nfloat edgeDisplacement(float y, float t) {\n return motionSample(y, t);\n}\n\nfloat flowDisplacement(float y, float t) {\n return (\n motionSample(y - 0.024, t) * 0.08 +\n motionSample(y - 0.012, t) * 0.18 +\n motionSample(y, t) * 0.48 +\n motionSample(y + 0.012, t) * 0.18 +\n motionSample(y + 0.024, t) * 0.08\n );\n}\n\nfloat ellipseRing(vec2 p, float radius, float width) {\n return gaussian(length(p), radius, width);\n}\n\nvoid main() {\n vec2 uv = v_uv;\n float t = u_time;\n float edge = u_progress + edgeDisplacement(uv.y, t);\n float flowEdge = u_progress + flowDisplacement(uv.y, t);\n float d = uv.x - edge;\n float fd = uv.x - flowEdge;\n\n vec3 rightBase = vec3(0.125, 0.129, 0.145);\n vec3 color = rightBase;\n\n float leftMask = 1.0 - smoothstep(-0.001, 0.002, d);\n color = mix(color, u_dark, leftMask * profileMix(0.96, 0.92, 0.96));\n\n vec2 flowP = vec2((fd + 0.10) * 6.2, uv.y * 1.95);\n float flowA = fbm(flowP + vec2(-t * 0.22, t * 0.27) + u_seed * 1.7);\n float flowB = fbm(flowP * 1.52 + vec2(t * 0.28, -t * 0.36) + 8.2 + u_seed);\n float flowC = fbm(flowP * 2.25 + vec2(-t * 0.41, t * 0.46) + 19.0);\n\n float farCenter = profileMix(-0.060, -0.079, -0.045) + (flowA - 0.5) * profileMix(0.018, 0.022, 0.014);\n float midCenter = profileMix(-0.039, -0.052, -0.030) + (flowB - 0.5) * profileMix(0.013, 0.016, 0.010);\n float hotCenter = profileMix(-0.026, -0.029, -0.023) + (flowC - 0.5) * 0.010;\n\n float farBand = gaussian(fd, farCenter, profileMix(0.035, 0.049, 0.030));\n float midBand = gaussian(fd, midCenter, profileMix(0.026, 0.034, 0.026));\n float hotBand = gaussian(fd, hotCenter, profileMix(0.023, 0.027, 0.026));\n float darkTrough = gaussian(fd, profileMix(-0.050, -0.058, -0.044) + (flowB - 0.5) * 0.010, profileMix(0.020, 0.025, 0.021));\n\n float ringY = 0.47 + sin(t * 0.58 + u_seed * 2.4) * 0.12;\n vec2 ringP = vec2((fd + 0.086) / 0.078, (uv.y - ringY) / 0.25);\n ringP += vec2((flowB - 0.5) * 0.08, (flowA - 0.5) * 0.06);\n float ringTexture = fbm(ringP * 2.15 + vec2(t * 0.18, -t * 0.14) + u_seed * 1.9);\n float ring = ellipseRing(ringP, 0.66, 0.32) * (0.30 + 0.64 * ringTexture);\n float ringCore = gaussian(length(ringP), 0.25, 0.25);\n float ringPulse = smoothstep(0.58, 0.90, 0.5 + 0.5 * sin(t * 0.82 + u_seed * 4.1));\n float modelRing = ring * ringPulse * (1.0 - step(0.5, u_profile));\n float visualRing = ring * 0.16 * step(1.5, u_profile) * ringPulse;\n\n float cloudGate = leftMask * smoothstep(-0.30, -0.008, fd);\n float textureA = smoothstep(0.24, 0.92, flowA * 0.72 + flowB * 0.42);\n float textureB = smoothstep(0.28, 0.94, flowB * 0.68 + flowC * 0.38);\n\n vec3 hotColor = u_accentB;\n color += u_accentA * farBand * cloudGate * (0.07 + textureA * profileMix(0.42, 0.24, 0.40));\n color += u_accentB * midBand * cloudGate * (0.15 + textureB * profileMix(0.70, 0.46, 0.68));\n color += hotColor * hotBand * cloudGate * profileMix(0.88, 0.62, 0.84);\n float modelMask = 1.0 - step(0.5, u_profile);\n color += u_accentA * (modelRing + visualRing) * cloudGate * profileMix(0.54, 0.0, 0.34);\n color *= 1.0 - darkTrough * profileMix(0.44, 0.24, 0.24) * cloudGate;\n color *= 1.0 - ringCore * modelMask * ringPulse * 0.44 * cloudGate;\n\n float broadHalo = exp(-abs(d) * 96.0);\n float innerHalo = exp(-abs(d) * 176.0);\n float colorCore = exp(-abs(d) * 360.0);\n float sharpCore = exp(-abs(d) * 760.0);\n float leftGate = 1.0 - smoothstep(-0.003, 0.005, d);\n\n color += u_accentA * broadHalo * leftGate * profileMix(0.09, 0.04, 0.06);\n color += hotColor * innerHalo * leftGate * profileMix(0.76, 0.72, 0.78);\n color += u_glow * colorCore * profileMix(0.72, 0.34, 0.24);\n\n float whiteStrength = profileMix(0.10, 0.0, 0.0);\n color += vec3(1.0, 0.99, 0.91) * sharpCore * whiteStrength;\n\n float rightCut = smoothstep(0.001, 0.006, d);\n color = mix(color, rightBase, rightCut);\n\n float effectX = (d * 1257.0 + 260.0) / 320.0;\n float atlasPhase = fract(t / 12.0) * u_effectFrames;\n float atlasFrameA = floor(atlasPhase);\n float atlasFrameB = mod(atlasFrameA + 1.0, u_effectFrames);\n float atlasMix = smoothstep(0.0, 1.0, fract(atlasPhase));\n float atlasXA = (atlasFrameA + clamp(effectX, 0.0, 1.0)) / u_effectFrames;\n float atlasXB = (atlasFrameB + clamp(effectX, 0.0, 1.0)) / u_effectFrames;\n vec3 referenceA = texture(u_effect, vec2(atlasXA, uv.y)).rgb;\n vec3 referenceB = texture(u_effect, vec2(atlasXB, uv.y)).rgb;\n vec3 referenceColor = mix(referenceA, referenceB, atlasMix);\n float stripMask = smoothstep(0.0, 0.018, effectX) * (1.0 - smoothstep(0.982, 1.0, effectX));\n float referenceLeft = 1.0 - smoothstep(-0.026, -0.012, d);\n // \u53C2\u8003\u56FE\u96C6\u53EA\u63D0\u4F9B\u4EAE\u5EA6\u7ED3\u6784\uFF0C\u989C\u8272\u59CB\u7EC8\u7531\u7528\u6237 colors\uFF08u_dark / u_accentA /\n // u_accentB / u_glow\uFF09\u51B3\u5B9A\uFF1A\u8FD9\u6837 setColors / colors \u5C5E\u6027\u5728 WebGL \u8DEF\u5F84\u4E0B\n // \u771F\u5B9E\u751F\u6548\uFF0C\u6539\u8272\u6709\u53EF\u89C1\u53CD\u9988\uFF0C\u800C\u4E0D\u662F\u88AB\u56FE\u96C6\u6574\u4F53\u8986\u76D6\u3002\n float referenceLuma = dot(referenceColor, vec3(0.299, 0.587, 0.114));\n vec3 tintedColor = color * (0.42 + 0.86 * referenceLuma);\n color = mix(color, tintedColor, stripMask * referenceLeft * u_hasEffect);\n\n outColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n}";
|
|
1524
1760
|
function compileShader(gl, type, source) {
|
|
1525
1761
|
var shader = gl.createShader(type);
|
|
1526
1762
|
gl.shaderSource(shader, source);
|
|
@@ -1551,64 +1787,95 @@ function createProgram(gl) {
|
|
|
1551
1787
|
var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
1552
1788
|
function ProgressFlowRenderer(canvas, preset) {
|
|
1553
1789
|
var _PROFILE_INDEX$preset;
|
|
1790
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1554
1791
|
_classCallCheck(this, ProgressFlowRenderer);
|
|
1555
1792
|
var gl = canvas.getContext('webgl2', {
|
|
1556
1793
|
alpha: false,
|
|
1557
1794
|
antialias: true,
|
|
1558
1795
|
premultipliedAlpha: false,
|
|
1559
|
-
powerPreference: 'high-performance'
|
|
1796
|
+
powerPreference: options.powerPreference || 'high-performance'
|
|
1560
1797
|
});
|
|
1561
1798
|
if (!gl) throw new Error('WebGL2 unavailable');
|
|
1562
1799
|
this.canvas = canvas;
|
|
1800
|
+
this.options = options;
|
|
1563
1801
|
this.gl = gl;
|
|
1564
|
-
this.program = createProgram(gl);
|
|
1565
1802
|
this.profile = preset.edgeStyle === 'tide' ? 3 : (_PROFILE_INDEX$preset = PROFILE_INDEX[preset.id]) !== null && _PROFILE_INDEX$preset !== void 0 ? _PROFILE_INDEX$preset : 2;
|
|
1566
1803
|
this.seed = stringSeed$1("".concat(preset.id, "-shader")) * 13.7 + 1.0;
|
|
1567
1804
|
this.colors = preset.colors.map(hexToRgb01);
|
|
1568
1805
|
this.motionData = getProgressMotionData(preset.id, preset.edgeStyle);
|
|
1569
1806
|
var motionFactor = preset.edgeStyle === 'tide' ? MOTION_SCALE_FACTORS.tide : MOTION_SCALE_FACTORS[preset.id] || 1.04;
|
|
1570
1807
|
this.motionScale = PROGRESS_MOTION_MAX_PX * motionFactor / 1257;
|
|
1571
|
-
this.
|
|
1572
|
-
this.
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
progress: gl.getUniformLocation(this.program, 'u_progress'),
|
|
1576
|
-
seed: gl.getUniformLocation(this.program, 'u_seed'),
|
|
1577
|
-
profile: gl.getUniformLocation(this.program, 'u_profile'),
|
|
1578
|
-
motion: gl.getUniformLocation(this.program, 'u_motion'),
|
|
1579
|
-
effect: gl.getUniformLocation(this.program, 'u_effect'),
|
|
1580
|
-
hasEffect: gl.getUniformLocation(this.program, 'u_hasEffect'),
|
|
1581
|
-
effectFrames: gl.getUniformLocation(this.program, 'u_effectFrames'),
|
|
1582
|
-
motionDuration: gl.getUniformLocation(this.program, 'u_motionDuration'),
|
|
1583
|
-
motionScale: gl.getUniformLocation(this.program, 'u_motionScale'),
|
|
1584
|
-
dark: gl.getUniformLocation(this.program, 'u_dark'),
|
|
1585
|
-
accentA: gl.getUniformLocation(this.program, 'u_accentA'),
|
|
1586
|
-
accentB: gl.getUniformLocation(this.program, 'u_accentB'),
|
|
1587
|
-
glow: gl.getUniformLocation(this.program, 'u_glow')
|
|
1588
|
-
};
|
|
1589
|
-
this.buffer = gl.createBuffer();
|
|
1590
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
1591
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);
|
|
1592
|
-
this.motionTexture = gl.createTexture();
|
|
1593
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
1594
|
-
gl.bindTexture(gl.TEXTURE_2D, this.motionTexture);
|
|
1595
|
-
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
1596
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, PROGRESS_MOTION_WIDTH, PROGRESS_MOTION_HEIGHT, 0, gl.RED, gl.UNSIGNED_BYTE, this.motionData);
|
|
1597
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1598
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1599
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
|
1600
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1601
|
-
this.effectTexture = gl.createTexture();
|
|
1602
|
-
gl.activeTexture(gl.TEXTURE1);
|
|
1603
|
-
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
1604
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([32, 33, 38]));
|
|
1605
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1606
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1607
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1608
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1609
|
-
this.effectUploaded = false;
|
|
1808
|
+
this.disposed = false;
|
|
1809
|
+
this.contextLost = false;
|
|
1810
|
+
this.setupResources();
|
|
1811
|
+
this.bindContextEvents();
|
|
1610
1812
|
}
|
|
1611
1813
|
return _createClass(ProgressFlowRenderer, [{
|
|
1814
|
+
key: "setupResources",
|
|
1815
|
+
value: function setupResources() {
|
|
1816
|
+
var gl = this.gl;
|
|
1817
|
+
this.program = createProgram(gl);
|
|
1818
|
+
this.position = gl.getAttribLocation(this.program, 'a_position');
|
|
1819
|
+
this.uniforms = {
|
|
1820
|
+
resolution: gl.getUniformLocation(this.program, 'u_resolution'),
|
|
1821
|
+
time: gl.getUniformLocation(this.program, 'u_time'),
|
|
1822
|
+
progress: gl.getUniformLocation(this.program, 'u_progress'),
|
|
1823
|
+
seed: gl.getUniformLocation(this.program, 'u_seed'),
|
|
1824
|
+
profile: gl.getUniformLocation(this.program, 'u_profile'),
|
|
1825
|
+
motion: gl.getUniformLocation(this.program, 'u_motion'),
|
|
1826
|
+
effect: gl.getUniformLocation(this.program, 'u_effect'),
|
|
1827
|
+
hasEffect: gl.getUniformLocation(this.program, 'u_hasEffect'),
|
|
1828
|
+
effectFrames: gl.getUniformLocation(this.program, 'u_effectFrames'),
|
|
1829
|
+
motionDuration: gl.getUniformLocation(this.program, 'u_motionDuration'),
|
|
1830
|
+
motionScale: gl.getUniformLocation(this.program, 'u_motionScale'),
|
|
1831
|
+
dark: gl.getUniformLocation(this.program, 'u_dark'),
|
|
1832
|
+
accentA: gl.getUniformLocation(this.program, 'u_accentA'),
|
|
1833
|
+
accentB: gl.getUniformLocation(this.program, 'u_accentB'),
|
|
1834
|
+
glow: gl.getUniformLocation(this.program, 'u_glow')
|
|
1835
|
+
};
|
|
1836
|
+
this.buffer = gl.createBuffer();
|
|
1837
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
1838
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);
|
|
1839
|
+
this.motionTexture = gl.createTexture();
|
|
1840
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
1841
|
+
gl.bindTexture(gl.TEXTURE_2D, this.motionTexture);
|
|
1842
|
+
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
1843
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, PROGRESS_MOTION_WIDTH, PROGRESS_MOTION_HEIGHT, 0, gl.RED, gl.UNSIGNED_BYTE, this.motionData);
|
|
1844
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1845
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1846
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
|
1847
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1848
|
+
this.effectTexture = gl.createTexture();
|
|
1849
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
1850
|
+
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
1851
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([32, 33, 38]));
|
|
1852
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1853
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1854
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1855
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1856
|
+
this.effectUploaded = false;
|
|
1857
|
+
}
|
|
1858
|
+
}, {
|
|
1859
|
+
key: "bindContextEvents",
|
|
1860
|
+
value: function bindContextEvents() {
|
|
1861
|
+
var _this = this;
|
|
1862
|
+
this.onContextLost = function (event) {
|
|
1863
|
+
event.preventDefault();
|
|
1864
|
+
if (_this.disposed) return;
|
|
1865
|
+
_this.contextLost = true;
|
|
1866
|
+
if (typeof _this.options.onContextLost === 'function') _this.options.onContextLost(event);
|
|
1867
|
+
};
|
|
1868
|
+
this.onContextRestored = function () {
|
|
1869
|
+
if (_this.disposed) return;
|
|
1870
|
+
_this.setupResources();
|
|
1871
|
+
_this.contextLost = false;
|
|
1872
|
+
_this.gl.viewport(0, 0, _this.canvas.width, _this.canvas.height);
|
|
1873
|
+
if (typeof _this.options.onContextRestored === 'function') _this.options.onContextRestored();
|
|
1874
|
+
};
|
|
1875
|
+
this.canvas.addEventListener('webglcontextlost', this.onContextLost, false);
|
|
1876
|
+
this.canvas.addEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
1877
|
+
}
|
|
1878
|
+
}, {
|
|
1612
1879
|
key: "resize",
|
|
1613
1880
|
value: function resize(width, height, dpr) {
|
|
1614
1881
|
var pixelWidth = Math.max(1, Math.round(width * dpr));
|
|
@@ -1623,6 +1890,7 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1623
1890
|
key: "draw",
|
|
1624
1891
|
value: function draw(time, progress) {
|
|
1625
1892
|
var effectImage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
1893
|
+
if (this.disposed || this.contextLost) return;
|
|
1626
1894
|
var gl = this.gl;
|
|
1627
1895
|
gl.useProgram(this.program);
|
|
1628
1896
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
@@ -1639,7 +1907,8 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1639
1907
|
gl.uniform1f(this.uniforms.motionDuration, PROGRESS_MOTION_DURATION);
|
|
1640
1908
|
gl.uniform1f(this.uniforms.motionScale, this.motionScale);
|
|
1641
1909
|
var hasEffect = this.effectUploaded ? 1 : 0;
|
|
1642
|
-
|
|
1910
|
+
var effectWidth = effectImage && (effectImage.naturalWidth || effectImage.width || 0);
|
|
1911
|
+
if (!this.effectUploaded && effectImage && effectWidth > 0) {
|
|
1643
1912
|
gl.activeTexture(gl.TEXTURE1);
|
|
1644
1913
|
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
1645
1914
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
@@ -1671,7 +1940,10 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1671
1940
|
}, {
|
|
1672
1941
|
key: "dispose",
|
|
1673
1942
|
value: function dispose() {
|
|
1943
|
+
this.disposed = true;
|
|
1674
1944
|
var gl = this.gl;
|
|
1945
|
+
this.canvas.removeEventListener('webglcontextlost', this.onContextLost, false);
|
|
1946
|
+
this.canvas.removeEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
1675
1947
|
gl.deleteBuffer(this.buffer);
|
|
1676
1948
|
gl.deleteTexture(this.motionTexture);
|
|
1677
1949
|
gl.deleteTexture(this.effectTexture);
|
|
@@ -1682,8 +1954,9 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1682
1954
|
}]);
|
|
1683
1955
|
}();
|
|
1684
1956
|
function createProgressFlowRenderer(canvas, preset) {
|
|
1957
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1685
1958
|
try {
|
|
1686
|
-
return new ProgressFlowRenderer(canvas, preset);
|
|
1959
|
+
return new ProgressFlowRenderer(canvas, preset, options);
|
|
1687
1960
|
} catch (error) {
|
|
1688
1961
|
console.warn('[画境观屿] 进度流体 WebGL2 不可用,使用 Canvas 2D 降级。', error);
|
|
1689
1962
|
return null;
|
|
@@ -1743,50 +2016,49 @@ function createAtlas(id) {
|
|
|
1743
2016
|
context.fillRect(20, 0, 44, FRAME_HEIGHT);
|
|
1744
2017
|
context.restore();
|
|
1745
2018
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
2019
|
+
|
|
2020
|
+
// A canvas is a valid TexImageSource. Keeping it directly avoids a PNG
|
|
2021
|
+
// encode -> base64 allocation -> Image decode round trip at startup.
|
|
2022
|
+
return {
|
|
2023
|
+
image: canvas,
|
|
2024
|
+
ready: true
|
|
1751
2025
|
};
|
|
1752
|
-
image.addEventListener('load', function () {
|
|
1753
|
-
state.ready = true;
|
|
1754
|
-
}, {
|
|
1755
|
-
once: true
|
|
1756
|
-
});
|
|
1757
|
-
image.addEventListener('error', function () {
|
|
1758
|
-
state.ready = false;
|
|
1759
|
-
}, {
|
|
1760
|
-
once: true
|
|
1761
|
-
});
|
|
1762
|
-
image.src = canvas.toDataURL('image/png');
|
|
1763
|
-
return state;
|
|
1764
2026
|
}
|
|
1765
2027
|
function getProgressReferenceAtlas(id) {
|
|
1766
2028
|
if (!CACHE[id]) CACHE[id] = createAtlas(id);
|
|
1767
2029
|
return CACHE[id];
|
|
1768
2030
|
}
|
|
1769
2031
|
|
|
1770
|
-
/**
|
|
1771
|
-
* Attach a WebGL2 fluid overlay to a progress capsule root.
|
|
1772
|
-
*
|
|
1773
|
-
* @param {object} params
|
|
1774
|
-
* @param {HTMLElement} params.root progress capsule root element
|
|
1775
|
-
* @param {HTMLCanvasElement} params.canvas 2D fallback canvas (kept beneath)
|
|
1776
|
-
* @param {object} params.preset progress preset
|
|
1777
|
-
* @param {() => number} params.getProgress reads the current progress value
|
|
1778
|
-
* @returns {{ update(flowTime: number): void, dispose(): void } | null}
|
|
2032
|
+
/**
|
|
2033
|
+
* Attach a WebGL2 fluid overlay to a progress capsule root.
|
|
2034
|
+
*
|
|
2035
|
+
* @param {object} params
|
|
2036
|
+
* @param {HTMLElement} params.root progress capsule root element
|
|
2037
|
+
* @param {HTMLCanvasElement} params.canvas 2D fallback canvas (kept beneath)
|
|
2038
|
+
* @param {object} params.preset progress preset
|
|
2039
|
+
* @param {() => number} params.getProgress reads the current progress value
|
|
2040
|
+
* @returns {{ update(flowTime: number): void, setDprCap(cap: number): void, dispose(): void } | null}
|
|
1779
2041
|
*/
|
|
1780
2042
|
function attachProgressFlowOverlay(_ref) {
|
|
1781
2043
|
var root = _ref.root,
|
|
1782
2044
|
canvas = _ref.canvas,
|
|
1783
2045
|
preset = _ref.preset,
|
|
1784
|
-
getProgress = _ref.getProgress
|
|
2046
|
+
getProgress = _ref.getProgress,
|
|
2047
|
+
_ref$dprCap = _ref.dprCap,
|
|
2048
|
+
dprCap = _ref$dprCap === void 0 ? 2 : _ref$dprCap,
|
|
2049
|
+
_ref$powerPreference = _ref.powerPreference,
|
|
2050
|
+
powerPreference = _ref$powerPreference === void 0 ? 'high-performance' : _ref$powerPreference,
|
|
2051
|
+
onContextLost = _ref.onContextLost,
|
|
2052
|
+
onContextRestored = _ref.onContextRestored;
|
|
1785
2053
|
var overlay = document.createElement('canvas');
|
|
1786
2054
|
overlay.className = 'hj-progress-canvas hj-progress-overlay';
|
|
1787
2055
|
overlay.setAttribute('aria-hidden', 'true');
|
|
1788
2056
|
canvas.insertAdjacentElement('afterend', overlay);
|
|
1789
|
-
var renderer = createProgressFlowRenderer(overlay, preset
|
|
2057
|
+
var renderer = createProgressFlowRenderer(overlay, preset, {
|
|
2058
|
+
powerPreference: powerPreference,
|
|
2059
|
+
onContextLost: onContextLost,
|
|
2060
|
+
onContextRestored: onContextRestored
|
|
2061
|
+
});
|
|
1790
2062
|
if (!renderer) {
|
|
1791
2063
|
overlay.remove();
|
|
1792
2064
|
return null;
|
|
@@ -1797,7 +2069,7 @@ function attachProgressFlowOverlay(_ref) {
|
|
|
1797
2069
|
var bounds = root.getBoundingClientRect();
|
|
1798
2070
|
var width = Math.max(1, bounds.width);
|
|
1799
2071
|
var height = Math.max(1, bounds.height);
|
|
1800
|
-
var dpr = Math.min(window.devicePixelRatio || 1,
|
|
2072
|
+
var dpr = Math.min(window.devicePixelRatio || 1, dprCap);
|
|
1801
2073
|
overlay.style.width = "".concat(width, "px");
|
|
1802
2074
|
overlay.style.height = "".concat(height, "px");
|
|
1803
2075
|
renderer.resize(width, height, dpr);
|
|
@@ -1821,6 +2093,10 @@ function attachProgressFlowOverlay(_ref) {
|
|
|
1821
2093
|
setColors: function setColors(colors) {
|
|
1822
2094
|
renderer.setColors(colors);
|
|
1823
2095
|
},
|
|
2096
|
+
setDprCap: function setDprCap(cap) {
|
|
2097
|
+
dprCap = cap;
|
|
2098
|
+
resize();
|
|
2099
|
+
},
|
|
1824
2100
|
dispose: function dispose() {
|
|
1825
2101
|
if (resizeObserver) resizeObserver.disconnect();
|
|
1826
2102
|
if (onWindowResize) window.removeEventListener('resize', onWindowResize);
|
|
@@ -1831,6 +2107,47 @@ function attachProgressFlowOverlay(_ref) {
|
|
|
1831
2107
|
};
|
|
1832
2108
|
}
|
|
1833
2109
|
|
|
2110
|
+
function normalizeRange(min, max) {
|
|
2111
|
+
var fallbackMin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
2112
|
+
var fallbackMax = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 100;
|
|
2113
|
+
var nextMin = toFiniteNumber(min);
|
|
2114
|
+
var nextMax = toFiniteNumber(max);
|
|
2115
|
+
if (nextMin === null) nextMin = fallbackMin;
|
|
2116
|
+
if (nextMax === null) nextMax = fallbackMax;
|
|
2117
|
+
if (nextMin > nextMax) {
|
|
2118
|
+
var swap = nextMin;
|
|
2119
|
+
nextMin = nextMax;
|
|
2120
|
+
nextMax = swap;
|
|
2121
|
+
}
|
|
2122
|
+
return [nextMin, nextMax];
|
|
2123
|
+
}
|
|
2124
|
+
function clampProgressValue(value, min, max) {
|
|
2125
|
+
var number = toFiniteNumber(value);
|
|
2126
|
+
if (number === null) return null;
|
|
2127
|
+
return Math.min(Math.max(number, min), max);
|
|
2128
|
+
}
|
|
2129
|
+
function normalizeProgressStep(step) {
|
|
2130
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'any';
|
|
2131
|
+
if (step === 'any' || step == null) return 'any';
|
|
2132
|
+
var increment = toFiniteNumber(step);
|
|
2133
|
+
return increment !== null && increment > 0 ? increment : fallback;
|
|
2134
|
+
}
|
|
2135
|
+
function snapProgressValue(value, min, max) {
|
|
2136
|
+
var step = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'any';
|
|
2137
|
+
var clamped = clampProgressValue(value, min, max);
|
|
2138
|
+
if (clamped === null) return null;
|
|
2139
|
+
if (step === 'any' || step == null) return clamped;
|
|
2140
|
+
var increment = normalizeProgressStep(step);
|
|
2141
|
+
if (increment === 'any') return clamped;
|
|
2142
|
+
var snapped = min + Math.round((clamped - min) / increment) * increment;
|
|
2143
|
+
return Math.min(Math.max(Number(snapped.toFixed(12)), min), max);
|
|
2144
|
+
}
|
|
2145
|
+
function progressRatio(value, min, max) {
|
|
2146
|
+
var range = max - min;
|
|
2147
|
+
if (!Number.isFinite(range) || range <= 0) return 0;
|
|
2148
|
+
return Math.min(Math.max((value - min) / range, 0), 1);
|
|
2149
|
+
}
|
|
2150
|
+
|
|
1834
2151
|
var clamp = function clamp(value, min, max) {
|
|
1835
2152
|
return Math.min(Math.max(value, min), max);
|
|
1836
2153
|
};
|
|
@@ -1857,9 +2174,6 @@ function interpolate(template, values) {
|
|
|
1857
2174
|
return values[key] !== undefined ? values[key] : '';
|
|
1858
2175
|
});
|
|
1859
2176
|
}
|
|
1860
|
-
function prefersReducedMotion$1() {
|
|
1861
|
-
return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
1862
|
-
}
|
|
1863
2177
|
var FLOW_PROFILES = {
|
|
1864
2178
|
'model-training': {
|
|
1865
2179
|
cycles: [0.98, 3.05, 5.45],
|
|
@@ -1920,8 +2234,6 @@ var FLOW_PROFILES = {
|
|
|
1920
2234
|
var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
1921
2235
|
function ProgressCapsuleController(_ref) {
|
|
1922
2236
|
var _options$valueSuffix,
|
|
1923
|
-
_options$min,
|
|
1924
|
-
_options$max,
|
|
1925
2237
|
_options$value,
|
|
1926
2238
|
_this = this;
|
|
1927
2239
|
var root = _ref.root,
|
|
@@ -1943,11 +2255,18 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1943
2255
|
this.dirty = dirty;
|
|
1944
2256
|
this.valueSuffix = (_options$valueSuffix = options.valueSuffix) !== null && _options$valueSuffix !== void 0 ? _options$valueSuffix : copy.valueSuffix;
|
|
1945
2257
|
this.profile = preset.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
this.
|
|
2258
|
+
var _normalizeRange = normalizeRange(options.min, options.max);
|
|
2259
|
+
var _normalizeRange2 = _slicedToArray(_normalizeRange, 2);
|
|
2260
|
+
this.min = _normalizeRange2[0];
|
|
2261
|
+
this.max = _normalizeRange2[1];
|
|
2262
|
+
this.step = normalizeProgressStep(options.step);
|
|
2263
|
+
this.precision = Number.isInteger(Number(options.precision)) ? clamp(Number(options.precision), 0, 20) : 0;
|
|
2264
|
+
this.formatValue = typeof options.formatValue === 'function' ? options.formatValue : null;
|
|
2265
|
+
this.direction = options.direction === 'rtl' ? 'rtl' : 'ltr';
|
|
2266
|
+
this.dprCap = effectiveDprCap(options.quality, options.renderScale);
|
|
1949
2267
|
this.ctx = canvas.getContext('2d');
|
|
1950
|
-
this.value =
|
|
2268
|
+
this.value = snapProgressValue((_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : preset.initialProgress, this.min, this.max, this.step);
|
|
2269
|
+
if (this.value === null) this.value = clamp(preset.initialProgress, this.min, this.max);
|
|
1951
2270
|
this.dragging = false;
|
|
1952
2271
|
this.webglActive = false;
|
|
1953
2272
|
this.flowTime = stringSeed(preset.id) * 31;
|
|
@@ -1957,10 +2276,12 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1957
2276
|
this.width = 0;
|
|
1958
2277
|
this.height = 0;
|
|
1959
2278
|
this.handlers = {};
|
|
1960
|
-
this.
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2279
|
+
this.onResize = function () {
|
|
2280
|
+
_this.resizeCanvas();
|
|
2281
|
+
if (typeof _this.options.onResize === 'function') _this.options.onResize();
|
|
2282
|
+
};
|
|
2283
|
+
this.resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(this.onResize) : null;
|
|
2284
|
+
if (this.resizeObserver) this.resizeObserver.observe(this.root);else window.addEventListener('resize', this.onResize);
|
|
1964
2285
|
this.suppressEvents = true;
|
|
1965
2286
|
this.setProgress(this.value, 'init');
|
|
1966
2287
|
this.suppressEvents = false;
|
|
@@ -1973,16 +2294,37 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1973
2294
|
this.randomState = Math.imul(this.randomState, 1664525) + 1013904223 >>> 0;
|
|
1974
2295
|
return this.randomState / 4294967296;
|
|
1975
2296
|
}
|
|
2297
|
+
}, {
|
|
2298
|
+
key: "displayText",
|
|
2299
|
+
value: function displayText() {
|
|
2300
|
+
if (this.formatValue) {
|
|
2301
|
+
return String(this.formatValue(this.value, {
|
|
2302
|
+
min: this.min,
|
|
2303
|
+
max: this.max,
|
|
2304
|
+
suffix: this.valueSuffix
|
|
2305
|
+
}));
|
|
2306
|
+
}
|
|
2307
|
+
var number = this.precision > 0 ? this.value.toFixed(this.precision) : String(Math.round(this.value));
|
|
2308
|
+
return "".concat(number).concat(this.valueSuffix);
|
|
2309
|
+
}
|
|
2310
|
+
}, {
|
|
2311
|
+
key: "syncValueDom",
|
|
2312
|
+
value: function syncValueDom() {
|
|
2313
|
+
var text = this.displayText();
|
|
2314
|
+
this.root.style.setProperty('--progress', this.value.toFixed(2));
|
|
2315
|
+
this.root.style.setProperty('--progress-ratio', progressRatio(this.value, this.min, this.max).toFixed(4));
|
|
2316
|
+
this.root.setAttribute('aria-valuenow', String(this.value));
|
|
2317
|
+
this.root.setAttribute('aria-valuetext', text);
|
|
2318
|
+
if (this.valueElement) this.valueElement.textContent = text;
|
|
2319
|
+
}
|
|
1976
2320
|
}, {
|
|
1977
2321
|
key: "setProgress",
|
|
1978
2322
|
value: function setProgress(nextValue) {
|
|
1979
2323
|
var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'auto';
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
this.
|
|
1983
|
-
this.
|
|
1984
|
-
this.root.setAttribute('aria-valuetext', "".concat(rounded).concat(this.valueSuffix));
|
|
1985
|
-
if (this.valueElement) this.valueElement.textContent = "".concat(rounded).concat(this.valueSuffix);
|
|
2324
|
+
var next = snapProgressValue(nextValue, this.min, this.max, this.step);
|
|
2325
|
+
if (next === null) return false;
|
|
2326
|
+
this.value = next;
|
|
2327
|
+
this.syncValueDom();
|
|
1986
2328
|
if (!this.suppressEvents) {
|
|
1987
2329
|
if (this.dirty) this.dirty.value = true;
|
|
1988
2330
|
this.emitter.emit('change', {
|
|
@@ -1990,19 +2332,58 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1990
2332
|
source: source
|
|
1991
2333
|
});
|
|
1992
2334
|
}
|
|
2335
|
+
return true;
|
|
1993
2336
|
}
|
|
1994
2337
|
}, {
|
|
1995
2338
|
key: "setValueSuffix",
|
|
1996
2339
|
value: function setValueSuffix(suffix) {
|
|
2340
|
+
if (this.dirty) this.dirty.valueSuffix = true;
|
|
1997
2341
|
this.valueSuffix = String(suffix == null ? '' : suffix);
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2342
|
+
this.syncValueDom();
|
|
2343
|
+
return this;
|
|
2344
|
+
}
|
|
2345
|
+
}, {
|
|
2346
|
+
key: "setStep",
|
|
2347
|
+
value: function setStep(step) {
|
|
2348
|
+
var nextStep = normalizeProgressStep(step, this.step);
|
|
2349
|
+
if (nextStep === this.step) return this;
|
|
2350
|
+
if (this.dirty) this.dirty.step = true;
|
|
2351
|
+
this.step = nextStep;
|
|
2352
|
+
var next = snapProgressValue(this.value, this.min, this.max, this.step);
|
|
2353
|
+
if (next !== null && next !== this.value) this.setProgress(next, 'prop');
|
|
2354
|
+
return this;
|
|
2355
|
+
}
|
|
2356
|
+
}, {
|
|
2357
|
+
key: "setPrecision",
|
|
2358
|
+
value: function setPrecision(precision) {
|
|
2359
|
+
var value = Number(precision);
|
|
2360
|
+
if (!Number.isInteger(value) || value < 0 || value > 20) return this;
|
|
2361
|
+
if (this.dirty) this.dirty.precision = true;
|
|
2362
|
+
this.precision = value;
|
|
2363
|
+
this.syncValueDom();
|
|
2364
|
+
return this;
|
|
2365
|
+
}
|
|
2366
|
+
}, {
|
|
2367
|
+
key: "setFormatValue",
|
|
2368
|
+
value: function setFormatValue(formatter) {
|
|
2369
|
+
if (formatter != null && typeof formatter !== 'function') return this;
|
|
2370
|
+
if (this.dirty) this.dirty.formatValue = true;
|
|
2371
|
+
this.formatValue = formatter || null;
|
|
2372
|
+
this.syncValueDom();
|
|
2373
|
+
return this;
|
|
2374
|
+
}
|
|
2375
|
+
}, {
|
|
2376
|
+
key: "setDirection",
|
|
2377
|
+
value: function setDirection(direction) {
|
|
2378
|
+
if (this.dirty) this.dirty.direction = true;
|
|
2379
|
+
this.direction = direction === 'rtl' ? 'rtl' : 'ltr';
|
|
2380
|
+
this.root.dataset.direction = this.direction;
|
|
2001
2381
|
return this;
|
|
2002
2382
|
}
|
|
2003
2383
|
}, {
|
|
2004
2384
|
key: "setShowValue",
|
|
2005
2385
|
value: function setShowValue(show) {
|
|
2386
|
+
if (this.dirty) this.dirty.showValue = true;
|
|
2006
2387
|
if (this.valueElement) this.valueElement.hidden = show === false;
|
|
2007
2388
|
return this;
|
|
2008
2389
|
}
|
|
@@ -2167,15 +2548,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2167
2548
|
}, {
|
|
2168
2549
|
key: "setRange",
|
|
2169
2550
|
value: function setRange(min, max) {
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
this.min
|
|
2176
|
-
this.
|
|
2177
|
-
|
|
2178
|
-
if (clamped !== this.value) this.setProgress(clamped, 'prop');
|
|
2551
|
+
var nextRange = normalizeRange(min, max, this.min, this.max);
|
|
2552
|
+
this.min = nextRange[0];
|
|
2553
|
+
this.max = nextRange[1];
|
|
2554
|
+
this.root.setAttribute('aria-valuemin', String(this.min));
|
|
2555
|
+
this.root.setAttribute('aria-valuemax', String(this.max));
|
|
2556
|
+
var next = snapProgressValue(this.value, this.min, this.max, this.step);
|
|
2557
|
+
if (next !== this.value) this.setProgress(next, 'prop');else this.syncValueDom();
|
|
2558
|
+
return this;
|
|
2179
2559
|
}
|
|
2180
2560
|
}, {
|
|
2181
2561
|
key: "drawReferenceFlow",
|
|
@@ -2300,14 +2680,45 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2300
2680
|
value: function updateFromPointer(event) {
|
|
2301
2681
|
var bounds = this.root.getBoundingClientRect();
|
|
2302
2682
|
var ratio = bounds.width > 0 ? (event.clientX - bounds.left) / bounds.width : 0;
|
|
2683
|
+
if (this.direction === 'rtl') ratio = 1 - ratio;
|
|
2303
2684
|
this.setProgress(this.min + ratio * (this.max - this.min), 'drag');
|
|
2304
2685
|
}
|
|
2686
|
+
}, {
|
|
2687
|
+
key: "onKeyDown",
|
|
2688
|
+
value: function onKeyDown(event) {
|
|
2689
|
+
var range = this.max - this.min;
|
|
2690
|
+
var configuredStep = Number(this.step);
|
|
2691
|
+
var step = Number.isFinite(configuredStep) && configuredStep > 0 ? configuredStep : Math.max(range / 100, 1e-7);
|
|
2692
|
+
var direction = this.direction === 'rtl' ? -1 : 1;
|
|
2693
|
+
var aliases = {
|
|
2694
|
+
Left: 'ArrowLeft',
|
|
2695
|
+
Right: 'ArrowRight',
|
|
2696
|
+
Up: 'ArrowUp',
|
|
2697
|
+
Down: 'ArrowDown'
|
|
2698
|
+
};
|
|
2699
|
+
var keyCodes = {
|
|
2700
|
+
35: 'End',
|
|
2701
|
+
36: 'Home',
|
|
2702
|
+
33: 'PageUp',
|
|
2703
|
+
34: 'PageDown',
|
|
2704
|
+
37: 'ArrowLeft',
|
|
2705
|
+
38: 'ArrowUp',
|
|
2706
|
+
39: 'ArrowRight',
|
|
2707
|
+
40: 'ArrowDown'
|
|
2708
|
+
};
|
|
2709
|
+
var key = aliases[event.key] || event.key || keyCodes[event.keyCode];
|
|
2710
|
+
var next = null;
|
|
2711
|
+
if (key === 'ArrowRight') next = this.value + step * direction;else if (key === 'ArrowLeft') next = this.value - step * direction;else if (key === 'ArrowUp') next = this.value + step;else if (key === 'ArrowDown') next = this.value - step;else if (key === 'PageUp') next = this.value + step * 10;else if (key === 'PageDown') next = this.value - step * 10;else if (key === 'Home') next = this.min;else if (key === 'End') next = this.max;
|
|
2712
|
+
if (next === null) return;
|
|
2713
|
+
event.preventDefault();
|
|
2714
|
+
this.setProgress(next, 'keyboard');
|
|
2715
|
+
}
|
|
2305
2716
|
}, {
|
|
2306
2717
|
key: "beginDrag",
|
|
2307
2718
|
value: function beginDrag(event) {
|
|
2308
2719
|
if (event.button !== undefined && event.button !== 0) return;
|
|
2309
2720
|
event.preventDefault();
|
|
2310
|
-
// preventDefault
|
|
2721
|
+
// preventDefault 会吞掉点击聚焦,主动聚焦让根节点获得无障碍焦点。
|
|
2311
2722
|
try {
|
|
2312
2723
|
this.root.focus({
|
|
2313
2724
|
preventScroll: true
|
|
@@ -2389,6 +2800,12 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2389
2800
|
this.root.addEventListener('pointerup', this.handlers.pointerup);
|
|
2390
2801
|
this.root.addEventListener('pointercancel', this.handlers.pointercancel);
|
|
2391
2802
|
}
|
|
2803
|
+
if (this.options.keyboard !== false) {
|
|
2804
|
+
this.handlers.keydown = function (event) {
|
|
2805
|
+
return _this3.onKeyDown(event);
|
|
2806
|
+
};
|
|
2807
|
+
this.root.addEventListener('keydown', this.handlers.keydown);
|
|
2808
|
+
}
|
|
2392
2809
|
}
|
|
2393
2810
|
}, {
|
|
2394
2811
|
key: "update",
|
|
@@ -2407,20 +2824,19 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2407
2824
|
key: "randomize",
|
|
2408
2825
|
value: function randomize() {
|
|
2409
2826
|
this.flowTime = this.random() * 40;
|
|
2827
|
+
return this.flowTime;
|
|
2410
2828
|
}
|
|
2411
2829
|
}, {
|
|
2412
2830
|
key: "setColors",
|
|
2413
2831
|
value: function setColors(colors) {
|
|
2414
2832
|
if (!Array.isArray(colors) || colors.length !== 4) return;
|
|
2415
|
-
this.preset =
|
|
2416
|
-
colors: colors
|
|
2417
|
-
});
|
|
2833
|
+
this.preset.colors = _toConsumableArray(colors);
|
|
2418
2834
|
}
|
|
2419
2835
|
}, {
|
|
2420
2836
|
key: "dispose",
|
|
2421
2837
|
value: function dispose() {
|
|
2422
2838
|
if (this._dragRaf) cancelAnimationFrame(this._dragRaf);
|
|
2423
|
-
if (this.resizeObserver) this.resizeObserver.disconnect();else window.removeEventListener('resize', this.
|
|
2839
|
+
if (this.resizeObserver) this.resizeObserver.disconnect();else window.removeEventListener('resize', this.onResize);
|
|
2424
2840
|
for (var _i = 0, _Object$keys = Object.keys(this.handlers); _i < _Object$keys.length; _i++) {
|
|
2425
2841
|
var name = _Object$keys[_i];
|
|
2426
2842
|
var handler = this.handlers[name];
|
|
@@ -2431,15 +2847,16 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
2431
2847
|
}]);
|
|
2432
2848
|
}();
|
|
2433
2849
|
|
|
2434
|
-
/**
|
|
2850
|
+
/**
|
|
2435
2851
|
* Mount a fluid progress capsule into `container`.
|
|
2436
2852
|
*
|
|
2437
|
-
* Options: preset (
|
|
2438
|
-
* draggable,
|
|
2853
|
+
* Options: preset (literary name), width, height, value/modelValue, min, max,
|
|
2854
|
+
* step, draggable, keyboard, direction, precision/formatValue, colors,
|
|
2855
|
+
* edgeStyle, textRatio (0-100, text region
|
|
2439
2856
|
* width in percent), text (HTML string or DOM nodes for the text slot),
|
|
2440
2857
|
* colorContent (HTML string or DOM nodes for the color slot),
|
|
2441
|
-
* showValue (show/hide the right-side percentage), quality,
|
|
2442
|
-
* respectReducedMotion, cssVars.
|
|
2858
|
+
* showValue (show/hide the right-side percentage), quality, renderScale,
|
|
2859
|
+
* powerPreference, fps, paused/static, respectReducedMotion, cssVars.
|
|
2443
2860
|
*/
|
|
2444
2861
|
function createProgressCapsule(container) {
|
|
2445
2862
|
var _options$preset, _merged$min, _merged$max;
|
|
@@ -2449,14 +2866,20 @@ function createProgressCapsule(container) {
|
|
|
2449
2866
|
}
|
|
2450
2867
|
var preset = _objectSpread2({}, getPreset('progress', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '星火'));
|
|
2451
2868
|
var merged = normalizeOptions(DEFAULTS.progress, preset, options);
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
var normalizedColors = merged.colors.map(normalizeColor);
|
|
2458
|
-
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
2459
|
-
|
|
2869
|
+
var _normalizeRange3 = normalizeRange(merged.min, merged.max);
|
|
2870
|
+
var _normalizeRange4 = _slicedToArray(_normalizeRange3, 2);
|
|
2871
|
+
merged.min = _normalizeRange4[0];
|
|
2872
|
+
merged.max = _normalizeRange4[1];
|
|
2873
|
+
if (merged.modelValue !== undefined) merged.value = merged.modelValue;
|
|
2874
|
+
var normalizedColors = Array.isArray(merged.colors) ? merged.colors.map(normalizeColor) : [];
|
|
2875
|
+
if (normalizedColors.length === 4 && normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
2876
|
+
var initialEdgeStyle = merged.edgeStyle === 'tide' || merged.edgeStyle === 'flow' ? merged.edgeStyle : preset.edgeStyle;
|
|
2877
|
+
preset.edgeStyle = initialEdgeStyle;
|
|
2878
|
+
merged.edgeStyle = initialEdgeStyle;
|
|
2879
|
+
merged.colors = _toConsumableArray(preset.colors);
|
|
2880
|
+
var optionColors = Array.isArray(options.colors) ? options.colors.map(normalizeColor) : [];
|
|
2881
|
+
var colorOverride = optionColors.length === 4 && optionColors.every(Boolean) ? _toConsumableArray(optionColors) : null;
|
|
2882
|
+
var edgeStyleOverride = options.edgeStyle === 'flow' || options.edgeStyle === 'tide' ? merged.edgeStyle : null;
|
|
2460
2883
|
var copy = COPY;
|
|
2461
2884
|
var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
|
|
2462
2885
|
// Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
|
|
@@ -2465,18 +2888,31 @@ function createProgressCapsule(container) {
|
|
|
2465
2888
|
var readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
|
|
2466
2889
|
var locked = disabled || readonly;
|
|
2467
2890
|
var effectiveDraggable = locked ? false : merged.draggable !== false;
|
|
2891
|
+
var effectiveKeyboard = locked ? false : merged.keyboard !== false;
|
|
2468
2892
|
var dirty = {
|
|
2469
2893
|
preset: false,
|
|
2470
2894
|
colors: false,
|
|
2471
2895
|
textRatio: false,
|
|
2472
2896
|
cssVars: false,
|
|
2473
2897
|
edgeStyle: false,
|
|
2474
|
-
value: false
|
|
2898
|
+
value: false,
|
|
2899
|
+
step: false,
|
|
2900
|
+
precision: false,
|
|
2901
|
+
formatValue: false,
|
|
2902
|
+
direction: false,
|
|
2903
|
+
showValue: false,
|
|
2904
|
+
valueSuffix: false,
|
|
2905
|
+
quality: false,
|
|
2906
|
+
renderScale: false,
|
|
2907
|
+
paused: false,
|
|
2908
|
+
static: false,
|
|
2909
|
+
fps: false
|
|
2475
2910
|
};
|
|
2476
2911
|
var root = document.createElement('div');
|
|
2477
2912
|
root.className = 'hj-capsule-root hj-progress-root';
|
|
2478
2913
|
root.setAttribute('role', 'slider');
|
|
2479
2914
|
root.setAttribute('data-draggable', String(effectiveDraggable));
|
|
2915
|
+
root.dataset.direction = merged.direction === 'rtl' ? 'rtl' : 'ltr';
|
|
2480
2916
|
if (disabled) {
|
|
2481
2917
|
root.setAttribute('aria-disabled', 'true');
|
|
2482
2918
|
root.classList.add('is-disabled');
|
|
@@ -2485,7 +2921,8 @@ function createProgressCapsule(container) {
|
|
|
2485
2921
|
root.setAttribute('aria-readonly', 'true');
|
|
2486
2922
|
root.classList.add('is-readonly');
|
|
2487
2923
|
}
|
|
2488
|
-
|
|
2924
|
+
root.setAttribute('tabindex', locked ? '-1' : effectiveKeyboard ? '0' : '-1');
|
|
2925
|
+
root.setAttribute('aria-orientation', 'horizontal');
|
|
2489
2926
|
root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
|
|
2490
2927
|
root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
|
|
2491
2928
|
root.setAttribute('aria-valuenow', String(preset.initialProgress));
|
|
@@ -2540,8 +2977,22 @@ function createProgressCapsule(container) {
|
|
|
2540
2977
|
root.appendChild(valueElement);
|
|
2541
2978
|
container.appendChild(root);
|
|
2542
2979
|
var emitter = createEmitter();
|
|
2543
|
-
var
|
|
2980
|
+
var manuallyPaused = merged.paused === true;
|
|
2981
|
+
var reducedPaused = false;
|
|
2982
|
+
var staticMode = merged.static === true;
|
|
2983
|
+
var contextLost = false;
|
|
2544
2984
|
var disposed = false;
|
|
2985
|
+
var renderOnce = function renderOnce() {};
|
|
2986
|
+
var onContextLost = function onContextLost() {
|
|
2987
|
+
contextLost = true;
|
|
2988
|
+
emitter.emit('contextlost', {});
|
|
2989
|
+
};
|
|
2990
|
+
var onContextRestored = function onContextRestored() {
|
|
2991
|
+
contextLost = false;
|
|
2992
|
+
emitter.emit('contextrestored', {});
|
|
2993
|
+
renderOnce();
|
|
2994
|
+
wakeScheduler();
|
|
2995
|
+
};
|
|
2545
2996
|
var applySize = function applySize() {
|
|
2546
2997
|
root.style.width = parseSize(merged.width);
|
|
2547
2998
|
root.style.height = parseSize(merged.height);
|
|
@@ -2562,7 +3013,11 @@ function createProgressCapsule(container) {
|
|
|
2562
3013
|
preset: preset,
|
|
2563
3014
|
emitter: emitter,
|
|
2564
3015
|
options: _objectSpread2(_objectSpread2({}, merged), {}, {
|
|
2565
|
-
draggable: effectiveDraggable
|
|
3016
|
+
draggable: effectiveDraggable,
|
|
3017
|
+
keyboard: effectiveKeyboard,
|
|
3018
|
+
onResize: function onResize() {
|
|
3019
|
+
if (manuallyPaused || reducedPaused || staticMode) renderOnce();
|
|
3020
|
+
}
|
|
2566
3021
|
}),
|
|
2567
3022
|
copy: copy,
|
|
2568
3023
|
dirty: dirty
|
|
@@ -2574,8 +3029,12 @@ function createProgressCapsule(container) {
|
|
|
2574
3029
|
canvas: canvas,
|
|
2575
3030
|
preset: preset,
|
|
2576
3031
|
getProgress: function getProgress() {
|
|
2577
|
-
return controller.value;
|
|
2578
|
-
}
|
|
3032
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
3033
|
+
},
|
|
3034
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
3035
|
+
powerPreference: merged.powerPreference,
|
|
3036
|
+
onContextLost: onContextLost,
|
|
3037
|
+
onContextRestored: onContextRestored
|
|
2579
3038
|
});
|
|
2580
3039
|
}
|
|
2581
3040
|
if (overlay) controller.webglActive = true;else if (merged.renderer !== 'canvas2d') {
|
|
@@ -2586,17 +3045,34 @@ function createProgressCapsule(container) {
|
|
|
2586
3045
|
});
|
|
2587
3046
|
});
|
|
2588
3047
|
}
|
|
2589
|
-
var visibility = createVisibilityGuard(root);
|
|
3048
|
+
var visibility = createVisibilityGuard(root, wakeScheduler);
|
|
3049
|
+
var motionPreference = createReducedMotionPreference(merged.respectReducedMotion, function (matches) {
|
|
3050
|
+
reducedPaused = matches;
|
|
3051
|
+
if (matches) renderOnce();else wakeScheduler();
|
|
3052
|
+
});
|
|
3053
|
+
reducedPaused = motionPreference.matches();
|
|
3054
|
+
var isMotionPaused = function isMotionPaused() {
|
|
3055
|
+
return manuallyPaused || reducedPaused || staticMode || contextLost;
|
|
3056
|
+
};
|
|
2590
3057
|
var flowTime = 0;
|
|
3058
|
+
var frameGate = createFrameGate(merged.fps);
|
|
3059
|
+
renderOnce = function renderOnce() {
|
|
3060
|
+
controller.draw();
|
|
3061
|
+
if (overlay) overlay.update(flowTime);
|
|
3062
|
+
};
|
|
3063
|
+
renderOnce();
|
|
3064
|
+
var offPausedChange = emitter.on('change', function () {
|
|
3065
|
+
if (isMotionPaused()) renderOnce();
|
|
3066
|
+
});
|
|
2591
3067
|
var unsubscribe = subscribeScheduler(function (delta, now) {
|
|
2592
3068
|
flowTime += delta;
|
|
2593
3069
|
controller.update(delta, false);
|
|
2594
|
-
if (
|
|
3070
|
+
if (frameGate.shouldDraw(delta)) {
|
|
2595
3071
|
controller.draw();
|
|
2596
3072
|
if (overlay) overlay.update(flowTime);
|
|
2597
3073
|
}
|
|
2598
3074
|
}, function () {
|
|
2599
|
-
return
|
|
3075
|
+
return isMotionPaused() || !visibility.isVisible();
|
|
2600
3076
|
});
|
|
2601
3077
|
nextTick(function () {
|
|
2602
3078
|
if (disposed) return;
|
|
@@ -2623,32 +3099,41 @@ function createProgressCapsule(container) {
|
|
|
2623
3099
|
},
|
|
2624
3100
|
setRange: function setRange(min, max) {
|
|
2625
3101
|
controller.setRange(min, max);
|
|
3102
|
+
if (isMotionPaused()) renderOnce();
|
|
2626
3103
|
return this;
|
|
2627
3104
|
},
|
|
2628
3105
|
setPreset: function setPreset(ref) {
|
|
2629
3106
|
var next = getPreset('progress', ref);
|
|
2630
3107
|
dirty.preset = true;
|
|
2631
3108
|
Object.assign(preset, next);
|
|
3109
|
+
if (colorOverride) preset.colors = _toConsumableArray(colorOverride);
|
|
3110
|
+
if (edgeStyleOverride) preset.edgeStyle = edgeStyleOverride;
|
|
2632
3111
|
var nextColors = preset.colors.map(normalizeColor);
|
|
2633
3112
|
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
2634
3113
|
controller.preset = preset;
|
|
2635
|
-
controller.profile =
|
|
3114
|
+
controller.profile = preset.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
2636
3115
|
controller.flowTime = stringSeed(next.id) * 31;
|
|
2637
3116
|
controller.seed = stringSeed("".concat(next.id, "-reference")) * Math.PI * 2;
|
|
2638
3117
|
syncDom();
|
|
2639
3118
|
if (overlay) {
|
|
2640
3119
|
overlay.dispose();
|
|
3120
|
+
contextLost = false;
|
|
2641
3121
|
overlay = attachProgressFlowOverlay({
|
|
2642
3122
|
root: root,
|
|
2643
3123
|
canvas: canvas,
|
|
2644
3124
|
preset: preset,
|
|
2645
3125
|
getProgress: function getProgress() {
|
|
2646
|
-
return controller.value;
|
|
2647
|
-
}
|
|
3126
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
3127
|
+
},
|
|
3128
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
3129
|
+
powerPreference: merged.powerPreference,
|
|
3130
|
+
onContextLost: onContextLost,
|
|
3131
|
+
onContextRestored: onContextRestored
|
|
2648
3132
|
});
|
|
2649
3133
|
}
|
|
2650
3134
|
controller.webglActive = Boolean(overlay);
|
|
2651
3135
|
controller.resizeCanvas();
|
|
3136
|
+
if (isMotionPaused()) renderOnce();
|
|
2652
3137
|
emitter.emit('presetchange', {
|
|
2653
3138
|
preset: _objectSpread2({}, preset)
|
|
2654
3139
|
});
|
|
@@ -2658,21 +3143,28 @@ function createProgressCapsule(container) {
|
|
|
2658
3143
|
var value = String(edgeStyle || '').toLowerCase();
|
|
2659
3144
|
if (value !== 'flow' && value !== 'tide') return this;
|
|
2660
3145
|
dirty.edgeStyle = true;
|
|
3146
|
+
edgeStyleOverride = value;
|
|
2661
3147
|
preset.edgeStyle = value;
|
|
2662
3148
|
controller.profile = value === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
2663
3149
|
if (overlay) {
|
|
2664
3150
|
overlay.dispose();
|
|
3151
|
+
contextLost = false;
|
|
2665
3152
|
overlay = attachProgressFlowOverlay({
|
|
2666
3153
|
root: root,
|
|
2667
3154
|
canvas: canvas,
|
|
2668
3155
|
preset: preset,
|
|
2669
3156
|
getProgress: function getProgress() {
|
|
2670
|
-
return controller.value;
|
|
2671
|
-
}
|
|
3157
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
3158
|
+
},
|
|
3159
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
3160
|
+
powerPreference: merged.powerPreference,
|
|
3161
|
+
onContextLost: onContextLost,
|
|
3162
|
+
onContextRestored: onContextRestored
|
|
2672
3163
|
});
|
|
2673
3164
|
}
|
|
2674
3165
|
controller.webglActive = Boolean(overlay);
|
|
2675
3166
|
controller.resizeCanvas();
|
|
3167
|
+
if (isMotionPaused()) renderOnce();
|
|
2676
3168
|
return this;
|
|
2677
3169
|
},
|
|
2678
3170
|
setText: function setText(content) {
|
|
@@ -2710,6 +3202,22 @@ function createProgressCapsule(container) {
|
|
|
2710
3202
|
controller.setValueSuffix(suffix);
|
|
2711
3203
|
return this;
|
|
2712
3204
|
},
|
|
3205
|
+
setStep: function setStep(step) {
|
|
3206
|
+
controller.setStep(step);
|
|
3207
|
+
return this;
|
|
3208
|
+
},
|
|
3209
|
+
setPrecision: function setPrecision(precision) {
|
|
3210
|
+
controller.setPrecision(precision);
|
|
3211
|
+
return this;
|
|
3212
|
+
},
|
|
3213
|
+
setFormatValue: function setFormatValue(formatter) {
|
|
3214
|
+
controller.setFormatValue(formatter);
|
|
3215
|
+
return this;
|
|
3216
|
+
},
|
|
3217
|
+
setDirection: function setDirection(direction) {
|
|
3218
|
+
controller.setDirection(direction);
|
|
3219
|
+
return this;
|
|
3220
|
+
},
|
|
2713
3221
|
setShowValue: function setShowValue(show) {
|
|
2714
3222
|
controller.setShowValue(show);
|
|
2715
3223
|
return this;
|
|
@@ -2720,9 +3228,12 @@ function createProgressCapsule(container) {
|
|
|
2720
3228
|
return !color;
|
|
2721
3229
|
})) return this;
|
|
2722
3230
|
dirty.colors = true;
|
|
3231
|
+
colorOverride = _toConsumableArray(next);
|
|
3232
|
+
preset.colors = _toConsumableArray(next);
|
|
2723
3233
|
controller.setColors(next);
|
|
2724
3234
|
if (overlay) overlay.setColors(next);
|
|
2725
3235
|
controller.resizeCanvas();
|
|
3236
|
+
if (isMotionPaused()) renderOnce();
|
|
2726
3237
|
return this;
|
|
2727
3238
|
},
|
|
2728
3239
|
setSize: function setSize(width, height) {
|
|
@@ -2736,30 +3247,68 @@ function createProgressCapsule(container) {
|
|
|
2736
3247
|
}
|
|
2737
3248
|
applySize();
|
|
2738
3249
|
controller.resizeCanvas();
|
|
3250
|
+
if (isMotionPaused()) renderOnce();
|
|
2739
3251
|
return this;
|
|
2740
3252
|
},
|
|
2741
3253
|
randomize: function randomize() {
|
|
2742
|
-
controller.randomize();
|
|
3254
|
+
flowTime = controller.randomize();
|
|
3255
|
+
if (isMotionPaused()) renderOnce();
|
|
2743
3256
|
return this;
|
|
2744
3257
|
},
|
|
2745
3258
|
pause: function pause() {
|
|
2746
|
-
paused = true;
|
|
3259
|
+
dirty.paused = true;
|
|
3260
|
+
manuallyPaused = true;
|
|
3261
|
+
renderOnce();
|
|
2747
3262
|
return this;
|
|
2748
3263
|
},
|
|
2749
3264
|
resume: function resume() {
|
|
2750
|
-
paused =
|
|
3265
|
+
dirty.paused = true;
|
|
3266
|
+
manuallyPaused = false;
|
|
3267
|
+
wakeScheduler();
|
|
3268
|
+
return this;
|
|
3269
|
+
},
|
|
3270
|
+
setPaused: function setPaused(value) {
|
|
3271
|
+
return value ? this.pause() : this.resume();
|
|
3272
|
+
},
|
|
3273
|
+
setStatic: function setStatic(value) {
|
|
3274
|
+
dirty.static = true;
|
|
3275
|
+
staticMode = value === true;
|
|
3276
|
+
merged.static = staticMode;
|
|
3277
|
+
if (staticMode) renderOnce();else wakeScheduler();
|
|
3278
|
+
return this;
|
|
3279
|
+
},
|
|
3280
|
+
setFps: function setFps(fps) {
|
|
3281
|
+
dirty.fps = true;
|
|
3282
|
+
merged.fps = frameGate.setFps(fps);
|
|
3283
|
+
wakeScheduler();
|
|
2751
3284
|
return this;
|
|
2752
3285
|
},
|
|
2753
3286
|
setQuality: function setQuality(quality) {
|
|
3287
|
+
dirty.quality = true;
|
|
2754
3288
|
merged.quality = quality;
|
|
2755
|
-
controller.dprCap =
|
|
3289
|
+
controller.dprCap = effectiveDprCap(quality, merged.renderScale);
|
|
2756
3290
|
controller.resizeCanvas();
|
|
3291
|
+
if (overlay) overlay.setDprCap(controller.dprCap);
|
|
3292
|
+
if (isMotionPaused()) renderOnce();
|
|
3293
|
+
return this;
|
|
3294
|
+
},
|
|
3295
|
+
setRenderScale: function setRenderScale(renderScale) {
|
|
3296
|
+
var value = Number(renderScale);
|
|
3297
|
+
if (!Number.isFinite(value)) return this;
|
|
3298
|
+
dirty.renderScale = true;
|
|
3299
|
+
merged.renderScale = Math.min(1, Math.max(0.25, value));
|
|
3300
|
+
controller.dprCap = effectiveDprCap(merged.quality, merged.renderScale);
|
|
3301
|
+
controller.resizeCanvas();
|
|
3302
|
+
if (overlay) overlay.setDprCap(controller.dprCap);
|
|
3303
|
+
if (isMotionPaused()) renderOnce();
|
|
2757
3304
|
return this;
|
|
2758
3305
|
},
|
|
2759
3306
|
dispose: function dispose() {
|
|
2760
3307
|
disposed = true;
|
|
2761
3308
|
unsubscribe();
|
|
3309
|
+
offPausedChange();
|
|
2762
3310
|
visibility.dispose();
|
|
3311
|
+
motionPreference.dispose();
|
|
2763
3312
|
if (overlay) overlay.dispose();
|
|
2764
3313
|
controller.dispose();
|
|
2765
3314
|
root.remove();
|
|
@@ -2770,26 +3319,89 @@ function createProgressCapsule(container) {
|
|
|
2770
3319
|
get cssVars() {
|
|
2771
3320
|
return merged.cssVars;
|
|
2772
3321
|
},
|
|
3322
|
+
get min() {
|
|
3323
|
+
return controller.min;
|
|
3324
|
+
},
|
|
3325
|
+
get max() {
|
|
3326
|
+
return controller.max;
|
|
3327
|
+
},
|
|
3328
|
+
get step() {
|
|
3329
|
+
return controller.step;
|
|
3330
|
+
},
|
|
3331
|
+
get precision() {
|
|
3332
|
+
return controller.precision;
|
|
3333
|
+
},
|
|
3334
|
+
get formatValue() {
|
|
3335
|
+
return controller.formatValue;
|
|
3336
|
+
},
|
|
3337
|
+
get direction() {
|
|
3338
|
+
return controller.direction;
|
|
3339
|
+
},
|
|
3340
|
+
get showValue() {
|
|
3341
|
+
return !valueElement.hidden;
|
|
3342
|
+
},
|
|
3343
|
+
get valueSuffix() {
|
|
3344
|
+
return controller.valueSuffix;
|
|
3345
|
+
},
|
|
3346
|
+
get quality() {
|
|
3347
|
+
return merged.quality;
|
|
3348
|
+
},
|
|
3349
|
+
get renderScale() {
|
|
3350
|
+
return merged.renderScale;
|
|
3351
|
+
},
|
|
3352
|
+
get paused() {
|
|
3353
|
+
return manuallyPaused;
|
|
3354
|
+
},
|
|
3355
|
+
get static() {
|
|
3356
|
+
return staticMode;
|
|
3357
|
+
},
|
|
3358
|
+
get fps() {
|
|
3359
|
+
return frameGate.getFps();
|
|
3360
|
+
},
|
|
2773
3361
|
dirty: dirty
|
|
2774
3362
|
};
|
|
2775
3363
|
}
|
|
2776
3364
|
|
|
2777
|
-
|
|
2778
|
-
|
|
3365
|
+
var HOST_STYLES = new WeakMap();
|
|
3366
|
+
function acquireHostStyles(host) {
|
|
3367
|
+
var active = HOST_STYLES.get(host);
|
|
3368
|
+
if (active) {
|
|
3369
|
+
active.count += 1;
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
var state = {
|
|
3373
|
+
count: 1,
|
|
3374
|
+
position: host.style.position,
|
|
3375
|
+
isolation: host.style.isolation
|
|
3376
|
+
};
|
|
3377
|
+
var computed = getComputedStyle(host);
|
|
3378
|
+
if (computed.position === 'static' || computed.position === '') host.style.position = 'relative';
|
|
3379
|
+
host.style.isolation = 'isolate';
|
|
3380
|
+
HOST_STYLES.set(host, state);
|
|
3381
|
+
}
|
|
3382
|
+
function releaseHostStyles(host) {
|
|
3383
|
+
var state = HOST_STYLES.get(host);
|
|
3384
|
+
if (!state) return;
|
|
3385
|
+
state.count -= 1;
|
|
3386
|
+
if (state.count > 0) return;
|
|
3387
|
+
host.style.position = state.position;
|
|
3388
|
+
host.style.isolation = state.isolation;
|
|
3389
|
+
HOST_STYLES.delete(host);
|
|
2779
3390
|
}
|
|
2780
3391
|
|
|
2781
|
-
/**
|
|
2782
|
-
* Mount the cosmic (nebula) material as a background layer inside `host`.
|
|
2783
|
-
*
|
|
2784
|
-
* The layer is absolutely positioned and defaults to `z-index: -1`, so it
|
|
2785
|
-
* paints behind the host's in-flow content: text/buttons/images inside the
|
|
2786
|
-
* host sit on top with zero extra CSS. Host gets `position: relative;
|
|
2787
|
-
* isolation: isolate` automatically so the layer can never escape its box
|
|
2788
|
-
* (or break stacking outside it).
|
|
2789
|
-
*
|
|
2790
|
-
* Options: preset (
|
|
2791
|
-
* renderer,
|
|
2792
|
-
*
|
|
3392
|
+
/**
|
|
3393
|
+
* Mount the cosmic (nebula) material as a background layer inside `host`.
|
|
3394
|
+
*
|
|
3395
|
+
* The layer is absolutely positioned and defaults to `z-index: -1`, so it
|
|
3396
|
+
* paints behind the host's in-flow content: text/buttons/images inside the
|
|
3397
|
+
* host sit on top with zero extra CSS. Host gets `position: relative;
|
|
3398
|
+
* isolation: isolate` automatically so the layer can never escape its box
|
|
3399
|
+
* (or break stacking outside it).
|
|
3400
|
+
*
|
|
3401
|
+
* Options: preset (literary name), colors, seed, speed, quality,
|
|
3402
|
+
* renderer, renderScale, powerPreference, fps, paused/static, mouseColor,
|
|
3403
|
+
* respectReducedMotion, opacity (0-1), fallbackColor (true=preset base
|
|
3404
|
+
* color, a hex string, or false to disable).
|
|
2793
3405
|
*/
|
|
2794
3406
|
function createColorBackground(host) {
|
|
2795
3407
|
var _options$preset;
|
|
@@ -2803,18 +3415,29 @@ function createColorBackground(host) {
|
|
|
2803
3415
|
renderer: DEFAULTS.capsule.renderer,
|
|
2804
3416
|
respectReducedMotion: DEFAULTS.capsule.respectReducedMotion,
|
|
2805
3417
|
mouseColor: true,
|
|
3418
|
+
renderScale: 1,
|
|
3419
|
+
powerPreference: 'high-performance',
|
|
3420
|
+
fps: DEFAULTS.capsule.fps,
|
|
3421
|
+
paused: false,
|
|
3422
|
+
static: false,
|
|
2806
3423
|
opacity: 1,
|
|
2807
3424
|
fallbackColor: true
|
|
2808
3425
|
}, preset, options);
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
preset.
|
|
2812
|
-
|
|
2813
|
-
var
|
|
2814
|
-
if (
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
3426
|
+
merged.opacity = Number.isFinite(Number(merged.opacity)) ? Math.min(1, Math.max(0, Number(merged.opacity))) : 1;
|
|
3427
|
+
var normalizedColors = Array.isArray(merged.colors) ? merged.colors.map(normalizeColor) : [];
|
|
3428
|
+
if (normalizedColors.length === 4 && normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
3429
|
+
var initialSeed = toFiniteNumber(merged.seed);
|
|
3430
|
+
var initialSpeed = toFiniteNumber(merged.speed);
|
|
3431
|
+
if (initialSeed !== null) preset.seed = initialSeed;
|
|
3432
|
+
if (initialSpeed !== null) preset.speed = initialSpeed;
|
|
3433
|
+
merged.colors = _toConsumableArray(preset.colors);
|
|
3434
|
+
merged.seed = preset.seed;
|
|
3435
|
+
merged.speed = preset.speed;
|
|
3436
|
+
var optionColors = Array.isArray(options.colors) ? options.colors.map(normalizeColor) : [];
|
|
3437
|
+
var colorOverride = optionColors.length === 4 && optionColors.every(Boolean) ? _toConsumableArray(optionColors) : null;
|
|
3438
|
+
var seedOverride = options.seed !== undefined ? toFiniteNumber(options.seed) : null;
|
|
3439
|
+
var speedOverride = options.speed !== undefined ? toFiniteNumber(options.speed) : null;
|
|
3440
|
+
acquireHostStyles(host);
|
|
2818
3441
|
var layer = document.createElement('div');
|
|
2819
3442
|
layer.className = 'dlc-color-layer';
|
|
2820
3443
|
var syncLayerVars = function syncLayerVars() {
|
|
@@ -2829,8 +3452,12 @@ function createColorBackground(host) {
|
|
|
2829
3452
|
layer.appendChild(canvas);
|
|
2830
3453
|
host.appendChild(layer);
|
|
2831
3454
|
var emitter = createEmitter();
|
|
2832
|
-
var
|
|
3455
|
+
var manuallyPaused = merged.paused === true;
|
|
3456
|
+
var reducedPaused = false;
|
|
3457
|
+
var staticMode = merged.static === true;
|
|
3458
|
+
var contextLost = false;
|
|
2833
3459
|
var disposed = false;
|
|
3460
|
+
var renderOnce = function renderOnce() {};
|
|
2834
3461
|
var dirty = {
|
|
2835
3462
|
preset: false,
|
|
2836
3463
|
seed: false,
|
|
@@ -2838,19 +3465,37 @@ function createColorBackground(host) {
|
|
|
2838
3465
|
colors: false,
|
|
2839
3466
|
opacity: false,
|
|
2840
3467
|
fallbackColor: false,
|
|
2841
|
-
mouseColor: false
|
|
3468
|
+
mouseColor: false,
|
|
3469
|
+
quality: false,
|
|
3470
|
+
renderScale: false,
|
|
3471
|
+
paused: false,
|
|
3472
|
+
static: false,
|
|
3473
|
+
fps: false
|
|
2842
3474
|
};
|
|
2843
3475
|
var renderer;
|
|
2844
3476
|
var useWebgl = merged.renderer !== 'canvas2d';
|
|
2845
3477
|
if (useWebgl) {
|
|
2846
3478
|
try {
|
|
2847
3479
|
renderer = new CosmicRenderer(canvas, merged, {
|
|
2848
|
-
dprCap:
|
|
3480
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
2849
3481
|
mouseColor: merged.mouseColor !== false,
|
|
2850
|
-
eventTarget: host
|
|
3482
|
+
eventTarget: host,
|
|
3483
|
+
powerPreference: merged.powerPreference,
|
|
3484
|
+
onContextLost: function onContextLost() {
|
|
3485
|
+
contextLost = true;
|
|
3486
|
+
emitter.emit('contextlost', {});
|
|
3487
|
+
},
|
|
3488
|
+
onContextRestored: function onContextRestored() {
|
|
3489
|
+
contextLost = false;
|
|
3490
|
+
emitter.emit('contextrestored', {});
|
|
3491
|
+
renderOnce();
|
|
3492
|
+
wakeScheduler();
|
|
3493
|
+
}
|
|
2851
3494
|
});
|
|
2852
3495
|
} catch (error) {
|
|
2853
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
3496
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
3497
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
3498
|
+
});
|
|
2854
3499
|
nextTick(function () {
|
|
2855
3500
|
if (disposed) return;
|
|
2856
3501
|
emitter.emit('error', {
|
|
@@ -2859,19 +3504,37 @@ function createColorBackground(host) {
|
|
|
2859
3504
|
});
|
|
2860
3505
|
}
|
|
2861
3506
|
} else {
|
|
2862
|
-
renderer = new FallbackRenderer(canvas, merged
|
|
3507
|
+
renderer = new FallbackRenderer(canvas, merged, {
|
|
3508
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale)
|
|
3509
|
+
});
|
|
2863
3510
|
}
|
|
2864
|
-
|
|
2865
|
-
return renderer.resize();
|
|
2866
|
-
}) : null;
|
|
2867
|
-
if (resizeObserver) resizeObserver.observe(host);else window.addEventListener('resize', renderer.resize);
|
|
2868
|
-
var visibility = createVisibilityGuard(layer);
|
|
3511
|
+
renderer.resize();
|
|
2869
3512
|
var animationTime = 0;
|
|
3513
|
+
var frameGate = createFrameGate(merged.fps);
|
|
3514
|
+
renderOnce = function renderOnce() {
|
|
3515
|
+
return renderer.draw(animationTime);
|
|
3516
|
+
};
|
|
3517
|
+
var resize = function resize() {
|
|
3518
|
+
renderer.resize();
|
|
3519
|
+
if (manuallyPaused || reducedPaused || staticMode) renderOnce();
|
|
3520
|
+
};
|
|
3521
|
+
var resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(resize) : null;
|
|
3522
|
+
if (resizeObserver) resizeObserver.observe(host);else window.addEventListener('resize', resize);
|
|
3523
|
+
var visibility = createVisibilityGuard(layer, wakeScheduler);
|
|
3524
|
+
var motionPreference = createReducedMotionPreference(merged.respectReducedMotion, function (matches) {
|
|
3525
|
+
reducedPaused = matches;
|
|
3526
|
+
if (matches) renderOnce();else wakeScheduler();
|
|
3527
|
+
});
|
|
3528
|
+
reducedPaused = motionPreference.matches();
|
|
3529
|
+
var isMotionPaused = function isMotionPaused() {
|
|
3530
|
+
return manuallyPaused || reducedPaused || staticMode || contextLost;
|
|
3531
|
+
};
|
|
3532
|
+
renderOnce();
|
|
2870
3533
|
var unsubscribe = subscribeScheduler(function (delta) {
|
|
2871
3534
|
animationTime += delta;
|
|
2872
|
-
if (
|
|
3535
|
+
if (frameGate.shouldDraw(delta)) renderer.draw(animationTime);
|
|
2873
3536
|
}, function () {
|
|
2874
|
-
return
|
|
3537
|
+
return isMotionPaused() || !visibility.isVisible();
|
|
2875
3538
|
});
|
|
2876
3539
|
nextTick(function () {
|
|
2877
3540
|
if (disposed) return;
|
|
@@ -2890,11 +3553,15 @@ function createColorBackground(host) {
|
|
|
2890
3553
|
var next = getPreset('capsule', ref);
|
|
2891
3554
|
dirty.preset = true;
|
|
2892
3555
|
Object.assign(preset, next);
|
|
3556
|
+
if (colorOverride) preset.colors = _toConsumableArray(colorOverride);
|
|
3557
|
+
if (seedOverride !== null) preset.seed = seedOverride;
|
|
3558
|
+
if (speedOverride !== null) preset.speed = speedOverride;
|
|
2893
3559
|
var nextColors = preset.colors.map(normalizeColor);
|
|
2894
3560
|
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
2895
3561
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
2896
3562
|
renderer.resize();
|
|
2897
3563
|
syncLayerVars();
|
|
3564
|
+
if (isMotionPaused()) renderOnce();
|
|
2898
3565
|
emitter.emit('presetchange', {
|
|
2899
3566
|
preset: _objectSpread2({}, preset)
|
|
2900
3567
|
});
|
|
@@ -2906,27 +3573,33 @@ function createColorBackground(host) {
|
|
|
2906
3573
|
return !color;
|
|
2907
3574
|
})) return this;
|
|
2908
3575
|
dirty.colors = true;
|
|
3576
|
+
colorOverride = _toConsumableArray(next);
|
|
2909
3577
|
preset.colors = next;
|
|
2910
3578
|
renderer.setPreset(_objectSpread2(_objectSpread2({}, preset), {}, {
|
|
2911
3579
|
colors: next
|
|
2912
3580
|
}));
|
|
2913
3581
|
syncLayerVars();
|
|
3582
|
+
if (isMotionPaused()) renderOnce();
|
|
2914
3583
|
return this;
|
|
2915
3584
|
},
|
|
2916
3585
|
setSeed: function setSeed(seed) {
|
|
2917
|
-
var value =
|
|
2918
|
-
if (
|
|
3586
|
+
var value = toFiniteNumber(seed);
|
|
3587
|
+
if (value === null) return this;
|
|
2919
3588
|
dirty.seed = true;
|
|
3589
|
+
seedOverride = value;
|
|
2920
3590
|
preset.seed = value;
|
|
2921
3591
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
3592
|
+
if (isMotionPaused()) renderOnce();
|
|
2922
3593
|
return this;
|
|
2923
3594
|
},
|
|
2924
3595
|
setSpeed: function setSpeed(speed) {
|
|
2925
|
-
var value =
|
|
2926
|
-
if (
|
|
3596
|
+
var value = toFiniteNumber(speed);
|
|
3597
|
+
if (value === null) return this;
|
|
2927
3598
|
dirty.speed = true;
|
|
3599
|
+
speedOverride = value;
|
|
2928
3600
|
preset.speed = value;
|
|
2929
3601
|
renderer.setPreset(_objectSpread2({}, preset));
|
|
3602
|
+
if (isMotionPaused()) renderOnce();
|
|
2930
3603
|
return this;
|
|
2931
3604
|
},
|
|
2932
3605
|
setFallbackColor: function setFallbackColor(value) {
|
|
@@ -2942,8 +3615,23 @@ function createColorBackground(host) {
|
|
|
2942
3615
|
return this;
|
|
2943
3616
|
},
|
|
2944
3617
|
setQuality: function setQuality(quality) {
|
|
3618
|
+
dirty.quality = true;
|
|
2945
3619
|
merged.quality = quality;
|
|
2946
|
-
if (typeof renderer.setDprCap === 'function')
|
|
3620
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
3621
|
+
renderer.setDprCap(effectiveDprCap(quality, merged.renderScale));
|
|
3622
|
+
}
|
|
3623
|
+
if (isMotionPaused()) renderOnce();
|
|
3624
|
+
return this;
|
|
3625
|
+
},
|
|
3626
|
+
setRenderScale: function setRenderScale(renderScale) {
|
|
3627
|
+
var value = Number(renderScale);
|
|
3628
|
+
if (!Number.isFinite(value)) return this;
|
|
3629
|
+
dirty.renderScale = true;
|
|
3630
|
+
merged.renderScale = Math.min(1, Math.max(0.25, value));
|
|
3631
|
+
if (typeof renderer.setDprCap === 'function') {
|
|
3632
|
+
renderer.setDprCap(effectiveDprCap(merged.quality, merged.renderScale));
|
|
3633
|
+
}
|
|
3634
|
+
if (isMotionPaused()) renderOnce();
|
|
2947
3635
|
return this;
|
|
2948
3636
|
},
|
|
2949
3637
|
setOpacity: function setOpacity(value) {
|
|
@@ -2959,20 +3647,42 @@ function createColorBackground(host) {
|
|
|
2959
3647
|
return this;
|
|
2960
3648
|
},
|
|
2961
3649
|
pause: function pause() {
|
|
2962
|
-
paused = true;
|
|
3650
|
+
dirty.paused = true;
|
|
3651
|
+
manuallyPaused = true;
|
|
3652
|
+
renderOnce();
|
|
2963
3653
|
return this;
|
|
2964
3654
|
},
|
|
2965
3655
|
resume: function resume() {
|
|
2966
|
-
paused =
|
|
3656
|
+
dirty.paused = true;
|
|
3657
|
+
manuallyPaused = false;
|
|
3658
|
+
wakeScheduler();
|
|
3659
|
+
return this;
|
|
3660
|
+
},
|
|
3661
|
+
setPaused: function setPaused(value) {
|
|
3662
|
+
return value ? this.pause() : this.resume();
|
|
3663
|
+
},
|
|
3664
|
+
setStatic: function setStatic(value) {
|
|
3665
|
+
dirty.static = true;
|
|
3666
|
+
staticMode = value === true;
|
|
3667
|
+
merged.static = staticMode;
|
|
3668
|
+
if (staticMode) renderOnce();else wakeScheduler();
|
|
3669
|
+
return this;
|
|
3670
|
+
},
|
|
3671
|
+
setFps: function setFps(fps) {
|
|
3672
|
+
dirty.fps = true;
|
|
3673
|
+
merged.fps = frameGate.setFps(fps);
|
|
3674
|
+
wakeScheduler();
|
|
2967
3675
|
return this;
|
|
2968
3676
|
},
|
|
2969
3677
|
dispose: function dispose() {
|
|
2970
3678
|
disposed = true;
|
|
2971
3679
|
unsubscribe();
|
|
2972
3680
|
visibility.dispose();
|
|
2973
|
-
|
|
3681
|
+
motionPreference.dispose();
|
|
3682
|
+
if (resizeObserver) resizeObserver.disconnect();else window.removeEventListener('resize', resize);
|
|
2974
3683
|
renderer.dispose();
|
|
2975
3684
|
layer.remove();
|
|
3685
|
+
releaseHostStyles(host);
|
|
2976
3686
|
},
|
|
2977
3687
|
get opacity() {
|
|
2978
3688
|
return merged.opacity;
|
|
@@ -2983,31 +3693,51 @@ function createColorBackground(host) {
|
|
|
2983
3693
|
get mouseColor() {
|
|
2984
3694
|
return merged.mouseColor;
|
|
2985
3695
|
},
|
|
3696
|
+
get quality() {
|
|
3697
|
+
return merged.quality;
|
|
3698
|
+
},
|
|
3699
|
+
get renderScale() {
|
|
3700
|
+
return merged.renderScale;
|
|
3701
|
+
},
|
|
3702
|
+
get paused() {
|
|
3703
|
+
return manuallyPaused;
|
|
3704
|
+
},
|
|
3705
|
+
get static() {
|
|
3706
|
+
return staticMode;
|
|
3707
|
+
},
|
|
3708
|
+
get fps() {
|
|
3709
|
+
return frameGate.getFps();
|
|
3710
|
+
},
|
|
2986
3711
|
dirty: dirty
|
|
2987
3712
|
};
|
|
2988
3713
|
}
|
|
2989
3714
|
|
|
2990
|
-
/**
|
|
2991
|
-
* Shared Options-API wrapper factory. The only framework difference is the
|
|
2992
|
-
* render function: Vue2 passes `h` as an argument, Vue3 needs the imported
|
|
2993
|
-
* `h` (see vue2.js / vue3.js). Lifecycle options cover both.
|
|
3715
|
+
/**
|
|
3716
|
+
* Shared Options-API wrapper factory. The only framework difference is the
|
|
3717
|
+
* render function: Vue2 passes `h` as an argument, Vue3 needs the imported
|
|
3718
|
+
* `h` (see vue2.js / vue3.js). Lifecycle options cover both.
|
|
2994
3719
|
*/
|
|
2995
3720
|
|
|
2996
|
-
var CAPSULE_EVENTS = ['ready', 'error', 'click', 'pointerdown', 'pointerup', 'dblclick', 'pointerenter', 'pointerleave', 'presetchange'];
|
|
2997
|
-
var PROGRESS_EVENTS = ['ready', 'error', 'change', 'dragstart', 'dragend', 'presetchange'];
|
|
2998
|
-
var COLOR_EVENTS = ['ready', 'error', 'presetchange'];
|
|
3721
|
+
var CAPSULE_EVENTS = ['ready', 'error', 'click', 'pointerdown', 'pointerup', 'dblclick', 'pointerenter', 'pointerleave', 'presetchange', 'contextlost', 'contextrestored'];
|
|
3722
|
+
var PROGRESS_EVENTS = ['ready', 'error', 'change', 'input', 'update:modelValue', 'dragstart', 'dragend', 'presetchange', 'contextlost', 'contextrestored'];
|
|
3723
|
+
var COLOR_EVENTS = ['ready', 'error', 'presetchange', 'contextlost', 'contextrestored'];
|
|
2999
3724
|
function hookEvents(controller, events, emit) {
|
|
3000
3725
|
var _iterator = _createForOfIteratorHelper(events),
|
|
3001
3726
|
_step;
|
|
3002
3727
|
try {
|
|
3003
3728
|
var _loop = function _loop() {
|
|
3004
3729
|
var event = _step.value;
|
|
3730
|
+
if (event === 'input' || event === 'update:modelValue') return 1; // continue
|
|
3005
3731
|
controller.on(event, function (payload) {
|
|
3006
|
-
|
|
3732
|
+
emit(event, payload);
|
|
3733
|
+
if (event === 'change' && payload && (payload.source === 'drag' || payload.source === 'keyboard')) {
|
|
3734
|
+
if (events.indexOf('input') !== -1) emit('input', payload.value);
|
|
3735
|
+
if (events.indexOf('update:modelValue') !== -1) emit('update:modelValue', payload.value);
|
|
3736
|
+
}
|
|
3007
3737
|
});
|
|
3008
3738
|
};
|
|
3009
3739
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
3010
|
-
_loop();
|
|
3740
|
+
if (_loop()) continue;
|
|
3011
3741
|
}
|
|
3012
3742
|
} catch (err) {
|
|
3013
3743
|
_iterator.e(err);
|
|
@@ -3098,6 +3828,17 @@ function makeWrapper(_ref) {
|
|
|
3098
3828
|
if (dirty.opacity) state.opacity = controller.opacity;
|
|
3099
3829
|
if (dirty.fallbackColor) state.fallbackColor = controller.fallbackColor;
|
|
3100
3830
|
if (dirty.mouseColor) state.mouseColor = controller.mouseColor;
|
|
3831
|
+
if (dirty.quality) state.quality = controller.quality;
|
|
3832
|
+
if (dirty.renderScale) state.renderScale = controller.renderScale;
|
|
3833
|
+
if (dirty.paused) state.paused = controller.paused;
|
|
3834
|
+
if (dirty.static) state.static = controller.static;
|
|
3835
|
+
if (dirty.fps) state.fps = controller.fps;
|
|
3836
|
+
if (dirty.step) state.step = controller.step;
|
|
3837
|
+
if (dirty.precision) state.precision = controller.precision;
|
|
3838
|
+
if (dirty.formatValue) state.formatValue = controller.formatValue;
|
|
3839
|
+
if (dirty.direction) state.direction = controller.direction;
|
|
3840
|
+
if (dirty.showValue) state.showValue = controller.showValue;
|
|
3841
|
+
if (dirty.valueSuffix) state.valueSuffix = controller.valueSuffix;
|
|
3101
3842
|
return state;
|
|
3102
3843
|
}
|
|
3103
3844
|
};
|
|
@@ -3143,7 +3884,7 @@ function makeWrapper(_ref) {
|
|
|
3143
3884
|
function makeCapsuleWrapper(createCapsule, render) {
|
|
3144
3885
|
return makeWrapper({
|
|
3145
3886
|
name: 'dlc-capsule',
|
|
3146
|
-
props: ['preset', 'width', 'height', 'colors', 'seed', 'speed', 'textRatio', 'label', 'mouseColor', 'renderer', 'quality', 'respectReducedMotion', 'cssVars'],
|
|
3887
|
+
props: ['preset', 'width', 'height', 'colors', 'seed', 'speed', 'textRatio', 'label', 'mouseColor', 'renderer', 'quality', 'respectReducedMotion', 'cssVars', 'paused', 'static', 'fps', 'renderScale', 'powerPreference'],
|
|
3147
3888
|
events: CAPSULE_EVENTS,
|
|
3148
3889
|
create: createCapsule,
|
|
3149
3890
|
render: render,
|
|
@@ -3172,8 +3913,26 @@ function makeCapsuleWrapper(createCapsule, render) {
|
|
|
3172
3913
|
mouseColor: function mouseColor(value) {
|
|
3173
3914
|
if (this.controller) this.controller.setMouseColor(value);
|
|
3174
3915
|
},
|
|
3916
|
+
paused: function paused(value) {
|
|
3917
|
+
if (this.controller) this.controller.setPaused(value);
|
|
3918
|
+
},
|
|
3919
|
+
static: function _static(value) {
|
|
3920
|
+
if (this.controller) this.controller.setStatic(value);
|
|
3921
|
+
},
|
|
3922
|
+
fps: function fps(value) {
|
|
3923
|
+
if (value !== undefined && this.controller) this.controller.setFps(value);
|
|
3924
|
+
},
|
|
3925
|
+
renderScale: function renderScale(value) {
|
|
3926
|
+
if (value !== undefined && this.controller) this.controller.setRenderScale(value);
|
|
3927
|
+
},
|
|
3175
3928
|
renderer: function renderer() {
|
|
3176
3929
|
this.scheduleRecreate();
|
|
3930
|
+
},
|
|
3931
|
+
powerPreference: function powerPreference() {
|
|
3932
|
+
this.scheduleRecreate();
|
|
3933
|
+
},
|
|
3934
|
+
respectReducedMotion: function respectReducedMotion() {
|
|
3935
|
+
this.scheduleRecreate();
|
|
3177
3936
|
}
|
|
3178
3937
|
},
|
|
3179
3938
|
methods: {
|
|
@@ -3216,6 +3975,18 @@ function makeCapsuleWrapper(createCapsule, render) {
|
|
|
3216
3975
|
setQuality: function setQuality(quality) {
|
|
3217
3976
|
return this.controller && this.controller.setQuality(quality);
|
|
3218
3977
|
},
|
|
3978
|
+
setRenderScale: function setRenderScale(value) {
|
|
3979
|
+
return this.controller && this.controller.setRenderScale(value);
|
|
3980
|
+
},
|
|
3981
|
+
setPaused: function setPaused(value) {
|
|
3982
|
+
return this.controller && this.controller.setPaused(value);
|
|
3983
|
+
},
|
|
3984
|
+
setStatic: function setStatic(value) {
|
|
3985
|
+
return this.controller && this.controller.setStatic(value);
|
|
3986
|
+
},
|
|
3987
|
+
setFps: function setFps(value) {
|
|
3988
|
+
return this.controller && this.controller.setFps(value);
|
|
3989
|
+
},
|
|
3219
3990
|
getController: function getController() {
|
|
3220
3991
|
return this.controller;
|
|
3221
3992
|
}
|
|
@@ -3225,13 +3996,16 @@ function makeCapsuleWrapper(createCapsule, render) {
|
|
|
3225
3996
|
function makeProgressWrapper(createProgressCapsule, render) {
|
|
3226
3997
|
return makeWrapper({
|
|
3227
3998
|
name: 'dlc-progress',
|
|
3228
|
-
props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
|
|
3999
|
+
props: ['preset', 'width', 'height', 'value', 'modelValue', 'min', 'max', 'step', 'draggable', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'keyboard', 'direction', 'precision', 'formatValue', 'quality', 'renderer', 'respectReducedMotion', 'cssVars', 'paused', 'static', 'fps', 'renderScale', 'powerPreference'],
|
|
3229
4000
|
events: PROGRESS_EVENTS,
|
|
3230
4001
|
create: createProgressCapsule,
|
|
3231
4002
|
render: render,
|
|
3232
4003
|
watch: {
|
|
3233
4004
|
value: function value(_value) {
|
|
3234
|
-
if (_value !== undefined && this.controller) this.controller.setValue(_value);
|
|
4005
|
+
if (_value !== undefined && this.modelValue === undefined && this.controller) this.controller.setValue(_value);
|
|
4006
|
+
},
|
|
4007
|
+
modelValue: function modelValue(value) {
|
|
4008
|
+
if (value !== undefined && this.controller) this.controller.setValue(value);
|
|
3235
4009
|
},
|
|
3236
4010
|
min: function min(value) {
|
|
3237
4011
|
if (value !== undefined && this.controller) this.controller.setRange(value, this.controller.max);
|
|
@@ -3239,6 +4013,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3239
4013
|
max: function max(value) {
|
|
3240
4014
|
if (value !== undefined && this.controller) this.controller.setRange(this.controller.min, value);
|
|
3241
4015
|
},
|
|
4016
|
+
step: function step(value) {
|
|
4017
|
+
if (value !== undefined && this.controller) this.controller.setStep(value);
|
|
4018
|
+
},
|
|
3242
4019
|
edgeStyle: function edgeStyle(value) {
|
|
3243
4020
|
if (value && this.controller) this.controller.setEdgeStyle(value);
|
|
3244
4021
|
},
|
|
@@ -3257,6 +4034,27 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3257
4034
|
showValue: function showValue(value) {
|
|
3258
4035
|
if (this.controller) this.controller.setShowValue(value);
|
|
3259
4036
|
},
|
|
4037
|
+
direction: function direction(value) {
|
|
4038
|
+
if (value && this.controller) this.controller.setDirection(value);
|
|
4039
|
+
},
|
|
4040
|
+
precision: function precision(value) {
|
|
4041
|
+
if (value !== undefined && this.controller) this.controller.setPrecision(value);
|
|
4042
|
+
},
|
|
4043
|
+
formatValue: function formatValue(value) {
|
|
4044
|
+
if (this.controller) this.controller.setFormatValue(value);
|
|
4045
|
+
},
|
|
4046
|
+
paused: function paused(value) {
|
|
4047
|
+
if (this.controller) this.controller.setPaused(value);
|
|
4048
|
+
},
|
|
4049
|
+
static: function _static(value) {
|
|
4050
|
+
if (this.controller) this.controller.setStatic(value);
|
|
4051
|
+
},
|
|
4052
|
+
fps: function fps(value) {
|
|
4053
|
+
if (value !== undefined && this.controller) this.controller.setFps(value);
|
|
4054
|
+
},
|
|
4055
|
+
renderScale: function renderScale(value) {
|
|
4056
|
+
if (value !== undefined && this.controller) this.controller.setRenderScale(value);
|
|
4057
|
+
},
|
|
3260
4058
|
disabled: function disabled() {
|
|
3261
4059
|
this.scheduleRecreate();
|
|
3262
4060
|
},
|
|
@@ -3268,6 +4066,15 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3268
4066
|
},
|
|
3269
4067
|
renderer: function renderer() {
|
|
3270
4068
|
this.scheduleRecreate();
|
|
4069
|
+
},
|
|
4070
|
+
keyboard: function keyboard() {
|
|
4071
|
+
this.scheduleRecreate();
|
|
4072
|
+
},
|
|
4073
|
+
powerPreference: function powerPreference() {
|
|
4074
|
+
this.scheduleRecreate();
|
|
4075
|
+
},
|
|
4076
|
+
respectReducedMotion: function respectReducedMotion() {
|
|
4077
|
+
this.scheduleRecreate();
|
|
3271
4078
|
}
|
|
3272
4079
|
},
|
|
3273
4080
|
methods: {
|
|
@@ -3280,6 +4087,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3280
4087
|
setRange: function setRange(min, max) {
|
|
3281
4088
|
return this.controller && this.controller.setRange(min, max);
|
|
3282
4089
|
},
|
|
4090
|
+
setStep: function setStep(step) {
|
|
4091
|
+
return this.controller && this.controller.setStep(step);
|
|
4092
|
+
},
|
|
3283
4093
|
randomize: function randomize() {
|
|
3284
4094
|
return this.controller && this.controller.randomize();
|
|
3285
4095
|
},
|
|
@@ -3319,9 +4129,30 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3319
4129
|
setShowValue: function setShowValue(show) {
|
|
3320
4130
|
return this.controller && this.controller.setShowValue(show);
|
|
3321
4131
|
},
|
|
4132
|
+
setDirection: function setDirection(direction) {
|
|
4133
|
+
return this.controller && this.controller.setDirection(direction);
|
|
4134
|
+
},
|
|
4135
|
+
setPrecision: function setPrecision(precision) {
|
|
4136
|
+
return this.controller && this.controller.setPrecision(precision);
|
|
4137
|
+
},
|
|
4138
|
+
setFormatValue: function setFormatValue(formatter) {
|
|
4139
|
+
return this.controller && this.controller.setFormatValue(formatter);
|
|
4140
|
+
},
|
|
3322
4141
|
setQuality: function setQuality(quality) {
|
|
3323
4142
|
return this.controller && this.controller.setQuality(quality);
|
|
3324
4143
|
},
|
|
4144
|
+
setRenderScale: function setRenderScale(value) {
|
|
4145
|
+
return this.controller && this.controller.setRenderScale(value);
|
|
4146
|
+
},
|
|
4147
|
+
setPaused: function setPaused(value) {
|
|
4148
|
+
return this.controller && this.controller.setPaused(value);
|
|
4149
|
+
},
|
|
4150
|
+
setStatic: function setStatic(value) {
|
|
4151
|
+
return this.controller && this.controller.setStatic(value);
|
|
4152
|
+
},
|
|
4153
|
+
setFps: function setFps(value) {
|
|
4154
|
+
return this.controller && this.controller.setFps(value);
|
|
4155
|
+
},
|
|
3325
4156
|
getController: function getController() {
|
|
3326
4157
|
return this.controller;
|
|
3327
4158
|
}
|
|
@@ -3331,7 +4162,7 @@ function makeProgressWrapper(createProgressCapsule, render) {
|
|
|
3331
4162
|
function makeColorWrapper(createColorBackground, render) {
|
|
3332
4163
|
return makeWrapper({
|
|
3333
4164
|
name: 'dlc-color',
|
|
3334
|
-
props: ['preset', 'colors', 'seed', 'speed', 'quality', 'renderer', 'mouseColor', 'respectReducedMotion', 'opacity', 'fallbackColor'],
|
|
4165
|
+
props: ['preset', 'colors', 'seed', 'speed', 'quality', 'renderer', 'mouseColor', 'respectReducedMotion', 'opacity', 'fallbackColor', 'paused', 'static', 'fps', 'renderScale', 'powerPreference'],
|
|
3335
4166
|
events: COLOR_EVENTS,
|
|
3336
4167
|
create: createColorBackground,
|
|
3337
4168
|
render: render,
|
|
@@ -3353,11 +4184,26 @@ function makeColorWrapper(createColorBackground, render) {
|
|
|
3353
4184
|
mouseColor: function mouseColor(value) {
|
|
3354
4185
|
if (this.controller) this.controller.setMouseColor(value);
|
|
3355
4186
|
},
|
|
4187
|
+
paused: function paused(value) {
|
|
4188
|
+
if (this.controller) this.controller.setPaused(value);
|
|
4189
|
+
},
|
|
4190
|
+
static: function _static(value) {
|
|
4191
|
+
if (this.controller) this.controller.setStatic(value);
|
|
4192
|
+
},
|
|
4193
|
+
fps: function fps(value) {
|
|
4194
|
+
if (value !== undefined && this.controller) this.controller.setFps(value);
|
|
4195
|
+
},
|
|
4196
|
+
renderScale: function renderScale(value) {
|
|
4197
|
+
if (value !== undefined && this.controller) this.controller.setRenderScale(value);
|
|
4198
|
+
},
|
|
3356
4199
|
renderer: function renderer() {
|
|
3357
4200
|
this.scheduleRecreate();
|
|
3358
4201
|
},
|
|
3359
4202
|
respectReducedMotion: function respectReducedMotion() {
|
|
3360
4203
|
this.scheduleRecreate();
|
|
4204
|
+
},
|
|
4205
|
+
powerPreference: function powerPreference() {
|
|
4206
|
+
this.scheduleRecreate();
|
|
3361
4207
|
}
|
|
3362
4208
|
},
|
|
3363
4209
|
methods: {
|
|
@@ -3376,6 +4222,9 @@ function makeColorWrapper(createColorBackground, render) {
|
|
|
3376
4222
|
setQuality: function setQuality(quality) {
|
|
3377
4223
|
return this.controller && this.controller.setQuality(quality);
|
|
3378
4224
|
},
|
|
4225
|
+
setRenderScale: function setRenderScale(value) {
|
|
4226
|
+
return this.controller && this.controller.setRenderScale(value);
|
|
4227
|
+
},
|
|
3379
4228
|
setOpacity: function setOpacity(value) {
|
|
3380
4229
|
return this.controller && this.controller.setOpacity(value);
|
|
3381
4230
|
},
|
|
@@ -3394,6 +4243,15 @@ function makeColorWrapper(createColorBackground, render) {
|
|
|
3394
4243
|
resume: function resume() {
|
|
3395
4244
|
return this.controller && this.controller.resume();
|
|
3396
4245
|
},
|
|
4246
|
+
setPaused: function setPaused(value) {
|
|
4247
|
+
return this.controller && this.controller.setPaused(value);
|
|
4248
|
+
},
|
|
4249
|
+
setStatic: function setStatic(value) {
|
|
4250
|
+
return this.controller && this.controller.setStatic(value);
|
|
4251
|
+
},
|
|
4252
|
+
setFps: function setFps(value) {
|
|
4253
|
+
return this.controller && this.controller.setFps(value);
|
|
4254
|
+
},
|
|
3397
4255
|
getController: function getController() {
|
|
3398
4256
|
return this.controller;
|
|
3399
4257
|
}
|