Spaces:
Running
Running
File size: 17,273 Bytes
f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 fc169c4 f9273e6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CMD Ingaze Reveal Animation</title>
<style>
/* Styles for the animation when embedded */
body {
background-color: #000000; /* Black background for the animation area */
color: #00FF00; /* Bright green text */
font-family: 'Courier New', Courier, monospace; /* Classic CMD font */
margin: 0; /* Remove default margin */
padding: 0; /* Remove default padding */
overflow: hidden; /* Prevent scrollbars on the body of the iframe content */
display: flex; /* Flex container to center the animation content */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
min-height: 350px; /* Minimum height for the animation area, adjust as needed */
}
#cmd-animation-container {
padding: 15px; /* Reduced padding slightly */
border: 2px solid #00AA00; /* Darker green border */
background-color: #080808; /* Slightly off-black for the "screen" */
box-shadow: 0 0 10px #00FF00; /* Green glow effect, slightly reduced */
border-radius: 8px; /* Rounded corners for the container */
box-sizing: border-box; /* Include padding and border in the element's total width and height */
/* width: 100%; */ /* Let it size based on pre content or set a max-width */
max-width: calc(100% - 10px); /* Ensure it fits if iframe has padding */
margin: 5px; /* Add a small margin around the container */
}
pre#cmd-animation {
white-space: pre; /* Preserve whitespace and newlines */
text-align: left;
font-size: 12px; /* Adjusted for potentially smaller iframe, ensure legibility */
line-height: 1.15; /* Compact lines, slightly increased for readability */
margin: 0;
overflow-x: auto; /* Add scroll if content is wider than container */
/* The height of the pre will be determined by its content (number of lines) */
}
</style>
</head>
<body>
<div id="cmd-animation-container">
<pre id="cmd-animation">Loading Animation...</pre>
</div>
<script>
// --- Configuration ---
const scene_width = 65; // Characters
const scene_height = 22; // Lines
const frameDuration = 150; // Milliseconds per frame
const MAX_DATA_PARTICLES = 100; // Reduced slightly
const FLOOR_LEVEL = scene_height - 1;
// --- ASCII Art Definitions ---
const stick_man_art_normal = [" O ", " /|\\ ", " / \\ "];
const stick_man_art_walk_1 = [" O ", " /|\\ ", " / > "];
const stick_man_art_walk_2 = [" O ", " /|\\ ", " < \\ "];
const stick_man_art_surprise = [" \\O/ ", " | ", " / \\ "];
const stick_man_art_gone = [" ", " ", " "];
const linked_in_art = ["+----+", "|i n |", "+----+"];
const linked_in_art_hit = ["x----x", "|BOOM|", "x----x"];
const lightning_strike_segment = "\\";
const explosion_art_frames = [
[" * ", " *#* ", " * "],
[" @!% ", " @*#*& ", " X%O "],
[" $*~+@ ", "$#@!%*&", " X*O#~ ", " !+%$ "],
[" ~ ", " +*% ", " $ "]
];
const ingaze_logo_art = [
"IIIII N N GGG AAA ZZZZZ EEEEE",
" I NN N G A A Z E ",
" I N N N G GG AAAAA Z EEE ",
" I N NN G G A A Z E ",
"IIIII N N GGG A A ZZZZZ EEEEE"
];
const ingaze_logo_width = ingaze_logo_art[0].length;
const ingaze_logo_height = ingaze_logo_art.length;
// --- Global State (scoped within this script) ---
let data_particles_state = []; // Renamed to avoid conflict if script is ever not isolated
let current_lightning_y_state = -1;
// --- Helper Functions ---
function overlay(baseLines, artLines, startX, startY, ignoreSpaces = true) {
artLines.forEach((artLine, i) => {
const y = startY + i;
if (y >= 0 && y < baseLines.length && artLine) {
let baseLineArr = baseLines[y].split('');
for (let j = 0; j < artLine.length; j++) {
const x = startX + j;
if (x >= 0 && x < baseLineArr.length) {
if (ignoreSpaces && artLine[j] === ' ') continue;
baseLineArr[x] = artLine[j];
}
}
baseLines[y] = baseLineArr.join('');
}
});
}
function drawLightningBoltInScene(sceneLines, tipX, tipY, length) {
for (let i = 0; i < length; i++) {
const y = tipY - i;
const x = tipX + (i % 2 === 0 ? 0 : (i % 4 === 1 ? -1 : 1));
if (y >= 0 && y < scene_height && x >= 0 && x < scene_width) {
if (sceneLines[y][x] === ' ') {
let lineArr = sceneLines[y].split('');
lineArr[x] = lightning_strike_segment;
sceneLines[y] = lineArr.join('');
}
}
}
}
function buildSceneFrame(stickmanArt, stickmanPos, showLogo, currentLogoArt, currentLogoPos,
showLightningBolt, lightningTipX, lightningTipY, lightningLength,
currentExplosionArt, explosionPos,
showIngazeLogo, ingazeArt, ingazePos) {
let sceneLines = Array(scene_height).fill(" ".repeat(scene_width));
data_particles_state.forEach(p => {
const px = Math.round(p.x);
const py = Math.round(p.y);
if (py >= 0 && py < sceneLines.length && px >= 0 && px < scene_width) {
if (sceneLines[py][px] === ' ') {
let lineArr = sceneLines[py].split('');
lineArr[px] = p.char;
sceneLines[py] = lineArr.join('');
}
}
});
overlay(sceneLines, stickmanArt, stickmanPos.x, stickmanPos.y);
if (showLogo) overlay(sceneLines, currentLogoArt, currentLogoPos.x, currentLogoPos.y);
if (showLightningBolt && lightningTipY >=0) {
drawLightningBoltInScene(sceneLines, lightningTipX, lightningTipY, lightningLength);
}
if (currentExplosionArt && currentExplosionArt.length > 0) {
overlay(sceneLines, currentExplosionArt, explosionPos.x, explosionPos.y, false);
}
if (showIngazeLogo) overlay(sceneLines, ingazeArt, ingazePos.x, ingazePos.y);
return sceneLines.join('\n');
}
function spawnNewDataParticle(logoX, logoY, logoWidth) {
if (data_particles_state.length >= MAX_DATA_PARTICLES) return;
const char = Math.random() > 0.5 ? '1' : '0';
const x = logoX + 1 + Math.floor(Math.random() * (logoWidth - 2));
const y = logoY + linked_in_art.length;
const vy = 0.2 + Math.random() * 0.3;
data_particles_state.push({ char, x, y, vy, active: true });
}
function generateAnimationFrames() {
const sequence = [];
data_particles_state = []; // Reset particles for this generation
current_lightning_y_state = -1; // Reset lightning state
const stickman_height = stick_man_art_normal.length;
const stickman_width = stick_man_art_normal[0].length;
const logo_width = linked_in_art[0].length;
const logo_height = linked_in_art.length;
const stickman_base_y = FLOOR_LEVEL - stickman_height;
const logo_base_y = stickman_base_y;
const stickman_initial_pos = { x: 2, y: stickman_base_y };
const logo_initial_pos = { x: scene_width - logo_width - 15, y: logo_base_y }; // Adjusted position
const stickman_walk_target_x = Math.max(stickman_initial_pos.x + 1, logo_initial_pos.x - stickman_width - 1);
const ingaze_pos = {
x: Math.floor((scene_width - ingaze_logo_width) / 2),
y: Math.floor((scene_height - ingaze_logo_height) / 2)
};
const explosion_center_x = logo_initial_pos.x + Math.floor(logo_width / 2);
const explosion_center_y = logo_initial_pos.y + Math.floor(logo_height / 2);
// Phase 0: Stickman Walks
const walk_frames = Math.max(10, Math.floor(Math.abs(stickman_walk_target_x - stickman_initial_pos.x) / 1.0) );
let current_stickman_x = stickman_initial_pos.x;
const walk_step_x = walk_frames > 0 ? (stickman_walk_target_x - stickman_initial_pos.x) / walk_frames : 0;
for (let i = 0; i < walk_frames; i++) {
current_stickman_x += walk_step_x;
const walk_art = (i % 4 < 2) ? stick_man_art_walk_1 : stick_man_art_walk_2;
sequence.push(buildSceneFrame(walk_art, { x: Math.round(current_stickman_x), y: stickman_base_y }, true, linked_in_art, logo_initial_pos, false,0,0,0, [], {}, false, [], {}));
}
current_stickman_x = stickman_walk_target_x;
let current_stickman_pos = { x: Math.round(current_stickman_x), y: stickman_base_y };
// Phase 1: Pause
for (let i = 0; i < 3; i++) {
sequence.push(buildSceneFrame(stick_man_art_normal, current_stickman_pos, true, linked_in_art, logo_initial_pos, false,0,0,0, [], {}, false, [], {}));
}
// Phase 2: Shaking & Data Fall
let current_logo_pos_phase2 = { ...logo_initial_pos };
const shake_frames = 20; // Reduced shake frames
for (let i = 0; i < shake_frames; i++) {
let logoAdj = { x: 0, y: 0 };
if (i % 6 < 2) logoAdj = { x: 1, y: 0 }; else if (i % 6 < 4) logoAdj = { x: -1, y: 0 };
current_logo_pos_phase2.x = logo_initial_pos.x + logoAdj.x;
if (i % 3 === 0) spawnNewDataParticle(current_logo_pos_phase2.x, current_logo_pos_phase2.y, logo_width);
data_particles_state.forEach(p => {
if (p.active) { p.y += p.vy; if (p.y >= FLOOR_LEVEL) { p.y = FLOOR_LEVEL; p.vy = 0; p.active = false; } }
});
sequence.push(buildSceneFrame(stick_man_art_normal, current_stickman_pos, true, linked_in_art, current_logo_pos_phase2, false,0,0,0, [], {}, false, [], {}));
}
current_logo_pos_phase2 = { ...logo_initial_pos };
// Phase 3: Data Settles, Stickman Surprised
const settle_frames = 8;
for (let i = 0; i < settle_frames; i++) {
let stickmanArtPhase3 = (i < settle_frames / 2) ? stick_man_art_normal : stick_man_art_surprise;
data_particles_state.forEach(p => {
if (p.active) { p.y += p.vy; if (p.y >= FLOOR_LEVEL) { p.y = FLOOR_LEVEL; p.vy = 0; p.active = false; } }
});
sequence.push(buildSceneFrame(stickmanArtPhase3, current_stickman_pos, true, linked_in_art, logo_initial_pos, false,0,0,0, [], {}, false, [], {}));
}
// Phase 4: Lightning Strike
const lightning_target_y = logo_initial_pos.y;
const lightning_strike_frames = lightning_target_y + 2;
const lightning_bolt_length = 4;
const lightning_tip_x_strike = logo_initial_pos.x + Math.floor(logo_width / 2);
for (let i = 0; i < lightning_strike_frames; i++) {
current_lightning_y_state = i; // This is the tip's current y as it descends
let logo_art_to_use = linked_in_art;
if (current_lightning_y_state >= lightning_target_y) {
logo_art_to_use = linked_in_art_hit;
current_lightning_y_state = lightning_target_y; // Hold at target
}
sequence.push(buildSceneFrame(stick_man_art_surprise, current_stickman_pos, true, logo_art_to_use, logo_initial_pos, true, lightning_tip_x_strike, current_lightning_y_state, lightning_bolt_length, [], {}, false, [], {}));
}
current_lightning_y_state = -1; // Reset lightning state
// Phase 5: Explosion
const explosion_duration_per_frame = 2;
let stickman_art_explosion = stick_man_art_surprise;
for (let i = 0; i < explosion_art_frames.length; i++) {
const explosion_art = explosion_art_frames[i];
const explosion_art_width = Math.max(...explosion_art.map(l => l.length));
const explosion_art_height = explosion_art.length;
const current_explosion_pos = {
x: explosion_center_x - Math.floor(explosion_art_width / 2),
y: explosion_center_y - Math.floor(explosion_art_height / 2)
};
for (let j = 0; j < explosion_duration_per_frame; j++) {
if (i === 0 && j === 0) {
data_particles_state = [];
stickman_art_explosion = stick_man_art_gone;
}
sequence.push(buildSceneFrame(stickman_art_explosion, current_stickman_pos, false, [], {}, false,0,0,0, explosion_art, current_explosion_pos, false, [], {}));
}
}
// Phase 6: "Ingaze" Logo Reveal
const ingaze_reveal_pause_frames = 4;
for(let i=0; i < ingaze_reveal_pause_frames; i++) {
sequence.push(buildSceneFrame(stick_man_art_gone, current_stickman_pos, false, [], {}, false,0,0,0, [], {}, false, [], {}));
}
const ingaze_display_frames = 25;
for (let i = 0; i < ingaze_display_frames; i++) {
sequence.push(buildSceneFrame(stick_man_art_gone, current_stickman_pos, false, [], {}, false,0,0,0, [], {}, true, ingaze_logo_art, ingaze_pos));
}
return sequence;
}
// --- Animation Player ---
const animationElement = document.getElementById('cmd-animation');
let currentFrameIndex = 0;
let animationIntervalId;
let allAnimationFrames = [];
function runAnimation() {
if (!animationElement) {
console.error("Animation element 'cmd-animation' not found.");
return;
}
if (allAnimationFrames.length === 0) {
console.error("Animation frames are empty. Cannot play animation.");
animationElement.textContent = "Error: No frames.";
return;
}
animationIntervalId = setInterval(() => {
if (allAnimationFrames[currentFrameIndex]) {
animationElement.textContent = allAnimationFrames[currentFrameIndex];
}
currentFrameIndex++;
if (currentFrameIndex >= allAnimationFrames.length) {
currentFrameIndex = 0; // Loop animation
}
}, frameDuration);
}
function initializeAnimation() {
if (!animationElement) {
// console.warn("Animation element not ready yet in initializeAnimation.");
return; // Element not ready
}
try {
allAnimationFrames = generateAnimationFrames();
if (allAnimationFrames.length > 0 && animationElement) {
animationElement.textContent = allAnimationFrames[0];
runAnimation();
} else if (animationElement) {
animationElement.textContent = "Error: Could not generate animation frames.";
}
} catch (error) {
console.error("Error during animation generation or initial play:", error);
if(animationElement) animationElement.textContent = "Error initializing: " + error.message;
}
}
// Start animation once DOM is ready
if (document.readyState === "complete" || document.readyState === "interactive") {
// DOM already loaded
setTimeout(initializeAnimation, 0); // Use setTimeout to ensure it runs after current execution block
} else {
document.addEventListener('DOMContentLoaded', initializeAnimation);
}
// Clean up interval when the window/iframe is unloaded
window.addEventListener('unload', () => {
if (animationIntervalId) {
clearInterval(animationIntervalId);
}
});
</script>
</body>
</html>
|