@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/progress.cjs
CHANGED
|
@@ -95,7 +95,10 @@ function _iterableToArrayLimit(r, l) {
|
|
|
95
95
|
f = true,
|
|
96
96
|
o = false;
|
|
97
97
|
try {
|
|
98
|
-
if (i = (t = t.call(r)).next, 0 === l)
|
|
98
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
99
|
+
if (Object(t) !== t) return;
|
|
100
|
+
f = !1;
|
|
101
|
+
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
99
102
|
} catch (r) {
|
|
100
103
|
o = true, n = r;
|
|
101
104
|
} finally {
|
|
@@ -172,9 +175,9 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
|
|
175
|
-
/**
|
|
176
|
-
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
177
|
-
* future events (hover, click, custom) without breaking changes.
|
|
178
|
+
/**
|
|
179
|
+
* Tiny event emitter. Accepts any event name so the API stays open for
|
|
180
|
+
* future events (hover, click, custom) without breaking changes.
|
|
178
181
|
*/
|
|
179
182
|
function createEmitter() {
|
|
180
183
|
// Plain object storage (no Map/Set) so the legacy build has no API
|
|
@@ -224,9 +227,9 @@ function createEmitter() {
|
|
|
224
227
|
|
|
225
228
|
var UNIT_PATTERN = /^[\d.]+(?:px|%|vw|vh|vmin|vmax|em|rem)$/;
|
|
226
229
|
|
|
227
|
-
/**
|
|
228
|
-
* Normalize a size option to a CSS length string.
|
|
229
|
-
* Accepts numbers (treated as px) or strings with px/%, vw/vh/vmin/vmax, em/rem.
|
|
230
|
+
/**
|
|
231
|
+
* Normalize a size option to a CSS length string.
|
|
232
|
+
* Accepts numbers (treated as px) or strings with px/%, vw/vh/vmin/vmax, em/rem.
|
|
230
233
|
*/
|
|
231
234
|
function parseSize(value) {
|
|
232
235
|
if (typeof value === 'number') {
|
|
@@ -265,11 +268,17 @@ function dprCapFor(quality) {
|
|
|
265
268
|
var tier = QUALITY_TIERS[quality] || QUALITY_TIERS.medium;
|
|
266
269
|
return tier.dpr;
|
|
267
270
|
}
|
|
271
|
+
function effectiveDprCap(quality) {
|
|
272
|
+
var renderScale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
273
|
+
var scale = Number(renderScale);
|
|
274
|
+
var normalizedScale = Number.isFinite(scale) ? Math.min(1, Math.max(0.25, scale)) : 1;
|
|
275
|
+
return Math.max(0.5, dprCapFor(quality) * normalizedScale);
|
|
276
|
+
}
|
|
268
277
|
|
|
269
|
-
/**
|
|
270
|
-
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
271
|
-
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
272
|
-
* change.
|
|
278
|
+
/**
|
|
279
|
+
* Merge defaults < preset < user. Unknown user keys are preserved so the
|
|
280
|
+
* component API can grow (new props, cssVars, callbacks) without a breaking
|
|
281
|
+
* change.
|
|
273
282
|
*/
|
|
274
283
|
function normalizeOptions(defaults, preset, user) {
|
|
275
284
|
// undefined means "not provided" (e.g. Vue $props with unset props):
|
|
@@ -287,9 +296,9 @@ function normalizeOptions(defaults, preset, user) {
|
|
|
287
296
|
return _objectSpread2(_objectSpread2(_objectSpread2({}, defaults), presetOptions), userOptions);
|
|
288
297
|
}
|
|
289
298
|
|
|
290
|
-
/**
|
|
291
|
-
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
292
|
-
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
299
|
+
/**
|
|
300
|
+
* 公共色板:NC-01~NC-06 的四色组(底色 / 主色 / 辅色 / 高光色)。
|
|
301
|
+
* Capsule 预置与 dlc-color 等组件共用,新增色板只改这里。
|
|
293
302
|
*/
|
|
294
303
|
var PALETTES$1 = {
|
|
295
304
|
original: ['#FFF3EA', '#F5B27A', '#F67BC6', '#A978E8'],
|
|
@@ -300,9 +309,9 @@ var PALETTES$1 = {
|
|
|
300
309
|
plus: ['#FFF0E6', '#F6C26B', '#F98A64', '#E86D74']
|
|
301
310
|
};
|
|
302
311
|
|
|
303
|
-
/**
|
|
304
|
-
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
305
|
-
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
312
|
+
/**
|
|
313
|
+
* Capsule 预置:仅星云材质 NC-01~NC-06(NC-07~09 aurora 已移除)。
|
|
314
|
+
* 颜色引用公共色板,seed/speed 决定形态与流速。
|
|
306
315
|
*/
|
|
307
316
|
var CAPSULE_PRESETS = [{
|
|
308
317
|
id: 'original',
|
|
@@ -420,13 +429,22 @@ var DEFAULTS = {
|
|
|
420
429
|
height: 104,
|
|
421
430
|
min: 0,
|
|
422
431
|
max: 100,
|
|
432
|
+
step: 'any',
|
|
423
433
|
draggable: true,
|
|
434
|
+
keyboard: true,
|
|
424
435
|
disabled: false,
|
|
425
436
|
readonly: false,
|
|
437
|
+
direction: 'ltr',
|
|
438
|
+
precision: 0,
|
|
426
439
|
valueSuffix: '%',
|
|
427
440
|
edgeStyle: 'flow',
|
|
428
441
|
quality: 'auto',
|
|
429
442
|
renderer: 'auto',
|
|
443
|
+
renderScale: 1,
|
|
444
|
+
powerPreference: 'high-performance',
|
|
445
|
+
fps: 60,
|
|
446
|
+
paused: false,
|
|
447
|
+
static: false,
|
|
430
448
|
textRatio: 54,
|
|
431
449
|
showValue: true,
|
|
432
450
|
respectReducedMotion: true
|
|
@@ -660,10 +678,10 @@ function hexToRgba(color) {
|
|
|
660
678
|
return "rgba(".concat(red, ", ").concat(green, ", ").concat(blue, ", ").concat(alpha, ")");
|
|
661
679
|
}
|
|
662
680
|
|
|
663
|
-
/**
|
|
664
|
-
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
665
|
-
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
666
|
-
* original demo), which avoids jank from many competing rAF loops.
|
|
681
|
+
/**
|
|
682
|
+
* Document-level shared rAF scheduler. Every component instance subscribes
|
|
683
|
+
* its own frame callback; the whole page runs ONE animation loop (like the
|
|
684
|
+
* original demo), which avoids jank from many competing rAF loops.
|
|
667
685
|
*/
|
|
668
686
|
var subscribers = [];
|
|
669
687
|
var running = false;
|
|
@@ -671,11 +689,7 @@ var rafId = 0;
|
|
|
671
689
|
var last = 0;
|
|
672
690
|
function tick(now) {
|
|
673
691
|
if (!running) return;
|
|
674
|
-
var
|
|
675
|
-
last = now;
|
|
676
|
-
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
677
|
-
// subscriber can never kill the whole animation loop.
|
|
678
|
-
rafId = requestAnimationFrame(tick);
|
|
692
|
+
var activeItems = [];
|
|
679
693
|
{
|
|
680
694
|
var _iterator = _createForOfIteratorHelper(subscribers.slice()),
|
|
681
695
|
_step;
|
|
@@ -683,10 +697,8 @@ function tick(now) {
|
|
|
683
697
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
684
698
|
var item = _step.value;
|
|
685
699
|
try {
|
|
686
|
-
if (!item.isPaused())
|
|
687
|
-
} catch (
|
|
688
|
-
console.warn('[dlc-ui] frame error:', error);
|
|
689
|
-
}
|
|
700
|
+
if (!item.isPaused()) activeItems.push(item);
|
|
701
|
+
} catch (_unused) {}
|
|
690
702
|
}
|
|
691
703
|
} catch (err) {
|
|
692
704
|
_iterator.e(err);
|
|
@@ -694,6 +706,25 @@ function tick(now) {
|
|
|
694
706
|
_iterator.f();
|
|
695
707
|
}
|
|
696
708
|
}
|
|
709
|
+
if (activeItems.length === 0) {
|
|
710
|
+
running = false;
|
|
711
|
+
rafId = 0;
|
|
712
|
+
last = 0;
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
var delta = last ? Math.min((now - last) / 1000, 0.05) : 0;
|
|
716
|
+
last = now;
|
|
717
|
+
// Schedule the next frame BEFORE running callbacks so one throwing
|
|
718
|
+
// subscriber can never kill the whole animation loop.
|
|
719
|
+
rafId = requestAnimationFrame(tick);
|
|
720
|
+
for (var _i = 0, _activeItems = activeItems; _i < _activeItems.length; _i++) {
|
|
721
|
+
var _item = _activeItems[_i];
|
|
722
|
+
try {
|
|
723
|
+
_item.onFrame(delta, now);
|
|
724
|
+
} catch (error) {
|
|
725
|
+
console.warn('[dlc-ui] frame error:', error);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
697
728
|
if (subscribers.length === 0) {
|
|
698
729
|
cancelAnimationFrame(rafId);
|
|
699
730
|
running = false;
|
|
@@ -706,6 +737,9 @@ function start() {
|
|
|
706
737
|
last = 0;
|
|
707
738
|
rafId = requestAnimationFrame(tick);
|
|
708
739
|
}
|
|
740
|
+
function wakeScheduler() {
|
|
741
|
+
start();
|
|
742
|
+
}
|
|
709
743
|
function subscribeScheduler(onFrame, isPaused) {
|
|
710
744
|
var item = {
|
|
711
745
|
onFrame: onFrame,
|
|
@@ -724,11 +758,12 @@ function subscribeScheduler(onFrame, isPaused) {
|
|
|
724
758
|
};
|
|
725
759
|
}
|
|
726
760
|
|
|
727
|
-
/**
|
|
728
|
-
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
729
|
-
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
761
|
+
/**
|
|
762
|
+
* Gates drawing on "element intersects viewport AND the page tab is visible".
|
|
763
|
+
* Falls back to always-visible when IntersectionObserver is unavailable.
|
|
730
764
|
*/
|
|
731
765
|
function createVisibilityGuard(element) {
|
|
766
|
+
var onChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
732
767
|
var intersecting = true;
|
|
733
768
|
var pageVisible = typeof document === 'undefined' || !document.hidden;
|
|
734
769
|
var disposed = false;
|
|
@@ -738,6 +773,7 @@ function createVisibilityGuard(element) {
|
|
|
738
773
|
intersecting = entries.some(function (entry) {
|
|
739
774
|
return entry.isIntersecting;
|
|
740
775
|
});
|
|
776
|
+
if (typeof onChange === 'function') onChange();
|
|
741
777
|
}, {
|
|
742
778
|
rootMargin: '180px'
|
|
743
779
|
});
|
|
@@ -745,6 +781,7 @@ function createVisibilityGuard(element) {
|
|
|
745
781
|
}
|
|
746
782
|
var onVisibilityChange = function onVisibilityChange() {
|
|
747
783
|
pageVisible = typeof document !== 'undefined' && !document.hidden;
|
|
784
|
+
if (typeof onChange === 'function') onChange();
|
|
748
785
|
};
|
|
749
786
|
if (typeof document !== 'undefined') {
|
|
750
787
|
document.addEventListener('visibilitychange', onVisibilityChange);
|
|
@@ -869,7 +906,7 @@ var MOTION_SCALE_FACTORS = {
|
|
|
869
906
|
'tide': 1.18
|
|
870
907
|
};
|
|
871
908
|
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}";
|
|
872
|
-
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,
|
|
909
|
+
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}";
|
|
873
910
|
function compileShader(gl, type, source) {
|
|
874
911
|
var shader = gl.createShader(type);
|
|
875
912
|
gl.shaderSource(shader, source);
|
|
@@ -900,64 +937,95 @@ function createProgram(gl) {
|
|
|
900
937
|
var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
901
938
|
function ProgressFlowRenderer(canvas, preset) {
|
|
902
939
|
var _PROFILE_INDEX$preset;
|
|
940
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
903
941
|
_classCallCheck(this, ProgressFlowRenderer);
|
|
904
942
|
var gl = canvas.getContext('webgl2', {
|
|
905
943
|
alpha: false,
|
|
906
944
|
antialias: true,
|
|
907
945
|
premultipliedAlpha: false,
|
|
908
|
-
powerPreference: 'high-performance'
|
|
946
|
+
powerPreference: options.powerPreference || 'high-performance'
|
|
909
947
|
});
|
|
910
948
|
if (!gl) throw new Error('WebGL2 unavailable');
|
|
911
949
|
this.canvas = canvas;
|
|
950
|
+
this.options = options;
|
|
912
951
|
this.gl = gl;
|
|
913
|
-
this.program = createProgram(gl);
|
|
914
952
|
this.profile = preset.edgeStyle === 'tide' ? 3 : (_PROFILE_INDEX$preset = PROFILE_INDEX[preset.id]) !== null && _PROFILE_INDEX$preset !== void 0 ? _PROFILE_INDEX$preset : 2;
|
|
915
953
|
this.seed = stringSeed$1("".concat(preset.id, "-shader")) * 13.7 + 1.0;
|
|
916
954
|
this.colors = preset.colors.map(hexToRgb01);
|
|
917
955
|
this.motionData = getProgressMotionData(preset.id, preset.edgeStyle);
|
|
918
956
|
var motionFactor = preset.edgeStyle === 'tide' ? MOTION_SCALE_FACTORS.tide : MOTION_SCALE_FACTORS[preset.id] || 1.04;
|
|
919
957
|
this.motionScale = PROGRESS_MOTION_MAX_PX * motionFactor / 1257;
|
|
920
|
-
this.
|
|
921
|
-
this.
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
progress: gl.getUniformLocation(this.program, 'u_progress'),
|
|
925
|
-
seed: gl.getUniformLocation(this.program, 'u_seed'),
|
|
926
|
-
profile: gl.getUniformLocation(this.program, 'u_profile'),
|
|
927
|
-
motion: gl.getUniformLocation(this.program, 'u_motion'),
|
|
928
|
-
effect: gl.getUniformLocation(this.program, 'u_effect'),
|
|
929
|
-
hasEffect: gl.getUniformLocation(this.program, 'u_hasEffect'),
|
|
930
|
-
effectFrames: gl.getUniformLocation(this.program, 'u_effectFrames'),
|
|
931
|
-
motionDuration: gl.getUniformLocation(this.program, 'u_motionDuration'),
|
|
932
|
-
motionScale: gl.getUniformLocation(this.program, 'u_motionScale'),
|
|
933
|
-
dark: gl.getUniformLocation(this.program, 'u_dark'),
|
|
934
|
-
accentA: gl.getUniformLocation(this.program, 'u_accentA'),
|
|
935
|
-
accentB: gl.getUniformLocation(this.program, 'u_accentB'),
|
|
936
|
-
glow: gl.getUniformLocation(this.program, 'u_glow')
|
|
937
|
-
};
|
|
938
|
-
this.buffer = gl.createBuffer();
|
|
939
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
940
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);
|
|
941
|
-
this.motionTexture = gl.createTexture();
|
|
942
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
943
|
-
gl.bindTexture(gl.TEXTURE_2D, this.motionTexture);
|
|
944
|
-
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
945
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, PROGRESS_MOTION_WIDTH, PROGRESS_MOTION_HEIGHT, 0, gl.RED, gl.UNSIGNED_BYTE, this.motionData);
|
|
946
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
947
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
948
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
|
949
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
950
|
-
this.effectTexture = gl.createTexture();
|
|
951
|
-
gl.activeTexture(gl.TEXTURE1);
|
|
952
|
-
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
953
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([32, 33, 38]));
|
|
954
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
955
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
956
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
957
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
958
|
-
this.effectUploaded = false;
|
|
958
|
+
this.disposed = false;
|
|
959
|
+
this.contextLost = false;
|
|
960
|
+
this.setupResources();
|
|
961
|
+
this.bindContextEvents();
|
|
959
962
|
}
|
|
960
963
|
return _createClass(ProgressFlowRenderer, [{
|
|
964
|
+
key: "setupResources",
|
|
965
|
+
value: function setupResources() {
|
|
966
|
+
var gl = this.gl;
|
|
967
|
+
this.program = createProgram(gl);
|
|
968
|
+
this.position = gl.getAttribLocation(this.program, 'a_position');
|
|
969
|
+
this.uniforms = {
|
|
970
|
+
resolution: gl.getUniformLocation(this.program, 'u_resolution'),
|
|
971
|
+
time: gl.getUniformLocation(this.program, 'u_time'),
|
|
972
|
+
progress: gl.getUniformLocation(this.program, 'u_progress'),
|
|
973
|
+
seed: gl.getUniformLocation(this.program, 'u_seed'),
|
|
974
|
+
profile: gl.getUniformLocation(this.program, 'u_profile'),
|
|
975
|
+
motion: gl.getUniformLocation(this.program, 'u_motion'),
|
|
976
|
+
effect: gl.getUniformLocation(this.program, 'u_effect'),
|
|
977
|
+
hasEffect: gl.getUniformLocation(this.program, 'u_hasEffect'),
|
|
978
|
+
effectFrames: gl.getUniformLocation(this.program, 'u_effectFrames'),
|
|
979
|
+
motionDuration: gl.getUniformLocation(this.program, 'u_motionDuration'),
|
|
980
|
+
motionScale: gl.getUniformLocation(this.program, 'u_motionScale'),
|
|
981
|
+
dark: gl.getUniformLocation(this.program, 'u_dark'),
|
|
982
|
+
accentA: gl.getUniformLocation(this.program, 'u_accentA'),
|
|
983
|
+
accentB: gl.getUniformLocation(this.program, 'u_accentB'),
|
|
984
|
+
glow: gl.getUniformLocation(this.program, 'u_glow')
|
|
985
|
+
};
|
|
986
|
+
this.buffer = gl.createBuffer();
|
|
987
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
988
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);
|
|
989
|
+
this.motionTexture = gl.createTexture();
|
|
990
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
991
|
+
gl.bindTexture(gl.TEXTURE_2D, this.motionTexture);
|
|
992
|
+
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
993
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, PROGRESS_MOTION_WIDTH, PROGRESS_MOTION_HEIGHT, 0, gl.RED, gl.UNSIGNED_BYTE, this.motionData);
|
|
994
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
995
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
996
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
|
997
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
998
|
+
this.effectTexture = gl.createTexture();
|
|
999
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
1000
|
+
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
1001
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([32, 33, 38]));
|
|
1002
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1003
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1004
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1005
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1006
|
+
this.effectUploaded = false;
|
|
1007
|
+
}
|
|
1008
|
+
}, {
|
|
1009
|
+
key: "bindContextEvents",
|
|
1010
|
+
value: function bindContextEvents() {
|
|
1011
|
+
var _this = this;
|
|
1012
|
+
this.onContextLost = function (event) {
|
|
1013
|
+
event.preventDefault();
|
|
1014
|
+
if (_this.disposed) return;
|
|
1015
|
+
_this.contextLost = true;
|
|
1016
|
+
if (typeof _this.options.onContextLost === 'function') _this.options.onContextLost(event);
|
|
1017
|
+
};
|
|
1018
|
+
this.onContextRestored = function () {
|
|
1019
|
+
if (_this.disposed) return;
|
|
1020
|
+
_this.setupResources();
|
|
1021
|
+
_this.contextLost = false;
|
|
1022
|
+
_this.gl.viewport(0, 0, _this.canvas.width, _this.canvas.height);
|
|
1023
|
+
if (typeof _this.options.onContextRestored === 'function') _this.options.onContextRestored();
|
|
1024
|
+
};
|
|
1025
|
+
this.canvas.addEventListener('webglcontextlost', this.onContextLost, false);
|
|
1026
|
+
this.canvas.addEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
1027
|
+
}
|
|
1028
|
+
}, {
|
|
961
1029
|
key: "resize",
|
|
962
1030
|
value: function resize(width, height, dpr) {
|
|
963
1031
|
var pixelWidth = Math.max(1, Math.round(width * dpr));
|
|
@@ -972,6 +1040,7 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
972
1040
|
key: "draw",
|
|
973
1041
|
value: function draw(time, progress) {
|
|
974
1042
|
var effectImage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
1043
|
+
if (this.disposed || this.contextLost) return;
|
|
975
1044
|
var gl = this.gl;
|
|
976
1045
|
gl.useProgram(this.program);
|
|
977
1046
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
@@ -988,7 +1057,8 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
988
1057
|
gl.uniform1f(this.uniforms.motionDuration, PROGRESS_MOTION_DURATION);
|
|
989
1058
|
gl.uniform1f(this.uniforms.motionScale, this.motionScale);
|
|
990
1059
|
var hasEffect = this.effectUploaded ? 1 : 0;
|
|
991
|
-
|
|
1060
|
+
var effectWidth = effectImage && (effectImage.naturalWidth || effectImage.width || 0);
|
|
1061
|
+
if (!this.effectUploaded && effectImage && effectWidth > 0) {
|
|
992
1062
|
gl.activeTexture(gl.TEXTURE1);
|
|
993
1063
|
gl.bindTexture(gl.TEXTURE_2D, this.effectTexture);
|
|
994
1064
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
@@ -1020,7 +1090,10 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1020
1090
|
}, {
|
|
1021
1091
|
key: "dispose",
|
|
1022
1092
|
value: function dispose() {
|
|
1093
|
+
this.disposed = true;
|
|
1023
1094
|
var gl = this.gl;
|
|
1095
|
+
this.canvas.removeEventListener('webglcontextlost', this.onContextLost, false);
|
|
1096
|
+
this.canvas.removeEventListener('webglcontextrestored', this.onContextRestored, false);
|
|
1024
1097
|
gl.deleteBuffer(this.buffer);
|
|
1025
1098
|
gl.deleteTexture(this.motionTexture);
|
|
1026
1099
|
gl.deleteTexture(this.effectTexture);
|
|
@@ -1031,8 +1104,9 @@ var ProgressFlowRenderer = /*#__PURE__*/function () {
|
|
|
1031
1104
|
}]);
|
|
1032
1105
|
}();
|
|
1033
1106
|
function createProgressFlowRenderer(canvas, preset) {
|
|
1107
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1034
1108
|
try {
|
|
1035
|
-
return new ProgressFlowRenderer(canvas, preset);
|
|
1109
|
+
return new ProgressFlowRenderer(canvas, preset, options);
|
|
1036
1110
|
} catch (error) {
|
|
1037
1111
|
console.warn('[画境观屿] 进度流体 WebGL2 不可用,使用 Canvas 2D 降级。', error);
|
|
1038
1112
|
return null;
|
|
@@ -1092,50 +1166,49 @@ function createAtlas(id) {
|
|
|
1092
1166
|
context.fillRect(20, 0, 44, FRAME_HEIGHT);
|
|
1093
1167
|
context.restore();
|
|
1094
1168
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1169
|
+
|
|
1170
|
+
// A canvas is a valid TexImageSource. Keeping it directly avoids a PNG
|
|
1171
|
+
// encode -> base64 allocation -> Image decode round trip at startup.
|
|
1172
|
+
return {
|
|
1173
|
+
image: canvas,
|
|
1174
|
+
ready: true
|
|
1100
1175
|
};
|
|
1101
|
-
image.addEventListener('load', function () {
|
|
1102
|
-
state.ready = true;
|
|
1103
|
-
}, {
|
|
1104
|
-
once: true
|
|
1105
|
-
});
|
|
1106
|
-
image.addEventListener('error', function () {
|
|
1107
|
-
state.ready = false;
|
|
1108
|
-
}, {
|
|
1109
|
-
once: true
|
|
1110
|
-
});
|
|
1111
|
-
image.src = canvas.toDataURL('image/png');
|
|
1112
|
-
return state;
|
|
1113
1176
|
}
|
|
1114
1177
|
function getProgressReferenceAtlas(id) {
|
|
1115
1178
|
if (!CACHE[id]) CACHE[id] = createAtlas(id);
|
|
1116
1179
|
return CACHE[id];
|
|
1117
1180
|
}
|
|
1118
1181
|
|
|
1119
|
-
/**
|
|
1120
|
-
* Attach a WebGL2 fluid overlay to a progress capsule root.
|
|
1121
|
-
*
|
|
1122
|
-
* @param {object} params
|
|
1123
|
-
* @param {HTMLElement} params.root progress capsule root element
|
|
1124
|
-
* @param {HTMLCanvasElement} params.canvas 2D fallback canvas (kept beneath)
|
|
1125
|
-
* @param {object} params.preset progress preset
|
|
1126
|
-
* @param {() => number} params.getProgress reads the current progress value
|
|
1127
|
-
* @returns {{ update(flowTime: number): void, dispose(): void } | null}
|
|
1182
|
+
/**
|
|
1183
|
+
* Attach a WebGL2 fluid overlay to a progress capsule root.
|
|
1184
|
+
*
|
|
1185
|
+
* @param {object} params
|
|
1186
|
+
* @param {HTMLElement} params.root progress capsule root element
|
|
1187
|
+
* @param {HTMLCanvasElement} params.canvas 2D fallback canvas (kept beneath)
|
|
1188
|
+
* @param {object} params.preset progress preset
|
|
1189
|
+
* @param {() => number} params.getProgress reads the current progress value
|
|
1190
|
+
* @returns {{ update(flowTime: number): void, setDprCap(cap: number): void, dispose(): void } | null}
|
|
1128
1191
|
*/
|
|
1129
1192
|
function attachProgressFlowOverlay(_ref) {
|
|
1130
1193
|
var root = _ref.root,
|
|
1131
1194
|
canvas = _ref.canvas,
|
|
1132
1195
|
preset = _ref.preset,
|
|
1133
|
-
getProgress = _ref.getProgress
|
|
1196
|
+
getProgress = _ref.getProgress,
|
|
1197
|
+
_ref$dprCap = _ref.dprCap,
|
|
1198
|
+
dprCap = _ref$dprCap === void 0 ? 2 : _ref$dprCap,
|
|
1199
|
+
_ref$powerPreference = _ref.powerPreference,
|
|
1200
|
+
powerPreference = _ref$powerPreference === void 0 ? 'high-performance' : _ref$powerPreference,
|
|
1201
|
+
onContextLost = _ref.onContextLost,
|
|
1202
|
+
onContextRestored = _ref.onContextRestored;
|
|
1134
1203
|
var overlay = document.createElement('canvas');
|
|
1135
1204
|
overlay.className = 'hj-progress-canvas hj-progress-overlay';
|
|
1136
1205
|
overlay.setAttribute('aria-hidden', 'true');
|
|
1137
1206
|
canvas.insertAdjacentElement('afterend', overlay);
|
|
1138
|
-
var renderer = createProgressFlowRenderer(overlay, preset
|
|
1207
|
+
var renderer = createProgressFlowRenderer(overlay, preset, {
|
|
1208
|
+
powerPreference: powerPreference,
|
|
1209
|
+
onContextLost: onContextLost,
|
|
1210
|
+
onContextRestored: onContextRestored
|
|
1211
|
+
});
|
|
1139
1212
|
if (!renderer) {
|
|
1140
1213
|
overlay.remove();
|
|
1141
1214
|
return null;
|
|
@@ -1146,7 +1219,7 @@ function attachProgressFlowOverlay(_ref) {
|
|
|
1146
1219
|
var bounds = root.getBoundingClientRect();
|
|
1147
1220
|
var width = Math.max(1, bounds.width);
|
|
1148
1221
|
var height = Math.max(1, bounds.height);
|
|
1149
|
-
var dpr = Math.min(window.devicePixelRatio || 1,
|
|
1222
|
+
var dpr = Math.min(window.devicePixelRatio || 1, dprCap);
|
|
1150
1223
|
overlay.style.width = "".concat(width, "px");
|
|
1151
1224
|
overlay.style.height = "".concat(height, "px");
|
|
1152
1225
|
renderer.resize(width, height, dpr);
|
|
@@ -1170,6 +1243,10 @@ function attachProgressFlowOverlay(_ref) {
|
|
|
1170
1243
|
setColors: function setColors(colors) {
|
|
1171
1244
|
renderer.setColors(colors);
|
|
1172
1245
|
},
|
|
1246
|
+
setDprCap: function setDprCap(cap) {
|
|
1247
|
+
dprCap = cap;
|
|
1248
|
+
resize();
|
|
1249
|
+
},
|
|
1173
1250
|
dispose: function dispose() {
|
|
1174
1251
|
if (resizeObserver) resizeObserver.disconnect();
|
|
1175
1252
|
if (onWindowResize) window.removeEventListener('resize', onWindowResize);
|
|
@@ -1196,6 +1273,101 @@ function nextTick(fn) {
|
|
|
1196
1273
|
}
|
|
1197
1274
|
}
|
|
1198
1275
|
|
|
1276
|
+
function toFiniteNumber(value) {
|
|
1277
|
+
if (value == null || typeof value === 'boolean') return null;
|
|
1278
|
+
if (typeof value === 'string' && value.trim() === '') return null;
|
|
1279
|
+
var number = Number(value);
|
|
1280
|
+
return Number.isFinite(number) ? number : null;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
function normalizeRange(min, max) {
|
|
1284
|
+
var fallbackMin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
1285
|
+
var fallbackMax = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 100;
|
|
1286
|
+
var nextMin = toFiniteNumber(min);
|
|
1287
|
+
var nextMax = toFiniteNumber(max);
|
|
1288
|
+
if (nextMin === null) nextMin = fallbackMin;
|
|
1289
|
+
if (nextMax === null) nextMax = fallbackMax;
|
|
1290
|
+
if (nextMin > nextMax) {
|
|
1291
|
+
var swap = nextMin;
|
|
1292
|
+
nextMin = nextMax;
|
|
1293
|
+
nextMax = swap;
|
|
1294
|
+
}
|
|
1295
|
+
return [nextMin, nextMax];
|
|
1296
|
+
}
|
|
1297
|
+
function clampProgressValue(value, min, max) {
|
|
1298
|
+
var number = toFiniteNumber(value);
|
|
1299
|
+
if (number === null) return null;
|
|
1300
|
+
return Math.min(Math.max(number, min), max);
|
|
1301
|
+
}
|
|
1302
|
+
function normalizeProgressStep(step) {
|
|
1303
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'any';
|
|
1304
|
+
if (step === 'any' || step == null) return 'any';
|
|
1305
|
+
var increment = toFiniteNumber(step);
|
|
1306
|
+
return increment !== null && increment > 0 ? increment : fallback;
|
|
1307
|
+
}
|
|
1308
|
+
function snapProgressValue(value, min, max) {
|
|
1309
|
+
var step = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'any';
|
|
1310
|
+
var clamped = clampProgressValue(value, min, max);
|
|
1311
|
+
if (clamped === null) return null;
|
|
1312
|
+
if (step === 'any' || step == null) return clamped;
|
|
1313
|
+
var increment = normalizeProgressStep(step);
|
|
1314
|
+
if (increment === 'any') return clamped;
|
|
1315
|
+
var snapped = min + Math.round((clamped - min) / increment) * increment;
|
|
1316
|
+
return Math.min(Math.max(Number(snapped.toFixed(12)), min), max);
|
|
1317
|
+
}
|
|
1318
|
+
function progressRatio(value, min, max) {
|
|
1319
|
+
var range = max - min;
|
|
1320
|
+
if (!Number.isFinite(range) || range <= 0) return 0;
|
|
1321
|
+
return Math.min(Math.max((value - min) / range, 0), 1);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
function normalizeFps(value) {
|
|
1325
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 60;
|
|
1326
|
+
var fps = Number(value);
|
|
1327
|
+
if (!Number.isFinite(fps)) return fallback;
|
|
1328
|
+
return Math.min(60, Math.max(1, fps));
|
|
1329
|
+
}
|
|
1330
|
+
function createFrameGate() {
|
|
1331
|
+
var initialFps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 60;
|
|
1332
|
+
var fps = normalizeFps(initialFps);
|
|
1333
|
+
var elapsed = 0;
|
|
1334
|
+
return {
|
|
1335
|
+
shouldDraw: function shouldDraw(delta) {
|
|
1336
|
+
elapsed += delta;
|
|
1337
|
+
var interval = 1 / fps;
|
|
1338
|
+
if (elapsed + 0.0001 < interval) return false;
|
|
1339
|
+
elapsed %= interval;
|
|
1340
|
+
return true;
|
|
1341
|
+
},
|
|
1342
|
+
setFps: function setFps(value) {
|
|
1343
|
+
fps = normalizeFps(value, fps);
|
|
1344
|
+
elapsed = 0;
|
|
1345
|
+
return fps;
|
|
1346
|
+
},
|
|
1347
|
+
getFps: function getFps() {
|
|
1348
|
+
return fps;
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
function createReducedMotionPreference(enabled, onChange) {
|
|
1353
|
+
var query = enabled && typeof matchMedia !== 'undefined' ? matchMedia('(prefers-reduced-motion: reduce)') : null;
|
|
1354
|
+
var notify = function notify() {
|
|
1355
|
+
if (typeof onChange === 'function') onChange(Boolean(query && query.matches));
|
|
1356
|
+
};
|
|
1357
|
+
if (query) {
|
|
1358
|
+
if (typeof query.addEventListener === 'function') query.addEventListener('change', notify);else if (typeof query.addListener === 'function') query.addListener(notify);
|
|
1359
|
+
}
|
|
1360
|
+
return {
|
|
1361
|
+
matches: function matches() {
|
|
1362
|
+
return Boolean(query && query.matches);
|
|
1363
|
+
},
|
|
1364
|
+
dispose: function dispose() {
|
|
1365
|
+
if (!query) return;
|
|
1366
|
+
if (typeof query.removeEventListener === 'function') query.removeEventListener('change', notify);else if (typeof query.removeListener === 'function') query.removeListener(notify);
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1199
1371
|
var clamp = function clamp(value, min, max) {
|
|
1200
1372
|
return Math.min(Math.max(value, min), max);
|
|
1201
1373
|
};
|
|
@@ -1222,9 +1394,6 @@ function interpolate(template, values) {
|
|
|
1222
1394
|
return values[key] !== undefined ? values[key] : '';
|
|
1223
1395
|
});
|
|
1224
1396
|
}
|
|
1225
|
-
function prefersReducedMotion() {
|
|
1226
|
-
return typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
1227
|
-
}
|
|
1228
1397
|
var FLOW_PROFILES = {
|
|
1229
1398
|
'model-training': {
|
|
1230
1399
|
cycles: [0.98, 3.05, 5.45],
|
|
@@ -1285,8 +1454,6 @@ var FLOW_PROFILES = {
|
|
|
1285
1454
|
var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
1286
1455
|
function ProgressCapsuleController(_ref) {
|
|
1287
1456
|
var _options$valueSuffix,
|
|
1288
|
-
_options$min,
|
|
1289
|
-
_options$max,
|
|
1290
1457
|
_options$value,
|
|
1291
1458
|
_this = this;
|
|
1292
1459
|
var root = _ref.root,
|
|
@@ -1308,11 +1475,18 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1308
1475
|
this.dirty = dirty;
|
|
1309
1476
|
this.valueSuffix = (_options$valueSuffix = options.valueSuffix) !== null && _options$valueSuffix !== void 0 ? _options$valueSuffix : copy.valueSuffix;
|
|
1310
1477
|
this.profile = preset.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
this.
|
|
1478
|
+
var _normalizeRange = normalizeRange(options.min, options.max);
|
|
1479
|
+
var _normalizeRange2 = _slicedToArray(_normalizeRange, 2);
|
|
1480
|
+
this.min = _normalizeRange2[0];
|
|
1481
|
+
this.max = _normalizeRange2[1];
|
|
1482
|
+
this.step = normalizeProgressStep(options.step);
|
|
1483
|
+
this.precision = Number.isInteger(Number(options.precision)) ? clamp(Number(options.precision), 0, 20) : 0;
|
|
1484
|
+
this.formatValue = typeof options.formatValue === 'function' ? options.formatValue : null;
|
|
1485
|
+
this.direction = options.direction === 'rtl' ? 'rtl' : 'ltr';
|
|
1486
|
+
this.dprCap = effectiveDprCap(options.quality, options.renderScale);
|
|
1314
1487
|
this.ctx = canvas.getContext('2d');
|
|
1315
|
-
this.value =
|
|
1488
|
+
this.value = snapProgressValue((_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : preset.initialProgress, this.min, this.max, this.step);
|
|
1489
|
+
if (this.value === null) this.value = clamp(preset.initialProgress, this.min, this.max);
|
|
1316
1490
|
this.dragging = false;
|
|
1317
1491
|
this.webglActive = false;
|
|
1318
1492
|
this.flowTime = stringSeed(preset.id) * 31;
|
|
@@ -1322,10 +1496,12 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1322
1496
|
this.width = 0;
|
|
1323
1497
|
this.height = 0;
|
|
1324
1498
|
this.handlers = {};
|
|
1325
|
-
this.
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1499
|
+
this.onResize = function () {
|
|
1500
|
+
_this.resizeCanvas();
|
|
1501
|
+
if (typeof _this.options.onResize === 'function') _this.options.onResize();
|
|
1502
|
+
};
|
|
1503
|
+
this.resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(this.onResize) : null;
|
|
1504
|
+
if (this.resizeObserver) this.resizeObserver.observe(this.root);else window.addEventListener('resize', this.onResize);
|
|
1329
1505
|
this.suppressEvents = true;
|
|
1330
1506
|
this.setProgress(this.value, 'init');
|
|
1331
1507
|
this.suppressEvents = false;
|
|
@@ -1338,16 +1514,37 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1338
1514
|
this.randomState = Math.imul(this.randomState, 1664525) + 1013904223 >>> 0;
|
|
1339
1515
|
return this.randomState / 4294967296;
|
|
1340
1516
|
}
|
|
1517
|
+
}, {
|
|
1518
|
+
key: "displayText",
|
|
1519
|
+
value: function displayText() {
|
|
1520
|
+
if (this.formatValue) {
|
|
1521
|
+
return String(this.formatValue(this.value, {
|
|
1522
|
+
min: this.min,
|
|
1523
|
+
max: this.max,
|
|
1524
|
+
suffix: this.valueSuffix
|
|
1525
|
+
}));
|
|
1526
|
+
}
|
|
1527
|
+
var number = this.precision > 0 ? this.value.toFixed(this.precision) : String(Math.round(this.value));
|
|
1528
|
+
return "".concat(number).concat(this.valueSuffix);
|
|
1529
|
+
}
|
|
1530
|
+
}, {
|
|
1531
|
+
key: "syncValueDom",
|
|
1532
|
+
value: function syncValueDom() {
|
|
1533
|
+
var text = this.displayText();
|
|
1534
|
+
this.root.style.setProperty('--progress', this.value.toFixed(2));
|
|
1535
|
+
this.root.style.setProperty('--progress-ratio', progressRatio(this.value, this.min, this.max).toFixed(4));
|
|
1536
|
+
this.root.setAttribute('aria-valuenow', String(this.value));
|
|
1537
|
+
this.root.setAttribute('aria-valuetext', text);
|
|
1538
|
+
if (this.valueElement) this.valueElement.textContent = text;
|
|
1539
|
+
}
|
|
1341
1540
|
}, {
|
|
1342
1541
|
key: "setProgress",
|
|
1343
1542
|
value: function setProgress(nextValue) {
|
|
1344
1543
|
var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'auto';
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
this.
|
|
1348
|
-
this.
|
|
1349
|
-
this.root.setAttribute('aria-valuetext', "".concat(rounded).concat(this.valueSuffix));
|
|
1350
|
-
if (this.valueElement) this.valueElement.textContent = "".concat(rounded).concat(this.valueSuffix);
|
|
1544
|
+
var next = snapProgressValue(nextValue, this.min, this.max, this.step);
|
|
1545
|
+
if (next === null) return false;
|
|
1546
|
+
this.value = next;
|
|
1547
|
+
this.syncValueDom();
|
|
1351
1548
|
if (!this.suppressEvents) {
|
|
1352
1549
|
if (this.dirty) this.dirty.value = true;
|
|
1353
1550
|
this.emitter.emit('change', {
|
|
@@ -1355,19 +1552,58 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1355
1552
|
source: source
|
|
1356
1553
|
});
|
|
1357
1554
|
}
|
|
1555
|
+
return true;
|
|
1358
1556
|
}
|
|
1359
1557
|
}, {
|
|
1360
1558
|
key: "setValueSuffix",
|
|
1361
1559
|
value: function setValueSuffix(suffix) {
|
|
1560
|
+
if (this.dirty) this.dirty.valueSuffix = true;
|
|
1362
1561
|
this.valueSuffix = String(suffix == null ? '' : suffix);
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1562
|
+
this.syncValueDom();
|
|
1563
|
+
return this;
|
|
1564
|
+
}
|
|
1565
|
+
}, {
|
|
1566
|
+
key: "setStep",
|
|
1567
|
+
value: function setStep(step) {
|
|
1568
|
+
var nextStep = normalizeProgressStep(step, this.step);
|
|
1569
|
+
if (nextStep === this.step) return this;
|
|
1570
|
+
if (this.dirty) this.dirty.step = true;
|
|
1571
|
+
this.step = nextStep;
|
|
1572
|
+
var next = snapProgressValue(this.value, this.min, this.max, this.step);
|
|
1573
|
+
if (next !== null && next !== this.value) this.setProgress(next, 'prop');
|
|
1574
|
+
return this;
|
|
1575
|
+
}
|
|
1576
|
+
}, {
|
|
1577
|
+
key: "setPrecision",
|
|
1578
|
+
value: function setPrecision(precision) {
|
|
1579
|
+
var value = Number(precision);
|
|
1580
|
+
if (!Number.isInteger(value) || value < 0 || value > 20) return this;
|
|
1581
|
+
if (this.dirty) this.dirty.precision = true;
|
|
1582
|
+
this.precision = value;
|
|
1583
|
+
this.syncValueDom();
|
|
1584
|
+
return this;
|
|
1585
|
+
}
|
|
1586
|
+
}, {
|
|
1587
|
+
key: "setFormatValue",
|
|
1588
|
+
value: function setFormatValue(formatter) {
|
|
1589
|
+
if (formatter != null && typeof formatter !== 'function') return this;
|
|
1590
|
+
if (this.dirty) this.dirty.formatValue = true;
|
|
1591
|
+
this.formatValue = formatter || null;
|
|
1592
|
+
this.syncValueDom();
|
|
1593
|
+
return this;
|
|
1594
|
+
}
|
|
1595
|
+
}, {
|
|
1596
|
+
key: "setDirection",
|
|
1597
|
+
value: function setDirection(direction) {
|
|
1598
|
+
if (this.dirty) this.dirty.direction = true;
|
|
1599
|
+
this.direction = direction === 'rtl' ? 'rtl' : 'ltr';
|
|
1600
|
+
this.root.dataset.direction = this.direction;
|
|
1366
1601
|
return this;
|
|
1367
1602
|
}
|
|
1368
1603
|
}, {
|
|
1369
1604
|
key: "setShowValue",
|
|
1370
1605
|
value: function setShowValue(show) {
|
|
1606
|
+
if (this.dirty) this.dirty.showValue = true;
|
|
1371
1607
|
if (this.valueElement) this.valueElement.hidden = show === false;
|
|
1372
1608
|
return this;
|
|
1373
1609
|
}
|
|
@@ -1532,15 +1768,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1532
1768
|
}, {
|
|
1533
1769
|
key: "setRange",
|
|
1534
1770
|
value: function setRange(min, max) {
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
this.min
|
|
1541
|
-
this.
|
|
1542
|
-
|
|
1543
|
-
if (clamped !== this.value) this.setProgress(clamped, 'prop');
|
|
1771
|
+
var nextRange = normalizeRange(min, max, this.min, this.max);
|
|
1772
|
+
this.min = nextRange[0];
|
|
1773
|
+
this.max = nextRange[1];
|
|
1774
|
+
this.root.setAttribute('aria-valuemin', String(this.min));
|
|
1775
|
+
this.root.setAttribute('aria-valuemax', String(this.max));
|
|
1776
|
+
var next = snapProgressValue(this.value, this.min, this.max, this.step);
|
|
1777
|
+
if (next !== this.value) this.setProgress(next, 'prop');else this.syncValueDom();
|
|
1778
|
+
return this;
|
|
1544
1779
|
}
|
|
1545
1780
|
}, {
|
|
1546
1781
|
key: "drawReferenceFlow",
|
|
@@ -1665,14 +1900,45 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1665
1900
|
value: function updateFromPointer(event) {
|
|
1666
1901
|
var bounds = this.root.getBoundingClientRect();
|
|
1667
1902
|
var ratio = bounds.width > 0 ? (event.clientX - bounds.left) / bounds.width : 0;
|
|
1903
|
+
if (this.direction === 'rtl') ratio = 1 - ratio;
|
|
1668
1904
|
this.setProgress(this.min + ratio * (this.max - this.min), 'drag');
|
|
1669
1905
|
}
|
|
1906
|
+
}, {
|
|
1907
|
+
key: "onKeyDown",
|
|
1908
|
+
value: function onKeyDown(event) {
|
|
1909
|
+
var range = this.max - this.min;
|
|
1910
|
+
var configuredStep = Number(this.step);
|
|
1911
|
+
var step = Number.isFinite(configuredStep) && configuredStep > 0 ? configuredStep : Math.max(range / 100, 1e-7);
|
|
1912
|
+
var direction = this.direction === 'rtl' ? -1 : 1;
|
|
1913
|
+
var aliases = {
|
|
1914
|
+
Left: 'ArrowLeft',
|
|
1915
|
+
Right: 'ArrowRight',
|
|
1916
|
+
Up: 'ArrowUp',
|
|
1917
|
+
Down: 'ArrowDown'
|
|
1918
|
+
};
|
|
1919
|
+
var keyCodes = {
|
|
1920
|
+
35: 'End',
|
|
1921
|
+
36: 'Home',
|
|
1922
|
+
33: 'PageUp',
|
|
1923
|
+
34: 'PageDown',
|
|
1924
|
+
37: 'ArrowLeft',
|
|
1925
|
+
38: 'ArrowUp',
|
|
1926
|
+
39: 'ArrowRight',
|
|
1927
|
+
40: 'ArrowDown'
|
|
1928
|
+
};
|
|
1929
|
+
var key = aliases[event.key] || event.key || keyCodes[event.keyCode];
|
|
1930
|
+
var next = null;
|
|
1931
|
+
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;
|
|
1932
|
+
if (next === null) return;
|
|
1933
|
+
event.preventDefault();
|
|
1934
|
+
this.setProgress(next, 'keyboard');
|
|
1935
|
+
}
|
|
1670
1936
|
}, {
|
|
1671
1937
|
key: "beginDrag",
|
|
1672
1938
|
value: function beginDrag(event) {
|
|
1673
1939
|
if (event.button !== undefined && event.button !== 0) return;
|
|
1674
1940
|
event.preventDefault();
|
|
1675
|
-
// preventDefault
|
|
1941
|
+
// preventDefault 会吞掉点击聚焦,主动聚焦让根节点获得无障碍焦点。
|
|
1676
1942
|
try {
|
|
1677
1943
|
this.root.focus({
|
|
1678
1944
|
preventScroll: true
|
|
@@ -1754,6 +2020,12 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1754
2020
|
this.root.addEventListener('pointerup', this.handlers.pointerup);
|
|
1755
2021
|
this.root.addEventListener('pointercancel', this.handlers.pointercancel);
|
|
1756
2022
|
}
|
|
2023
|
+
if (this.options.keyboard !== false) {
|
|
2024
|
+
this.handlers.keydown = function (event) {
|
|
2025
|
+
return _this3.onKeyDown(event);
|
|
2026
|
+
};
|
|
2027
|
+
this.root.addEventListener('keydown', this.handlers.keydown);
|
|
2028
|
+
}
|
|
1757
2029
|
}
|
|
1758
2030
|
}, {
|
|
1759
2031
|
key: "update",
|
|
@@ -1772,20 +2044,19 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1772
2044
|
key: "randomize",
|
|
1773
2045
|
value: function randomize() {
|
|
1774
2046
|
this.flowTime = this.random() * 40;
|
|
2047
|
+
return this.flowTime;
|
|
1775
2048
|
}
|
|
1776
2049
|
}, {
|
|
1777
2050
|
key: "setColors",
|
|
1778
2051
|
value: function setColors(colors) {
|
|
1779
2052
|
if (!Array.isArray(colors) || colors.length !== 4) return;
|
|
1780
|
-
this.preset =
|
|
1781
|
-
colors: colors
|
|
1782
|
-
});
|
|
2053
|
+
this.preset.colors = _toConsumableArray(colors);
|
|
1783
2054
|
}
|
|
1784
2055
|
}, {
|
|
1785
2056
|
key: "dispose",
|
|
1786
2057
|
value: function dispose() {
|
|
1787
2058
|
if (this._dragRaf) cancelAnimationFrame(this._dragRaf);
|
|
1788
|
-
if (this.resizeObserver) this.resizeObserver.disconnect();else window.removeEventListener('resize', this.
|
|
2059
|
+
if (this.resizeObserver) this.resizeObserver.disconnect();else window.removeEventListener('resize', this.onResize);
|
|
1789
2060
|
for (var _i = 0, _Object$keys = Object.keys(this.handlers); _i < _Object$keys.length; _i++) {
|
|
1790
2061
|
var name = _Object$keys[_i];
|
|
1791
2062
|
var handler = this.handlers[name];
|
|
@@ -1796,15 +2067,16 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
|
|
|
1796
2067
|
}]);
|
|
1797
2068
|
}();
|
|
1798
2069
|
|
|
1799
|
-
/**
|
|
2070
|
+
/**
|
|
1800
2071
|
* Mount a fluid progress capsule into `container`.
|
|
1801
2072
|
*
|
|
1802
|
-
* Options: preset (
|
|
1803
|
-
* draggable,
|
|
2073
|
+
* Options: preset (literary name), width, height, value/modelValue, min, max,
|
|
2074
|
+
* step, draggable, keyboard, direction, precision/formatValue, colors,
|
|
2075
|
+
* edgeStyle, textRatio (0-100, text region
|
|
1804
2076
|
* width in percent), text (HTML string or DOM nodes for the text slot),
|
|
1805
2077
|
* colorContent (HTML string or DOM nodes for the color slot),
|
|
1806
|
-
* showValue (show/hide the right-side percentage), quality,
|
|
1807
|
-
* respectReducedMotion, cssVars.
|
|
2078
|
+
* showValue (show/hide the right-side percentage), quality, renderScale,
|
|
2079
|
+
* powerPreference, fps, paused/static, respectReducedMotion, cssVars.
|
|
1808
2080
|
*/
|
|
1809
2081
|
function createProgressCapsule(container) {
|
|
1810
2082
|
var _options$preset, _merged$min, _merged$max;
|
|
@@ -1814,14 +2086,20 @@ function createProgressCapsule(container) {
|
|
|
1814
2086
|
}
|
|
1815
2087
|
var preset = _objectSpread2({}, getPreset('progress', (_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : '星火'));
|
|
1816
2088
|
var merged = normalizeOptions(DEFAULTS.progress, preset, options);
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
var normalizedColors = merged.colors.map(normalizeColor);
|
|
1823
|
-
if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
1824
|
-
|
|
2089
|
+
var _normalizeRange3 = normalizeRange(merged.min, merged.max);
|
|
2090
|
+
var _normalizeRange4 = _slicedToArray(_normalizeRange3, 2);
|
|
2091
|
+
merged.min = _normalizeRange4[0];
|
|
2092
|
+
merged.max = _normalizeRange4[1];
|
|
2093
|
+
if (merged.modelValue !== undefined) merged.value = merged.modelValue;
|
|
2094
|
+
var normalizedColors = Array.isArray(merged.colors) ? merged.colors.map(normalizeColor) : [];
|
|
2095
|
+
if (normalizedColors.length === 4 && normalizedColors.every(Boolean)) preset.colors = normalizedColors;
|
|
2096
|
+
var initialEdgeStyle = merged.edgeStyle === 'tide' || merged.edgeStyle === 'flow' ? merged.edgeStyle : preset.edgeStyle;
|
|
2097
|
+
preset.edgeStyle = initialEdgeStyle;
|
|
2098
|
+
merged.edgeStyle = initialEdgeStyle;
|
|
2099
|
+
merged.colors = _toConsumableArray(preset.colors);
|
|
2100
|
+
var optionColors = Array.isArray(options.colors) ? options.colors.map(normalizeColor) : [];
|
|
2101
|
+
var colorOverride = optionColors.length === 4 && optionColors.every(Boolean) ? _toConsumableArray(optionColors) : null;
|
|
2102
|
+
var edgeStyleOverride = options.edgeStyle === 'flow' || options.edgeStyle === 'tide' ? merged.edgeStyle : null;
|
|
1825
2103
|
var copy = COPY;
|
|
1826
2104
|
var customLabel = typeof options.label === 'string' && options.label ? options.label : null;
|
|
1827
2105
|
// Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
|
|
@@ -1830,18 +2108,31 @@ function createProgressCapsule(container) {
|
|
|
1830
2108
|
var readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
|
|
1831
2109
|
var locked = disabled || readonly;
|
|
1832
2110
|
var effectiveDraggable = locked ? false : merged.draggable !== false;
|
|
2111
|
+
var effectiveKeyboard = locked ? false : merged.keyboard !== false;
|
|
1833
2112
|
var dirty = {
|
|
1834
2113
|
preset: false,
|
|
1835
2114
|
colors: false,
|
|
1836
2115
|
textRatio: false,
|
|
1837
2116
|
cssVars: false,
|
|
1838
2117
|
edgeStyle: false,
|
|
1839
|
-
value: false
|
|
2118
|
+
value: false,
|
|
2119
|
+
step: false,
|
|
2120
|
+
precision: false,
|
|
2121
|
+
formatValue: false,
|
|
2122
|
+
direction: false,
|
|
2123
|
+
showValue: false,
|
|
2124
|
+
valueSuffix: false,
|
|
2125
|
+
quality: false,
|
|
2126
|
+
renderScale: false,
|
|
2127
|
+
paused: false,
|
|
2128
|
+
static: false,
|
|
2129
|
+
fps: false
|
|
1840
2130
|
};
|
|
1841
2131
|
var root = document.createElement('div');
|
|
1842
2132
|
root.className = 'hj-capsule-root hj-progress-root';
|
|
1843
2133
|
root.setAttribute('role', 'slider');
|
|
1844
2134
|
root.setAttribute('data-draggable', String(effectiveDraggable));
|
|
2135
|
+
root.dataset.direction = merged.direction === 'rtl' ? 'rtl' : 'ltr';
|
|
1845
2136
|
if (disabled) {
|
|
1846
2137
|
root.setAttribute('aria-disabled', 'true');
|
|
1847
2138
|
root.classList.add('is-disabled');
|
|
@@ -1850,7 +2141,8 @@ function createProgressCapsule(container) {
|
|
|
1850
2141
|
root.setAttribute('aria-readonly', 'true');
|
|
1851
2142
|
root.classList.add('is-readonly');
|
|
1852
2143
|
}
|
|
1853
|
-
|
|
2144
|
+
root.setAttribute('tabindex', locked ? '-1' : effectiveKeyboard ? '0' : '-1');
|
|
2145
|
+
root.setAttribute('aria-orientation', 'horizontal');
|
|
1854
2146
|
root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
|
|
1855
2147
|
root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
|
|
1856
2148
|
root.setAttribute('aria-valuenow', String(preset.initialProgress));
|
|
@@ -1905,8 +2197,22 @@ function createProgressCapsule(container) {
|
|
|
1905
2197
|
root.appendChild(valueElement);
|
|
1906
2198
|
container.appendChild(root);
|
|
1907
2199
|
var emitter = createEmitter();
|
|
1908
|
-
var
|
|
2200
|
+
var manuallyPaused = merged.paused === true;
|
|
2201
|
+
var reducedPaused = false;
|
|
2202
|
+
var staticMode = merged.static === true;
|
|
2203
|
+
var contextLost = false;
|
|
1909
2204
|
var disposed = false;
|
|
2205
|
+
var renderOnce = function renderOnce() {};
|
|
2206
|
+
var onContextLost = function onContextLost() {
|
|
2207
|
+
contextLost = true;
|
|
2208
|
+
emitter.emit('contextlost', {});
|
|
2209
|
+
};
|
|
2210
|
+
var onContextRestored = function onContextRestored() {
|
|
2211
|
+
contextLost = false;
|
|
2212
|
+
emitter.emit('contextrestored', {});
|
|
2213
|
+
renderOnce();
|
|
2214
|
+
wakeScheduler();
|
|
2215
|
+
};
|
|
1910
2216
|
var applySize = function applySize() {
|
|
1911
2217
|
root.style.width = parseSize(merged.width);
|
|
1912
2218
|
root.style.height = parseSize(merged.height);
|
|
@@ -1927,7 +2233,11 @@ function createProgressCapsule(container) {
|
|
|
1927
2233
|
preset: preset,
|
|
1928
2234
|
emitter: emitter,
|
|
1929
2235
|
options: _objectSpread2(_objectSpread2({}, merged), {}, {
|
|
1930
|
-
draggable: effectiveDraggable
|
|
2236
|
+
draggable: effectiveDraggable,
|
|
2237
|
+
keyboard: effectiveKeyboard,
|
|
2238
|
+
onResize: function onResize() {
|
|
2239
|
+
if (manuallyPaused || reducedPaused || staticMode) renderOnce();
|
|
2240
|
+
}
|
|
1931
2241
|
}),
|
|
1932
2242
|
copy: copy,
|
|
1933
2243
|
dirty: dirty
|
|
@@ -1939,8 +2249,12 @@ function createProgressCapsule(container) {
|
|
|
1939
2249
|
canvas: canvas,
|
|
1940
2250
|
preset: preset,
|
|
1941
2251
|
getProgress: function getProgress() {
|
|
1942
|
-
return controller.value;
|
|
1943
|
-
}
|
|
2252
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
2253
|
+
},
|
|
2254
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
2255
|
+
powerPreference: merged.powerPreference,
|
|
2256
|
+
onContextLost: onContextLost,
|
|
2257
|
+
onContextRestored: onContextRestored
|
|
1944
2258
|
});
|
|
1945
2259
|
}
|
|
1946
2260
|
if (overlay) controller.webglActive = true;else if (merged.renderer !== 'canvas2d') {
|
|
@@ -1951,17 +2265,34 @@ function createProgressCapsule(container) {
|
|
|
1951
2265
|
});
|
|
1952
2266
|
});
|
|
1953
2267
|
}
|
|
1954
|
-
var visibility = createVisibilityGuard(root);
|
|
2268
|
+
var visibility = createVisibilityGuard(root, wakeScheduler);
|
|
2269
|
+
var motionPreference = createReducedMotionPreference(merged.respectReducedMotion, function (matches) {
|
|
2270
|
+
reducedPaused = matches;
|
|
2271
|
+
if (matches) renderOnce();else wakeScheduler();
|
|
2272
|
+
});
|
|
2273
|
+
reducedPaused = motionPreference.matches();
|
|
2274
|
+
var isMotionPaused = function isMotionPaused() {
|
|
2275
|
+
return manuallyPaused || reducedPaused || staticMode || contextLost;
|
|
2276
|
+
};
|
|
1955
2277
|
var flowTime = 0;
|
|
2278
|
+
var frameGate = createFrameGate(merged.fps);
|
|
2279
|
+
renderOnce = function renderOnce() {
|
|
2280
|
+
controller.draw();
|
|
2281
|
+
if (overlay) overlay.update(flowTime);
|
|
2282
|
+
};
|
|
2283
|
+
renderOnce();
|
|
2284
|
+
var offPausedChange = emitter.on('change', function () {
|
|
2285
|
+
if (isMotionPaused()) renderOnce();
|
|
2286
|
+
});
|
|
1956
2287
|
var unsubscribe = subscribeScheduler(function (delta, now) {
|
|
1957
2288
|
flowTime += delta;
|
|
1958
2289
|
controller.update(delta, false);
|
|
1959
|
-
if (
|
|
2290
|
+
if (frameGate.shouldDraw(delta)) {
|
|
1960
2291
|
controller.draw();
|
|
1961
2292
|
if (overlay) overlay.update(flowTime);
|
|
1962
2293
|
}
|
|
1963
2294
|
}, function () {
|
|
1964
|
-
return
|
|
2295
|
+
return isMotionPaused() || !visibility.isVisible();
|
|
1965
2296
|
});
|
|
1966
2297
|
nextTick(function () {
|
|
1967
2298
|
if (disposed) return;
|
|
@@ -1988,32 +2319,41 @@ function createProgressCapsule(container) {
|
|
|
1988
2319
|
},
|
|
1989
2320
|
setRange: function setRange(min, max) {
|
|
1990
2321
|
controller.setRange(min, max);
|
|
2322
|
+
if (isMotionPaused()) renderOnce();
|
|
1991
2323
|
return this;
|
|
1992
2324
|
},
|
|
1993
2325
|
setPreset: function setPreset(ref) {
|
|
1994
2326
|
var next = getPreset('progress', ref);
|
|
1995
2327
|
dirty.preset = true;
|
|
1996
2328
|
Object.assign(preset, next);
|
|
2329
|
+
if (colorOverride) preset.colors = _toConsumableArray(colorOverride);
|
|
2330
|
+
if (edgeStyleOverride) preset.edgeStyle = edgeStyleOverride;
|
|
1997
2331
|
var nextColors = preset.colors.map(normalizeColor);
|
|
1998
2332
|
if (nextColors.every(Boolean)) preset.colors = nextColors;
|
|
1999
2333
|
controller.preset = preset;
|
|
2000
|
-
controller.profile =
|
|
2334
|
+
controller.profile = preset.edgeStyle === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
2001
2335
|
controller.flowTime = stringSeed(next.id) * 31;
|
|
2002
2336
|
controller.seed = stringSeed("".concat(next.id, "-reference")) * Math.PI * 2;
|
|
2003
2337
|
syncDom();
|
|
2004
2338
|
if (overlay) {
|
|
2005
2339
|
overlay.dispose();
|
|
2340
|
+
contextLost = false;
|
|
2006
2341
|
overlay = attachProgressFlowOverlay({
|
|
2007
2342
|
root: root,
|
|
2008
2343
|
canvas: canvas,
|
|
2009
2344
|
preset: preset,
|
|
2010
2345
|
getProgress: function getProgress() {
|
|
2011
|
-
return controller.value;
|
|
2012
|
-
}
|
|
2346
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
2347
|
+
},
|
|
2348
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
2349
|
+
powerPreference: merged.powerPreference,
|
|
2350
|
+
onContextLost: onContextLost,
|
|
2351
|
+
onContextRestored: onContextRestored
|
|
2013
2352
|
});
|
|
2014
2353
|
}
|
|
2015
2354
|
controller.webglActive = Boolean(overlay);
|
|
2016
2355
|
controller.resizeCanvas();
|
|
2356
|
+
if (isMotionPaused()) renderOnce();
|
|
2017
2357
|
emitter.emit('presetchange', {
|
|
2018
2358
|
preset: _objectSpread2({}, preset)
|
|
2019
2359
|
});
|
|
@@ -2023,21 +2363,28 @@ function createProgressCapsule(container) {
|
|
|
2023
2363
|
var value = String(edgeStyle || '').toLowerCase();
|
|
2024
2364
|
if (value !== 'flow' && value !== 'tide') return this;
|
|
2025
2365
|
dirty.edgeStyle = true;
|
|
2366
|
+
edgeStyleOverride = value;
|
|
2026
2367
|
preset.edgeStyle = value;
|
|
2027
2368
|
controller.profile = value === 'tide' ? FLOW_PROFILES.tide : FLOW_PROFILES[preset.id] || FLOW_PROFILES['visual-training'];
|
|
2028
2369
|
if (overlay) {
|
|
2029
2370
|
overlay.dispose();
|
|
2371
|
+
contextLost = false;
|
|
2030
2372
|
overlay = attachProgressFlowOverlay({
|
|
2031
2373
|
root: root,
|
|
2032
2374
|
canvas: canvas,
|
|
2033
2375
|
preset: preset,
|
|
2034
2376
|
getProgress: function getProgress() {
|
|
2035
|
-
return controller.value;
|
|
2036
|
-
}
|
|
2377
|
+
return progressRatio(controller.value, controller.min, controller.max) * 100;
|
|
2378
|
+
},
|
|
2379
|
+
dprCap: effectiveDprCap(merged.quality, merged.renderScale),
|
|
2380
|
+
powerPreference: merged.powerPreference,
|
|
2381
|
+
onContextLost: onContextLost,
|
|
2382
|
+
onContextRestored: onContextRestored
|
|
2037
2383
|
});
|
|
2038
2384
|
}
|
|
2039
2385
|
controller.webglActive = Boolean(overlay);
|
|
2040
2386
|
controller.resizeCanvas();
|
|
2387
|
+
if (isMotionPaused()) renderOnce();
|
|
2041
2388
|
return this;
|
|
2042
2389
|
},
|
|
2043
2390
|
setText: function setText(content) {
|
|
@@ -2075,6 +2422,22 @@ function createProgressCapsule(container) {
|
|
|
2075
2422
|
controller.setValueSuffix(suffix);
|
|
2076
2423
|
return this;
|
|
2077
2424
|
},
|
|
2425
|
+
setStep: function setStep(step) {
|
|
2426
|
+
controller.setStep(step);
|
|
2427
|
+
return this;
|
|
2428
|
+
},
|
|
2429
|
+
setPrecision: function setPrecision(precision) {
|
|
2430
|
+
controller.setPrecision(precision);
|
|
2431
|
+
return this;
|
|
2432
|
+
},
|
|
2433
|
+
setFormatValue: function setFormatValue(formatter) {
|
|
2434
|
+
controller.setFormatValue(formatter);
|
|
2435
|
+
return this;
|
|
2436
|
+
},
|
|
2437
|
+
setDirection: function setDirection(direction) {
|
|
2438
|
+
controller.setDirection(direction);
|
|
2439
|
+
return this;
|
|
2440
|
+
},
|
|
2078
2441
|
setShowValue: function setShowValue(show) {
|
|
2079
2442
|
controller.setShowValue(show);
|
|
2080
2443
|
return this;
|
|
@@ -2085,9 +2448,12 @@ function createProgressCapsule(container) {
|
|
|
2085
2448
|
return !color;
|
|
2086
2449
|
})) return this;
|
|
2087
2450
|
dirty.colors = true;
|
|
2451
|
+
colorOverride = _toConsumableArray(next);
|
|
2452
|
+
preset.colors = _toConsumableArray(next);
|
|
2088
2453
|
controller.setColors(next);
|
|
2089
2454
|
if (overlay) overlay.setColors(next);
|
|
2090
2455
|
controller.resizeCanvas();
|
|
2456
|
+
if (isMotionPaused()) renderOnce();
|
|
2091
2457
|
return this;
|
|
2092
2458
|
},
|
|
2093
2459
|
setSize: function setSize(width, height) {
|
|
@@ -2101,30 +2467,68 @@ function createProgressCapsule(container) {
|
|
|
2101
2467
|
}
|
|
2102
2468
|
applySize();
|
|
2103
2469
|
controller.resizeCanvas();
|
|
2470
|
+
if (isMotionPaused()) renderOnce();
|
|
2104
2471
|
return this;
|
|
2105
2472
|
},
|
|
2106
2473
|
randomize: function randomize() {
|
|
2107
|
-
controller.randomize();
|
|
2474
|
+
flowTime = controller.randomize();
|
|
2475
|
+
if (isMotionPaused()) renderOnce();
|
|
2108
2476
|
return this;
|
|
2109
2477
|
},
|
|
2110
2478
|
pause: function pause() {
|
|
2111
|
-
paused = true;
|
|
2479
|
+
dirty.paused = true;
|
|
2480
|
+
manuallyPaused = true;
|
|
2481
|
+
renderOnce();
|
|
2112
2482
|
return this;
|
|
2113
2483
|
},
|
|
2114
2484
|
resume: function resume() {
|
|
2115
|
-
paused =
|
|
2485
|
+
dirty.paused = true;
|
|
2486
|
+
manuallyPaused = false;
|
|
2487
|
+
wakeScheduler();
|
|
2488
|
+
return this;
|
|
2489
|
+
},
|
|
2490
|
+
setPaused: function setPaused(value) {
|
|
2491
|
+
return value ? this.pause() : this.resume();
|
|
2492
|
+
},
|
|
2493
|
+
setStatic: function setStatic(value) {
|
|
2494
|
+
dirty.static = true;
|
|
2495
|
+
staticMode = value === true;
|
|
2496
|
+
merged.static = staticMode;
|
|
2497
|
+
if (staticMode) renderOnce();else wakeScheduler();
|
|
2498
|
+
return this;
|
|
2499
|
+
},
|
|
2500
|
+
setFps: function setFps(fps) {
|
|
2501
|
+
dirty.fps = true;
|
|
2502
|
+
merged.fps = frameGate.setFps(fps);
|
|
2503
|
+
wakeScheduler();
|
|
2116
2504
|
return this;
|
|
2117
2505
|
},
|
|
2118
2506
|
setQuality: function setQuality(quality) {
|
|
2507
|
+
dirty.quality = true;
|
|
2119
2508
|
merged.quality = quality;
|
|
2120
|
-
controller.dprCap =
|
|
2509
|
+
controller.dprCap = effectiveDprCap(quality, merged.renderScale);
|
|
2510
|
+
controller.resizeCanvas();
|
|
2511
|
+
if (overlay) overlay.setDprCap(controller.dprCap);
|
|
2512
|
+
if (isMotionPaused()) renderOnce();
|
|
2513
|
+
return this;
|
|
2514
|
+
},
|
|
2515
|
+
setRenderScale: function setRenderScale(renderScale) {
|
|
2516
|
+
var value = Number(renderScale);
|
|
2517
|
+
if (!Number.isFinite(value)) return this;
|
|
2518
|
+
dirty.renderScale = true;
|
|
2519
|
+
merged.renderScale = Math.min(1, Math.max(0.25, value));
|
|
2520
|
+
controller.dprCap = effectiveDprCap(merged.quality, merged.renderScale);
|
|
2121
2521
|
controller.resizeCanvas();
|
|
2522
|
+
if (overlay) overlay.setDprCap(controller.dprCap);
|
|
2523
|
+
if (isMotionPaused()) renderOnce();
|
|
2122
2524
|
return this;
|
|
2123
2525
|
},
|
|
2124
2526
|
dispose: function dispose() {
|
|
2125
2527
|
disposed = true;
|
|
2126
2528
|
unsubscribe();
|
|
2529
|
+
offPausedChange();
|
|
2127
2530
|
visibility.dispose();
|
|
2531
|
+
motionPreference.dispose();
|
|
2128
2532
|
if (overlay) overlay.dispose();
|
|
2129
2533
|
controller.dispose();
|
|
2130
2534
|
root.remove();
|
|
@@ -2135,6 +2539,45 @@ function createProgressCapsule(container) {
|
|
|
2135
2539
|
get cssVars() {
|
|
2136
2540
|
return merged.cssVars;
|
|
2137
2541
|
},
|
|
2542
|
+
get min() {
|
|
2543
|
+
return controller.min;
|
|
2544
|
+
},
|
|
2545
|
+
get max() {
|
|
2546
|
+
return controller.max;
|
|
2547
|
+
},
|
|
2548
|
+
get step() {
|
|
2549
|
+
return controller.step;
|
|
2550
|
+
},
|
|
2551
|
+
get precision() {
|
|
2552
|
+
return controller.precision;
|
|
2553
|
+
},
|
|
2554
|
+
get formatValue() {
|
|
2555
|
+
return controller.formatValue;
|
|
2556
|
+
},
|
|
2557
|
+
get direction() {
|
|
2558
|
+
return controller.direction;
|
|
2559
|
+
},
|
|
2560
|
+
get showValue() {
|
|
2561
|
+
return !valueElement.hidden;
|
|
2562
|
+
},
|
|
2563
|
+
get valueSuffix() {
|
|
2564
|
+
return controller.valueSuffix;
|
|
2565
|
+
},
|
|
2566
|
+
get quality() {
|
|
2567
|
+
return merged.quality;
|
|
2568
|
+
},
|
|
2569
|
+
get renderScale() {
|
|
2570
|
+
return merged.renderScale;
|
|
2571
|
+
},
|
|
2572
|
+
get paused() {
|
|
2573
|
+
return manuallyPaused;
|
|
2574
|
+
},
|
|
2575
|
+
get static() {
|
|
2576
|
+
return staticMode;
|
|
2577
|
+
},
|
|
2578
|
+
get fps() {
|
|
2579
|
+
return frameGate.getFps();
|
|
2580
|
+
},
|
|
2138
2581
|
dirty: dirty
|
|
2139
2582
|
};
|
|
2140
2583
|
}
|