@whykusanagi/corrupted-theme 0.1.6 → 0.1.8
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 +38 -0
- package/README.md +207 -42
- package/docs/COMPONENTS_REFERENCE.md +142 -35
- package/docs/governance/VERSION_MANAGEMENT.md +2 -2
- package/docs/governance/VERSION_REFERENCES.md +56 -199
- package/docs/platforms/NPM_PACKAGE.md +9 -7
- package/examples/advanced/glsl-vortex.html +298 -0
- package/examples/advanced/particles-bg.html +264 -0
- package/examples/basic/multi-gallery.html +155 -0
- package/examples/button.html +5 -2
- package/examples/card.html +5 -2
- package/examples/extensions-showcase.html +41 -2
- package/examples/form.html +5 -2
- package/examples/index.html +34 -6
- package/examples/interactive-components.html +223 -0
- package/examples/layout.html +5 -2
- package/examples/nikke-team-builder.html +6 -3
- package/examples/showcase-complete.html +14 -13
- package/examples/showcase.html +6 -3
- package/package.json +8 -5
- package/src/core/corrupted-text.js +25 -5
- package/src/core/event-tracker.js +46 -0
- package/src/core/timer-registry.js +94 -0
- package/src/core/typing-animation.js +36 -17
- package/src/css/components.css +108 -0
- package/src/lib/carousel.js +308 -0
- package/src/lib/celeste-widget.js +178 -47
- package/src/lib/character-corruption.js +33 -8
- package/src/lib/components.js +357 -25
- package/src/lib/corrupted-particles.js +309 -0
- package/src/lib/corrupted-text.js +21 -5
- package/src/lib/corrupted-vortex.js +329 -0
- package/src/lib/corruption-loading.js +40 -10
- package/src/lib/countdown-widget.js +25 -6
- package/src/lib/gallery.js +420 -354
|
@@ -31,6 +31,34 @@
|
|
|
31
31
|
localStorage.setItem("corruptionLoadingLastPlayed", Date.now().toString());
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// Inline timer tracking (IIFE can't import ES modules)
|
|
35
|
+
const _timers = { _t: new Set(), _i: new Set() };
|
|
36
|
+
function _setTimeout(fn, delay) {
|
|
37
|
+
const id = setTimeout(() => { _timers._t.delete(id); fn(); }, delay);
|
|
38
|
+
_timers._t.add(id);
|
|
39
|
+
return id;
|
|
40
|
+
}
|
|
41
|
+
function _setInterval(fn, delay) {
|
|
42
|
+
const id = setInterval(fn, delay);
|
|
43
|
+
_timers._i.add(id);
|
|
44
|
+
return id;
|
|
45
|
+
}
|
|
46
|
+
function _clearAllTimers() {
|
|
47
|
+
_timers._t.forEach(id => clearTimeout(id));
|
|
48
|
+
_timers._i.forEach(id => clearInterval(id));
|
|
49
|
+
_timers._t.clear();
|
|
50
|
+
_timers._i.clear();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Cancel loading screen early
|
|
54
|
+
function cancelLoading() {
|
|
55
|
+
_clearAllTimers();
|
|
56
|
+
const screen = document.getElementById('corruption-loading');
|
|
57
|
+
if (screen) screen.remove();
|
|
58
|
+
const styles = document.getElementById('corruption-loading-styles');
|
|
59
|
+
if (styles) styles.remove();
|
|
60
|
+
}
|
|
61
|
+
|
|
34
62
|
// Main function to show loading screen
|
|
35
63
|
function showCorruptionLoading(options = {}) {
|
|
36
64
|
const config = {
|
|
@@ -51,7 +79,7 @@
|
|
|
51
79
|
// Inject styles
|
|
52
80
|
const style = document.createElement("style");
|
|
53
81
|
style.id = "corruption-loading-styles";
|
|
54
|
-
style.
|
|
82
|
+
style.textContent = `
|
|
55
83
|
@keyframes flicker {
|
|
56
84
|
0%, 100% { opacity: 1; }
|
|
57
85
|
50% { opacity: 0.4; }
|
|
@@ -235,6 +263,7 @@
|
|
|
235
263
|
const loadingScreen = document.createElement("div");
|
|
236
264
|
loadingScreen.id = "corruption-loading-screen";
|
|
237
265
|
|
|
266
|
+
// Static HTML only — no interpolated variables, safe from XSS
|
|
238
267
|
loadingScreen.innerHTML = `
|
|
239
268
|
<div class="corrupt-stream"></div>
|
|
240
269
|
<div class="crt-overlay"></div>
|
|
@@ -306,8 +335,8 @@
|
|
|
306
335
|
|
|
307
336
|
target.innerHTML = '';
|
|
308
337
|
let i = 0;
|
|
309
|
-
const interval =
|
|
310
|
-
if (i >= text.length)
|
|
338
|
+
const interval = _setInterval(() => {
|
|
339
|
+
if (i >= text.length) { clearInterval(interval); _timers._i.delete(interval); return; }
|
|
311
340
|
const span = document.createElement('span');
|
|
312
341
|
span.className = 'glyph';
|
|
313
342
|
span.textContent = text[i];
|
|
@@ -349,16 +378,16 @@
|
|
|
349
378
|
});
|
|
350
379
|
|
|
351
380
|
// Animate progress text
|
|
352
|
-
|
|
381
|
+
_setTimeout(() => {
|
|
353
382
|
[...progressText.children].forEach((span, idx) => {
|
|
354
|
-
|
|
383
|
+
_setTimeout(() => {
|
|
355
384
|
span.textContent = phrase.replace(/\s/g, '').charAt(idx);
|
|
356
385
|
}, 500 * (idx + 1));
|
|
357
386
|
});
|
|
358
387
|
}, 3600);
|
|
359
388
|
|
|
360
389
|
// Type grow text
|
|
361
|
-
|
|
390
|
+
_setTimeout(() => {
|
|
362
391
|
const growText = document.getElementById("grow-text");
|
|
363
392
|
if (growText) {
|
|
364
393
|
typeGlyphText("grow-text", "Initializing corruption protocols...", 80);
|
|
@@ -366,9 +395,10 @@
|
|
|
366
395
|
}, 2000);
|
|
367
396
|
|
|
368
397
|
// Remove loading screen
|
|
369
|
-
|
|
398
|
+
_setTimeout(() => {
|
|
370
399
|
loadingScreen.style.opacity = "0";
|
|
371
|
-
|
|
400
|
+
_setTimeout(() => {
|
|
401
|
+
_clearAllTimers();
|
|
372
402
|
loadingScreen.remove();
|
|
373
403
|
const styles = document.getElementById("corruption-loading-styles");
|
|
374
404
|
if (styles) styles.remove();
|
|
@@ -394,12 +424,12 @@
|
|
|
394
424
|
|
|
395
425
|
// Export for manual use
|
|
396
426
|
window.showCorruptionLoading = showCorruptionLoading;
|
|
397
|
-
window.CorruptionLoading = { show: showCorruptionLoading };
|
|
427
|
+
window.CorruptionLoading = { show: showCorruptionLoading, cancel: cancelLoading };
|
|
398
428
|
}
|
|
399
429
|
|
|
400
430
|
// Export for modules
|
|
401
431
|
if (typeof module !== 'undefined' && module.exports) {
|
|
402
|
-
module.exports = { showCorruptionLoading };
|
|
432
|
+
module.exports = { showCorruptionLoading, cancelLoading };
|
|
403
433
|
}
|
|
404
434
|
})();
|
|
405
435
|
|
|
@@ -134,6 +134,8 @@ let state = {
|
|
|
134
134
|
config: null,
|
|
135
135
|
countdownInterval: null,
|
|
136
136
|
popupInterval: null,
|
|
137
|
+
popupInitTimeout: null,
|
|
138
|
+
popupDurationTimeout: null,
|
|
137
139
|
isCompleted: false
|
|
138
140
|
};
|
|
139
141
|
|
|
@@ -314,7 +316,7 @@ function renderWidget(config) {
|
|
|
314
316
|
if (config.popup?.message) {
|
|
315
317
|
popup = document.createElement('div');
|
|
316
318
|
popup.className = 'countdown-popup';
|
|
317
|
-
popup.
|
|
319
|
+
popup.textContent = config.popup.message;
|
|
318
320
|
|
|
319
321
|
if (config.popup.colors) {
|
|
320
322
|
if (config.popup.colors.bg) popup.style.background = config.popup.colors.bg;
|
|
@@ -460,7 +462,8 @@ function startPopup(popupConfig, popupElement) {
|
|
|
460
462
|
const duration = popupConfig.duration || 5000;
|
|
461
463
|
|
|
462
464
|
// Show popup initially after a delay
|
|
463
|
-
setTimeout(() => {
|
|
465
|
+
state.popupInitTimeout = setTimeout(() => {
|
|
466
|
+
state.popupInitTimeout = null;
|
|
464
467
|
showPopup(popupElement, duration);
|
|
465
468
|
}, 2000);
|
|
466
469
|
|
|
@@ -478,8 +481,14 @@ function startPopup(popupConfig, popupElement) {
|
|
|
478
481
|
*/
|
|
479
482
|
function showPopup(popup, duration) {
|
|
480
483
|
popup.classList.add('active');
|
|
481
|
-
|
|
482
|
-
|
|
484
|
+
|
|
485
|
+
// Clear previous duration timeout if popup is re-shown before it hides
|
|
486
|
+
if (state.popupDurationTimeout) {
|
|
487
|
+
clearTimeout(state.popupDurationTimeout);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
state.popupDurationTimeout = setTimeout(() => {
|
|
491
|
+
state.popupDurationTimeout = null;
|
|
483
492
|
popup.classList.remove('active');
|
|
484
493
|
}, duration);
|
|
485
494
|
}
|
|
@@ -584,12 +593,22 @@ export function destroyCountdown() {
|
|
|
584
593
|
clearInterval(state.countdownInterval);
|
|
585
594
|
state.countdownInterval = null;
|
|
586
595
|
}
|
|
587
|
-
|
|
596
|
+
|
|
588
597
|
if (state.popupInterval) {
|
|
589
598
|
clearInterval(state.popupInterval);
|
|
590
599
|
state.popupInterval = null;
|
|
591
600
|
}
|
|
592
|
-
|
|
601
|
+
|
|
602
|
+
if (state.popupInitTimeout) {
|
|
603
|
+
clearTimeout(state.popupInitTimeout);
|
|
604
|
+
state.popupInitTimeout = null;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (state.popupDurationTimeout) {
|
|
608
|
+
clearTimeout(state.popupDurationTimeout);
|
|
609
|
+
state.popupDurationTimeout = null;
|
|
610
|
+
}
|
|
611
|
+
|
|
593
612
|
state.config = null;
|
|
594
613
|
state.isCompleted = false;
|
|
595
614
|
|