(function(){ // Demo addition (§9.11-style): render the game's OWN load progress as a real, // visible bar on the splash. // // The original splash shows only a bouncing ball + a paddle that slides back and // forth on a 3s loop (`animation:paddleMove` — purely decorative), and its // `.preloader-counter` is `display:none`, so the user gets ZERO feedback that // anything is loading. The game's preloader controller already tracks progress // (0..1) and writes it as "00".."100" into `.preloader-counter`, then fades the // splash at 100. We piggyback on that authoritative value instead of byte-counting // the network: the two giant textures (~16.8 MiB of the ~22 MiB first load) are // loaded via `new Image`/`loadTexture`, not `fetch`, so a fetch-level counter // would never see them — the game's task-weighted counter does. // // We read the counter the game is already writing and drive a fill width. No game // bundle is modified; a no-op on pages without a preloader (e.g. the 404 shell). var pre=document.getElementById('preloader'); var counter=pre&&pre.querySelector('.preloader-counter'); if(!pre||!counter)return; var racket=pre.querySelector('.tennis-racket'); var ball=pre.querySelector('.ball-wrapper'); if(!racket)return; var track=document.createElement('div'); track.id='ww-loader-track'; var fill=document.createElement('div'); fill.id='ww-loader-fill'; track.appendChild(fill); racket.appendChild(track); // Sit just below the ball, horizontally centered — robust to the responsive // top offsets the preloader CSS applies to the paddle/racket. function place(){ track.style.top=(ball?(ball.offsetTop+ball.offsetHeight+16):30)+'px'; } place(); window.addEventListener('resize',place); var css=document.createElement('style'); css.textContent="#ww-loader-track{position:absolute;left:50%;transform:translateX(-50%);width:200px;height:8px;border-radius:4px;background:rgba(255,255,255,.14);box-shadow:inset 0 0 0 .715px rgba(255,255,255,.28);overflow:hidden;pointer-events:none}"+ "#ww-loader-fill{width:0%;height:100%;border-radius:4px;background:linear-gradient(90deg,#eef2f7 0%,#ff5f6d 100%);transition:width .18s linear}"; (document.head||pre).appendChild(css); function set(){ var p=parseInt(counter.textContent,10); if(isNaN(p))p=0; var v=p/100; if(v>1)v=1; fill.style.width=(v*100)+'%'; if(v>=1){clearInterval(tick);setTimeout(function(){track.remove();css.remove();},2500);} } var tick=setInterval(set,40); setTimeout(function(){clearInterval(tick);set();},30000); // safety net set(); })();