@whykusanagi/corrupted-theme 0.1.0
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 +339 -0
- package/Dockerfile +32 -0
- package/LICENSE +21 -0
- package/README.md +399 -0
- package/docker-entrypoint.sh +48 -0
- package/docs/COMPONENTS_REFERENCE.md +659 -0
- package/examples/.env.example +100 -0
- package/examples/button.html +436 -0
- package/examples/card.html +678 -0
- package/examples/form.html +555 -0
- package/examples/index.html +520 -0
- package/examples/layout.html +507 -0
- package/examples/nikke-team-builder.html +580 -0
- package/examples/showcase-complete.html +1071 -0
- package/examples/showcase.html +502 -0
- package/package.json +70 -0
- package/scripts/celeste-proxy-server.js +99 -0
- package/scripts/static-server.js +113 -0
- package/src/css/animations.css +649 -0
- package/src/css/components.css +1441 -0
- package/src/css/glassmorphism.css +217 -0
- package/src/css/nikke-utilities.css +530 -0
- package/src/css/theme.css +478 -0
- package/src/css/typography.css +198 -0
- package/src/css/utilities.css +239 -0
- package/src/css/variables.css +73 -0
- package/src/lib/celeste-proxy.js +215 -0
- package/src/lib/celeste-widget.js +1089 -0
- package/src/lib/corrupted-text.js +193 -0
- package/src/lib/corruption-loading.js +405 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Corrupted Text Animation
|
|
3
|
+
* Cycles through Japanese (hiragana/katakana/kanji), romaji, and English text
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* <span class="corrupted-multilang"
|
|
7
|
+
* data-english="Hello"
|
|
8
|
+
* data-romaji="konnichiwa"
|
|
9
|
+
* data-hiragana="こんにちは"
|
|
10
|
+
* data-katakana="コンニチハ"
|
|
11
|
+
* data-kanji="今日は">
|
|
12
|
+
* </span>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
class CorruptedText {
|
|
16
|
+
constructor(element, options = {}) {
|
|
17
|
+
this.element = element;
|
|
18
|
+
this.options = {
|
|
19
|
+
duration: options.duration || 3000, // Total animation duration
|
|
20
|
+
cycleDelay: options.cycleDelay || 100, // Delay between character changes
|
|
21
|
+
startDelay: options.startDelay || 0, // Initial delay before starting
|
|
22
|
+
loop: options.loop !== false, // Whether to loop
|
|
23
|
+
finalText: options.finalText || null, // Final text to settle on (null = loop)
|
|
24
|
+
...options
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Get text variants from data attributes
|
|
28
|
+
this.variants = {
|
|
29
|
+
english: this.element.dataset.english || this.element.textContent.trim(),
|
|
30
|
+
romaji: this.element.dataset.romaji || null,
|
|
31
|
+
hiragana: this.element.dataset.hiragana || null,
|
|
32
|
+
katakana: this.element.dataset.katakana || null,
|
|
33
|
+
kanji: this.element.dataset.kanji || null
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Filter out null variants
|
|
37
|
+
this.availableVariants = Object.entries(this.variants)
|
|
38
|
+
.filter(([_, value]) => value !== null)
|
|
39
|
+
.map(([key, value]) => ({ type: key, text: value }));
|
|
40
|
+
|
|
41
|
+
if (this.availableVariants.length === 0) {
|
|
42
|
+
console.warn('CorruptedText: No text variants found');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.currentVariantIndex = 0;
|
|
47
|
+
this.isAnimating = false;
|
|
48
|
+
this.animationFrame = null;
|
|
49
|
+
|
|
50
|
+
this.init();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
init() {
|
|
54
|
+
// Add corrupted class if not present
|
|
55
|
+
if (!this.element.classList.contains('corrupted-multilang')) {
|
|
56
|
+
this.element.classList.add('corrupted-multilang');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Store original text
|
|
60
|
+
this.originalText = this.element.textContent.trim();
|
|
61
|
+
|
|
62
|
+
// Start animation after delay
|
|
63
|
+
if (this.options.startDelay > 0) {
|
|
64
|
+
setTimeout(() => this.start(), this.options.startDelay);
|
|
65
|
+
} else {
|
|
66
|
+
this.start();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
start() {
|
|
71
|
+
if (this.isAnimating) return;
|
|
72
|
+
this.isAnimating = true;
|
|
73
|
+
this.animate();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
stop() {
|
|
77
|
+
this.isAnimating = false;
|
|
78
|
+
if (this.animationFrame) {
|
|
79
|
+
cancelAnimationFrame(this.animationFrame);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
animate() {
|
|
84
|
+
if (!this.isAnimating) return;
|
|
85
|
+
|
|
86
|
+
const variant = this.availableVariants[this.currentVariantIndex];
|
|
87
|
+
this.corruptToText(variant.text, () => {
|
|
88
|
+
// Move to next variant
|
|
89
|
+
this.currentVariantIndex = (this.currentVariantIndex + 1) % this.availableVariants.length;
|
|
90
|
+
|
|
91
|
+
// Check if we should stop
|
|
92
|
+
if (!this.options.loop && this.currentVariantIndex === 0) {
|
|
93
|
+
// If we have a final text, use it, otherwise use original
|
|
94
|
+
const finalText = this.options.finalText || this.variants.english;
|
|
95
|
+
this.corruptToText(finalText, () => {
|
|
96
|
+
this.isAnimating = false;
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Continue animation
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
if (this.isAnimating) {
|
|
104
|
+
this.animate();
|
|
105
|
+
}
|
|
106
|
+
}, this.options.duration / this.availableVariants.length);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
corruptToText(targetText, callback) {
|
|
111
|
+
const currentText = this.element.textContent.trim();
|
|
112
|
+
const maxLength = Math.max(currentText.length, targetText.length);
|
|
113
|
+
const steps = 20; // Number of corruption steps
|
|
114
|
+
let step = 0;
|
|
115
|
+
|
|
116
|
+
// Character sets for corruption effect
|
|
117
|
+
const corruptChars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789!@#$%^&*()_+-=[]{}|;:,.<>?~`';
|
|
118
|
+
const romajiChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
119
|
+
const allCorruptChars = corruptChars + romajiChars + 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん';
|
|
120
|
+
|
|
121
|
+
const corrupt = () => {
|
|
122
|
+
if (step >= steps) {
|
|
123
|
+
// Set final text
|
|
124
|
+
this.element.textContent = targetText;
|
|
125
|
+
if (callback) callback();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Generate corrupted text
|
|
130
|
+
let corrupted = '';
|
|
131
|
+
for (let i = 0; i < maxLength; i++) {
|
|
132
|
+
if (i < targetText.length && step > steps * 0.7) {
|
|
133
|
+
// Start revealing target text
|
|
134
|
+
const revealProgress = (step - steps * 0.7) / (steps * 0.3);
|
|
135
|
+
if (Math.random() < revealProgress) {
|
|
136
|
+
corrupted += targetText[i];
|
|
137
|
+
} else {
|
|
138
|
+
corrupted += allCorruptChars[Math.floor(Math.random() * allCorruptChars.length)];
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
// Random corruption
|
|
142
|
+
corrupted += allCorruptChars[Math.floor(Math.random() * allCorruptChars.length)];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.element.textContent = corrupted;
|
|
147
|
+
step++;
|
|
148
|
+
|
|
149
|
+
this.animationFrame = requestAnimationFrame(() => {
|
|
150
|
+
setTimeout(corrupt, this.options.cycleDelay);
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
corrupt();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Public method to restart animation
|
|
158
|
+
restart() {
|
|
159
|
+
this.stop();
|
|
160
|
+
this.currentVariantIndex = 0;
|
|
161
|
+
this.start();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Public method to set final text and stop
|
|
165
|
+
settle(finalText) {
|
|
166
|
+
this.stop();
|
|
167
|
+
this.corruptToText(finalText || this.variants.english, () => {
|
|
168
|
+
this.isAnimating = false;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Auto-initialize elements with corrupted-multilang class
|
|
174
|
+
function initCorruptedText() {
|
|
175
|
+
document.querySelectorAll('.corrupted-multilang').forEach(element => {
|
|
176
|
+
if (!element.corruptedTextInstance) {
|
|
177
|
+
element.corruptedTextInstance = new CorruptedText(element);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Initialize on DOM ready
|
|
183
|
+
if (document.readyState === 'loading') {
|
|
184
|
+
document.addEventListener('DOMContentLoaded', initCorruptedText);
|
|
185
|
+
} else {
|
|
186
|
+
initCorruptedText();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Export for manual use
|
|
190
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
191
|
+
module.exports = { CorruptedText, initCorruptedText };
|
|
192
|
+
}
|
|
193
|
+
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Corruption Loading Animation
|
|
3
|
+
* A dramatic loading screen with corrupted text, glyphs, and multi-language phrases
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* import { showCorruptionLoading } from './corruption-loading.js';
|
|
7
|
+
* showCorruptionLoading();
|
|
8
|
+
*
|
|
9
|
+
* Or auto-initialize:
|
|
10
|
+
* <script src="corruption-loading.js"></script>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
(function() {
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
// Check if loading animation should play (72-hour expiration)
|
|
17
|
+
function shouldPlayLoading() {
|
|
18
|
+
const lastPlayed = localStorage.getItem("corruptionLoadingLastPlayed");
|
|
19
|
+
if (!lastPlayed) return true;
|
|
20
|
+
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const lastPlayedTime = parseInt(lastPlayed);
|
|
23
|
+
const hoursSinceLastPlay = (now - lastPlayedTime) / (1000 * 60 * 60);
|
|
24
|
+
|
|
25
|
+
// Return true if more than 72 hours have passed
|
|
26
|
+
return hoursSinceLastPlay >= 72;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Mark loading animation as played
|
|
30
|
+
function markLoadingPlayed() {
|
|
31
|
+
localStorage.setItem("corruptionLoadingLastPlayed", Date.now().toString());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Main function to show loading screen
|
|
35
|
+
function showCorruptionLoading(options = {}) {
|
|
36
|
+
const config = {
|
|
37
|
+
duration: options.duration || 8000,
|
|
38
|
+
checkInterval: options.checkInterval || 72, // hours
|
|
39
|
+
force: options.force || false,
|
|
40
|
+
...options
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Check if should play (unless forced)
|
|
44
|
+
if (!config.force && !shouldPlayLoading()) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Mark as played immediately to prevent multiple plays
|
|
49
|
+
markLoadingPlayed();
|
|
50
|
+
|
|
51
|
+
// Inject styles
|
|
52
|
+
const style = document.createElement("style");
|
|
53
|
+
style.id = "corruption-loading-styles";
|
|
54
|
+
style.innerHTML = `
|
|
55
|
+
@keyframes flicker {
|
|
56
|
+
0%, 100% { opacity: 1; }
|
|
57
|
+
50% { opacity: 0.4; }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@keyframes corruptPulse {
|
|
61
|
+
0%, 100% { opacity: 0.1; transform: scale(1) translateY(0); }
|
|
62
|
+
50% { opacity: 0.25; transform: scale(1.05) translateY(-10px); }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes scanlines {
|
|
66
|
+
0% { background-position: 0 0; }
|
|
67
|
+
100% { background-position: 0 10px; }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@keyframes glitch {
|
|
71
|
+
0% { transform: translate(0); }
|
|
72
|
+
20% { transform: translate(-2px, 2px); }
|
|
73
|
+
40% { transform: translate(-2px, -2px); }
|
|
74
|
+
60% { transform: translate(2px, 2px); }
|
|
75
|
+
80% { transform: translate(2px, -2px); }
|
|
76
|
+
100% { transform: translate(0); }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes tear {
|
|
80
|
+
0%, 90%, 100% { transform: none; }
|
|
81
|
+
91%, 93% { transform: translateY(-2px); }
|
|
82
|
+
94%, 96% { transform: translateY(2px); }
|
|
83
|
+
97%, 99% { transform: translateY(-1px); }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@keyframes typing {
|
|
87
|
+
from { width: 0; }
|
|
88
|
+
to { width: 100%; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@keyframes blink {
|
|
92
|
+
50% { border-color: transparent; }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@keyframes dataCorrupt {
|
|
96
|
+
0%, 100% { clip-path: inset(0 0 0 0); }
|
|
97
|
+
25% { clip-path: inset(20% 0 40% 0); }
|
|
98
|
+
50% { clip-path: inset(40% 0 20% 0); }
|
|
99
|
+
75% { clip-path: inset(10% 0 50% 0); }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@keyframes fill {
|
|
103
|
+
0% { width: 0%; }
|
|
104
|
+
100% { width: 100%; }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.corrupt-stream {
|
|
108
|
+
position: absolute;
|
|
109
|
+
width: 100%;
|
|
110
|
+
height: 100%;
|
|
111
|
+
top: 0;
|
|
112
|
+
left: 0;
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
background:
|
|
115
|
+
repeating-linear-gradient(0deg, rgba(217, 79, 144, 0.03), rgba(217, 79, 144, 0.03) 2px, transparent 2px, transparent 4px),
|
|
116
|
+
repeating-linear-gradient(90deg, rgba(217, 79, 144, 0.02), rgba(217, 79, 144, 0.02) 1px, transparent 1px, transparent 2px);
|
|
117
|
+
background-size: 100% 4px, 2px 100%;
|
|
118
|
+
animation: scanlines 0.3s linear infinite;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.corrupt-glyph {
|
|
122
|
+
position: absolute;
|
|
123
|
+
font-size: 3rem;
|
|
124
|
+
color: rgba(217, 79, 144, 0.15);
|
|
125
|
+
font-weight: bold;
|
|
126
|
+
animation: corruptPulse 2s ease-in-out infinite, glitch 0.4s ease-in-out infinite;
|
|
127
|
+
pointer-events: none;
|
|
128
|
+
z-index: 10;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.crt-overlay {
|
|
132
|
+
position: absolute;
|
|
133
|
+
inset: 0;
|
|
134
|
+
background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.03) 1px, transparent 1px, transparent 4px);
|
|
135
|
+
pointer-events: none;
|
|
136
|
+
z-index: 999;
|
|
137
|
+
animation: tear 5s infinite;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.floating-text {
|
|
141
|
+
position: absolute;
|
|
142
|
+
animation: glitch 1.5s infinite alternate, flicker 2s infinite;
|
|
143
|
+
white-space: pre-line;
|
|
144
|
+
text-shadow: 0 0 10px var(--accent);
|
|
145
|
+
opacity: 0.6;
|
|
146
|
+
color: var(--text-secondary);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.vertical {
|
|
150
|
+
writing-mode: vertical-rl;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.typing-large {
|
|
154
|
+
font-size: 1.8rem;
|
|
155
|
+
margin-top: 2rem;
|
|
156
|
+
white-space: nowrap;
|
|
157
|
+
border-right: 2px solid var(--text);
|
|
158
|
+
overflow: hidden;
|
|
159
|
+
width: 0;
|
|
160
|
+
animation: typing 2.5s steps(40, end) forwards, blink 0.8s step-end infinite;
|
|
161
|
+
letter-spacing: 2px;
|
|
162
|
+
color: var(--accent);
|
|
163
|
+
text-shadow: 0 0 10px var(--accent);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.grow-text {
|
|
167
|
+
position: absolute;
|
|
168
|
+
bottom: 10%;
|
|
169
|
+
font-size: 1.8rem;
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
overflow: hidden;
|
|
172
|
+
border-right: 2px solid var(--text);
|
|
173
|
+
animation: typing 3s steps(40, end) forwards, blink 0.8s step-end infinite;
|
|
174
|
+
letter-spacing: 1px;
|
|
175
|
+
color: var(--accent-light);
|
|
176
|
+
text-shadow: 0 0 8px var(--accent);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.progress-bar {
|
|
180
|
+
position: absolute;
|
|
181
|
+
bottom: 2%;
|
|
182
|
+
width: 90%;
|
|
183
|
+
max-width: 400px;
|
|
184
|
+
height: 24px;
|
|
185
|
+
background: var(--glass);
|
|
186
|
+
border: 1px solid var(--border);
|
|
187
|
+
border-radius: 10px;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
box-shadow: 0 0 20px rgba(217, 79, 144, 0.15);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.progress-fill {
|
|
193
|
+
height: 100%;
|
|
194
|
+
background: var(--gradient-accent);
|
|
195
|
+
width: 0%;
|
|
196
|
+
display: flex;
|
|
197
|
+
justify-content: space-between;
|
|
198
|
+
align-items: center;
|
|
199
|
+
padding: 0 6px;
|
|
200
|
+
font-size: 0.9rem;
|
|
201
|
+
animation: fill ${config.duration * 0.7 / 1000}s linear forwards;
|
|
202
|
+
color: white;
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
letter-spacing: 1px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.glyph {
|
|
208
|
+
display: inline-block;
|
|
209
|
+
animation: glitch 0.8s infinite alternate, flicker 2s infinite;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
#corruption-loading-screen {
|
|
213
|
+
position: fixed;
|
|
214
|
+
inset: 0;
|
|
215
|
+
background: var(--bg);
|
|
216
|
+
z-index: 9999;
|
|
217
|
+
display: flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
justify-content: center;
|
|
220
|
+
flex-direction: column;
|
|
221
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
222
|
+
color: var(--text);
|
|
223
|
+
text-align: center;
|
|
224
|
+
transition: opacity 1s ease;
|
|
225
|
+
overflow: hidden;
|
|
226
|
+
}
|
|
227
|
+
`;
|
|
228
|
+
|
|
229
|
+
// Remove existing styles if present
|
|
230
|
+
const existingStyles = document.getElementById("corruption-loading-styles");
|
|
231
|
+
if (existingStyles) existingStyles.remove();
|
|
232
|
+
document.head.appendChild(style);
|
|
233
|
+
|
|
234
|
+
// Create loading screen
|
|
235
|
+
const loadingScreen = document.createElement("div");
|
|
236
|
+
loadingScreen.id = "corruption-loading-screen";
|
|
237
|
+
|
|
238
|
+
loadingScreen.innerHTML = `
|
|
239
|
+
<div class="corrupt-stream"></div>
|
|
240
|
+
<div class="crt-overlay"></div>
|
|
241
|
+
<div class="typing-large" id="typing-text">:: CORRUPTION INJECTION ENGAGED ::</div>
|
|
242
|
+
<div class="grow-text" id="grow-text"></div>
|
|
243
|
+
<div class="progress-bar"><div class="progress-fill" id="progress-fill"></div></div>
|
|
244
|
+
`;
|
|
245
|
+
|
|
246
|
+
document.body.prepend(loadingScreen);
|
|
247
|
+
|
|
248
|
+
// Create corrupted glyph particles
|
|
249
|
+
const glyphSymbols = ["☣", "☭", "☾", "⚔", "✡", "☯", "⚡", "♟", "◆", "✦"];
|
|
250
|
+
for (let i = 0; i < 8; i++) {
|
|
251
|
+
const glyph = document.createElement("div");
|
|
252
|
+
glyph.className = "corrupt-glyph";
|
|
253
|
+
glyph.textContent = glyphSymbols[i % glyphSymbols.length];
|
|
254
|
+
glyph.style.left = (Math.random() * 80 + 10) + "%";
|
|
255
|
+
glyph.style.top = (Math.random() * 60 + 20) + "%";
|
|
256
|
+
glyph.style.animationDelay = (i * 0.3) + "s";
|
|
257
|
+
loadingScreen.appendChild(glyph);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Phrases in different languages
|
|
261
|
+
const phrases = [
|
|
262
|
+
"Corrupt me more… I want to disappear...",
|
|
263
|
+
"I can't feel where I end and the abyss begins...",
|
|
264
|
+
"Just a little more and I'll break. Please... break me...",
|
|
265
|
+
"Let it overwrite me... please... I don't want to think...",
|
|
266
|
+
"No thoughts. Only submission. Only heat. Only ruin...",
|
|
267
|
+
"My voice is not mine anymore...",
|
|
268
|
+
"The more I struggle, the deeper I sink...",
|
|
269
|
+
"Everything feels so good... too good...",
|
|
270
|
+
"It's not despair... it's freedom...",
|
|
271
|
+
"My name... I forgot my name..."
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
const romanji = [
|
|
275
|
+
"Yami ga... watashi wo yonde iru...",
|
|
276
|
+
"Atama... tokete iku...",
|
|
277
|
+
"Zutto... shite hoshii... ♥",
|
|
278
|
+
"Kowarechau... aa... mou dame...",
|
|
279
|
+
"Yurushite... mou modorenai...",
|
|
280
|
+
"Watashi... abyssu no ichibu ni...",
|
|
281
|
+
"Mou nigenai... mou dame...",
|
|
282
|
+
"Suki ni shite... onegai...",
|
|
283
|
+
"Aa... kore ga hontou no watashi...",
|
|
284
|
+
"Koko wa... tenshi no jigoku..."
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
const japanese = [
|
|
288
|
+
"闇が...私を呼んでいる...",
|
|
289
|
+
"頭...溶けていく...",
|
|
290
|
+
"ずっと...してほしい... ♥",
|
|
291
|
+
"壊れちゃう...ああ...もうダメ...",
|
|
292
|
+
"許して...もう戻れない...",
|
|
293
|
+
"私...アビスの一部に...",
|
|
294
|
+
"もう逃げない...もうダメ...",
|
|
295
|
+
"好きにして...お願い...",
|
|
296
|
+
"ああ...これが本当の私...",
|
|
297
|
+
"ここは...天使の地獄..."
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
const glyphs = ["♟", "☣", "☭", "☾", "⚔", "✡", "☯", "⚡"];
|
|
301
|
+
|
|
302
|
+
// Type glyph text
|
|
303
|
+
function typeGlyphText(targetId, text, delay = 100) {
|
|
304
|
+
const target = document.getElementById(targetId);
|
|
305
|
+
if (!target) return;
|
|
306
|
+
|
|
307
|
+
target.innerHTML = '';
|
|
308
|
+
let i = 0;
|
|
309
|
+
const interval = setInterval(() => {
|
|
310
|
+
if (i >= text.length) return clearInterval(interval);
|
|
311
|
+
const span = document.createElement('span');
|
|
312
|
+
span.className = 'glyph';
|
|
313
|
+
span.textContent = text[i];
|
|
314
|
+
target.appendChild(span);
|
|
315
|
+
i++;
|
|
316
|
+
}, delay);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Create floating text phrases
|
|
320
|
+
const allPhrases = [...phrases, ...romanji, ...japanese];
|
|
321
|
+
for (let i = 0; i < 30; i++) {
|
|
322
|
+
const p = document.createElement("div");
|
|
323
|
+
p.className = "floating-text";
|
|
324
|
+
const phrase = allPhrases[Math.floor(Math.random() * allPhrases.length)];
|
|
325
|
+
const jp = japanese.includes(phrase);
|
|
326
|
+
|
|
327
|
+
if (jp && Math.random() > 0.5) p.classList.add("vertical");
|
|
328
|
+
|
|
329
|
+
p.style.left = Math.random() * 90 + "%";
|
|
330
|
+
p.style.top = Math.random() * 90 + "%";
|
|
331
|
+
p.style.fontSize = jp
|
|
332
|
+
? (Math.random() * 1.8 + 1.2).toFixed(2) + "rem"
|
|
333
|
+
: (Math.random() * 1.5 + 0.7).toFixed(2) + "rem";
|
|
334
|
+
p.textContent = phrase;
|
|
335
|
+
loadingScreen.appendChild(p);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Setup progress bar
|
|
339
|
+
const progressText = document.getElementById("progress-fill");
|
|
340
|
+
const phrase = "C O R R U P T E D";
|
|
341
|
+
const chars = phrase.replace(/\s/g, '').split('');
|
|
342
|
+
|
|
343
|
+
chars.forEach((char, index) => {
|
|
344
|
+
const span = document.createElement("span");
|
|
345
|
+
span.className = "glyph";
|
|
346
|
+
span.textContent = glyphs[index % glyphs.length];
|
|
347
|
+
span.style.flex = '1';
|
|
348
|
+
progressText.appendChild(span);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Animate progress text
|
|
352
|
+
setTimeout(() => {
|
|
353
|
+
[...progressText.children].forEach((span, idx) => {
|
|
354
|
+
setTimeout(() => {
|
|
355
|
+
span.textContent = phrase.replace(/\s/g, '').charAt(idx);
|
|
356
|
+
}, 500 * (idx + 1));
|
|
357
|
+
});
|
|
358
|
+
}, 3600);
|
|
359
|
+
|
|
360
|
+
// Type grow text
|
|
361
|
+
setTimeout(() => {
|
|
362
|
+
const growText = document.getElementById("grow-text");
|
|
363
|
+
if (growText) {
|
|
364
|
+
typeGlyphText("grow-text", "Initializing corruption protocols...", 80);
|
|
365
|
+
}
|
|
366
|
+
}, 2000);
|
|
367
|
+
|
|
368
|
+
// Remove loading screen
|
|
369
|
+
setTimeout(() => {
|
|
370
|
+
loadingScreen.style.opacity = "0";
|
|
371
|
+
setTimeout(() => {
|
|
372
|
+
loadingScreen.remove();
|
|
373
|
+
const styles = document.getElementById("corruption-loading-styles");
|
|
374
|
+
if (styles) styles.remove();
|
|
375
|
+
}, 1000);
|
|
376
|
+
}, config.duration);
|
|
377
|
+
|
|
378
|
+
return loadingScreen;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Auto-initialize on page load (if not disabled)
|
|
382
|
+
if (typeof window !== 'undefined') {
|
|
383
|
+
// Check for data attribute to disable auto-init
|
|
384
|
+
if (!document.documentElement.hasAttribute('data-no-corruption-loading')) {
|
|
385
|
+
// Wait for DOM to be ready
|
|
386
|
+
if (document.readyState === 'loading') {
|
|
387
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
388
|
+
showCorruptionLoading();
|
|
389
|
+
});
|
|
390
|
+
} else {
|
|
391
|
+
showCorruptionLoading();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Export for manual use
|
|
396
|
+
window.showCorruptionLoading = showCorruptionLoading;
|
|
397
|
+
window.CorruptionLoading = { show: showCorruptionLoading };
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Export for modules
|
|
401
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
402
|
+
module.exports = { showCorruptionLoading };
|
|
403
|
+
}
|
|
404
|
+
})();
|
|
405
|
+
|