SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,338
Folders
408
Scanned Size
3.84 GB
PHP Files
890
Editable Text Files
12,599
File viewer
guarded to /htdocs
/arcade/index.php
<?php /** * /arcade/index.php — SIMON ARCADE 3D / SIMS-EFFECT DESIGN * PHP 8.0+ compatible. Drop into /arcade/index.php. * Auto-discovers /arcade/games/*.php|*.html|*.htm and tracks every game/menu click. */ declare(strict_types=1); $inc = __DIR__ . '/../_inc/app.php'; if (is_file($inc)) { require $inc; } if (!function_exists('h')) { function h($v): string { return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } } /* Shared telemetry config */ $SIMON = [ 'GA4_ID' => 'G-S6MEHB4BEY', 'IMPACT_VERIFICATION' => 'e8ec6683-663c-421a-a30d-f8c0fe517345', 'WEBHOOK_BASE' => '/connlink/test1/ui/webhook_inbox.php', 'VISIT_STREAM' => 'visits', 'PULSE_STREAM' => 'default', 'KEY' => '', 'SOURCE' => 'arcade-index-sims-simon-effects.php', ]; $gaFile = __DIR__ . '/../_inc/_ga.php'; if (is_file($gaFile)) { $maybe = trim((string)require $gaFile); if ($maybe !== '') { $SIMON['GA4_ID'] = $maybe; } } $ARCADE = [ 'name' => 'SIMON ARCADE', 'tagline' => 'Play • Build • Evolve', 'desc' => '3D browser games, spatial menu intelligence, and SIMON telemetry capture.', 'links' => [ 'Home' => '/', 'Books' => '/books/', 'Art' => '/art/', 'Comics' => '/comics/', 'Infinity' => '/infinity/', 'Kosmos' => '/kosmos/', ], ]; $gamesDirAbs = __DIR__ . '/games'; $gamesDirWeb = '/arcade/games'; $GAMES = []; if (is_dir($gamesDirAbs)) { foreach ((scandir($gamesDirAbs) ?: []) as $f) { if ($f === '.' || $f === '..' || $f[0] === '.') { continue; } $ext = strtolower(pathinfo($f, PATHINFO_EXTENSION)); if (!in_array($ext, ['php','html','htm'], true)) { continue; } $slug = pathinfo($f, PATHINFO_FILENAME); if ($slug === 'index') { continue; } $title = ucwords(str_replace(['-', '_'], ' ', $slug)); $thumb = ''; foreach (['webp','jpg','jpeg','png','gif'] as $tx) { $cand = __DIR__ . '/thumbs/' . $slug . '.' . $tx; if (is_file($cand)) { $thumb = '/arcade/thumbs/' . rawurlencode($slug . '.' . $tx); break; } } $GAMES[] = [ 'slug' => $slug, 'title' => $title, 'href' => $gamesDirWeb . '/' . rawurlencode($f), 'thumb' => $thumb, 'ext' => strtoupper($ext), ]; } usort($GAMES, fn($a,$b) => strcmp($a['title'], $b['title'])); } $REEL = ['PLAY','BUILD','EVOLVE','3D MENU','SIMON CAPTURE','GAME CLICKS','PULSE STREAM','ARCADE MODE','KOSMOS READY','SPATIAL UI']; ?><!doctype html> <html lang="en" data-app="simon-arcade" data-system="SIMON"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"> <meta name="theme-color" content="#060914"> <meta name="description" content="<?= h($ARCADE['desc']) ?>"> <meta name="impact-site-verification" value="<?= h($SIMON['IMPACT_VERIFICATION']) ?>"> <title><?= h($ARCADE['name']) ?> — <?= h($ARCADE['tagline']) ?></title> <link rel="canonical" href="https://www.gaylordsinclair.com/arcade/"> <?php if ($SIMON['GA4_ID'] !== ''): ?> <script async src="https://www.googletagmanager.com/gtag/js?id=<?= h($SIMON['GA4_ID']) ?>"></script> <script> window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)} gtag('js',new Date());gtag('config',<?= json_encode($SIMON['GA4_ID']) ?>,{anonymize_ip:true,send_page_view:true}); </script> <?php endif; ?> <style> :root{ --bg:#030510;--bg2:#090d20;--ink:#ecf6ff;--muted:#aab8d8;--glass:rgba(255,255,255,.075); --line:rgba(255,255,255,.15);--cyan:#63e7ff;--blue:#6f7dff;--pink:#ff54dd;--gold:#ffdc83;--green:#57ff9b; --panelW:min(440px,88vw);--safeB:env(safe-area-inset-bottom,0px);--safeT:env(safe-area-inset-top,0px) } *{box-sizing:border-box}html,body{height:100%;width:100%}body{margin:0;overflow:hidden;color:var(--ink);font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;background:#000;perspective:1200px;-webkit-font-smoothing:antialiased}a,button{-webkit-tap-highlight-color:transparent}button{font:inherit;color:inherit} .bg{position:fixed;inset:0;z-index:0;overflow:hidden;background:radial-gradient(circle at 50% 30%,rgba(111,125,255,.24),transparent 34%),linear-gradient(180deg,var(--bg),var(--bg2))}.bg video,.bg .poster{position:absolute;inset:-3%;width:106%;height:106%;object-fit:cover;filter:saturate(1.25) contrast(1.15) brightness(.62);transform:scale(1.04)}.poster{background:url('/arcade/media/arcade.jpg') center/cover no-repeat;display:none}.bg:after{content:"";position:absolute;inset:0;background:radial-gradient(circle at 50% 22%,rgba(87,255,155,.12),transparent 18%),radial-gradient(circle at 74% 62%,rgba(255,84,221,.16),transparent 28%),radial-gradient(circle at 25% 68%,rgba(99,231,255,.16),transparent 32%),linear-gradient(180deg,rgba(3,5,16,.18),rgba(3,5,16,.92))}.grid3d{position:fixed;inset:auto -12vw -20vh -12vw;height:52vh;z-index:1;pointer-events:none;background-image:linear-gradient(rgba(99,231,255,.14) 1px,transparent 1px),linear-gradient(90deg,rgba(99,231,255,.14) 1px,transparent 1px);background-size:54px 54px;transform:rotateX(68deg);transform-origin:50% 100%;filter:drop-shadow(0 0 20px rgba(99,231,255,.18));animation:gridDrift 12s linear infinite}@keyframes gridDrift{to{background-position:0 54px,54px 0}} #fx{position:fixed;inset:0;z-index:2;pointer-events:none}.simGlyphs{position:fixed;inset:0;z-index:3;pointer-events:none;overflow:hidden}.glyph{position:absolute;display:block;width:22px;height:38px;background:linear-gradient(180deg,var(--green),#b9ff7c 48%,var(--cyan));clip-path:polygon(50% 0,100% 28%,50% 100%,0 28%);opacity:.2;filter:drop-shadow(0 0 18px rgba(87,255,155,.5));animation:plumb 8s linear forwards}@keyframes plumb{0%{transform:translate3d(var(--x),110vh,0) rotateZ(0deg) scale(.8);opacity:0}15%{opacity:.28}70%{opacity:.2}100%{transform:translate3d(calc(var(--x) + var(--dx)),-15vh,0) rotateZ(360deg) scale(1.8);opacity:0}} .hud{position:fixed;inset:calc(16px + var(--safeT)) 18px auto 18px;z-index:20;display:flex;align-items:center;justify-content:space-between;gap:14px;pointer-events:none}.brand{pointer-events:auto;transform-style:preserve-3d}.brand h1{margin:0;font-size:clamp(22px,4vw,54px);line-height:.9;letter-spacing:.16em;text-transform:uppercase;text-shadow:0 0 24px rgba(99,231,255,.35),0 0 70px rgba(255,84,221,.22);transform:translateZ(38px)}.brand p{margin:8px 0 0;color:var(--muted);font-size:12px;letter-spacing:.14em;text-transform:uppercase}.status{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}.chip{pointer-events:auto;border:1px solid var(--line);background:rgba(255,255,255,.06);backdrop-filter:blur(18px);border-radius:999px;padding:9px 12px;font-size:11px;text-transform:uppercase;letter-spacing:.12em;box-shadow:0 18px 60px rgba(0,0,0,.25)}.chip b{color:var(--green)} .stage{position:relative;z-index:10;height:100%;display:grid;place-items:center;padding:110px 20px 34px}.core{width:min(980px,94vw);height:min(560px,66vh);min-height:420px;position:relative;transform-style:preserve-3d;animation:coreFloat 5.6s ease-in-out infinite}@keyframes coreFloat{50%{transform:translateY(-10px) rotateX(2deg)}}.portal{position:absolute;inset:0;border-radius:42px;border:1px solid rgba(255,255,255,.16);background:linear-gradient(135deg,rgba(255,255,255,.09),rgba(255,255,255,.025));box-shadow:0 40px 140px rgba(0,0,0,.65),inset 0 0 80px rgba(99,231,255,.08);backdrop-filter:blur(20px);transform:rotateX(7deg) rotateY(-8deg);overflow:hidden}.portal:before{content:"";position:absolute;inset:-40%;background:conic-gradient(from 0deg,transparent,rgba(99,231,255,.22),transparent,rgba(255,84,221,.20),transparent,rgba(87,255,155,.16),transparent);animation:spin 12s linear infinite;opacity:.75}.portal:after{content:"";position:absolute;inset:1px;border-radius:41px;background:radial-gradient(circle at 50% 35%,rgba(255,255,255,.12),transparent 22%),linear-gradient(180deg,rgba(6,9,20,.24),rgba(6,9,20,.74))}@keyframes spin{to{transform:rotate(360deg)}}.center{position:absolute;inset:0;display:grid;place-items:center;z-index:2;text-align:center;padding:40px;transform:translateZ(80px)}.diamond{width:120px;height:190px;clip-path:polygon(50% 0,100% 28%,50% 100%,0 28%);background:linear-gradient(180deg,var(--green),#e6ff8c 42%,var(--cyan));filter:drop-shadow(0 0 24px rgba(87,255,155,.75)) drop-shadow(0 0 80px rgba(99,231,255,.35));animation:diamond 2.2s ease-in-out infinite;opacity:.95}@keyframes diamond{50%{transform:translateY(-14px) rotateY(34deg) rotateZ(2deg);filter:drop-shadow(0 0 36px rgba(87,255,155,.95)) drop-shadow(0 0 110px rgba(99,231,255,.50))}}.title3d{font-size:clamp(46px,8vw,118px);font-weight:1000;letter-spacing:.12em;line-height:.86;text-transform:uppercase;margin:22px 0 6px;text-shadow:0 2px 0 rgba(255,255,255,.18),0 12px 22px rgba(0,0,0,.55),0 0 55px rgba(99,231,255,.28)}.reel{min-height:34px;color:rgba(236,246,255,.86);font-weight:850;letter-spacing:.18em;text-transform:uppercase}.hint{margin-top:18px;color:var(--muted);font-size:13px;letter-spacing:.1em;text-transform:uppercase} .orb{position:fixed;right:22px;bottom:calc(22px + var(--safeB));z-index:55;width:92px;height:92px;border:1px solid rgba(255,255,255,.18);border-radius:30px;background:linear-gradient(135deg,rgba(255,255,255,.13),rgba(255,255,255,.035));box-shadow:0 28px 90px rgba(0,0,0,.55),0 0 80px rgba(99,231,255,.18);backdrop-filter:blur(18px);cursor:pointer;display:grid;place-items:center;overflow:hidden;transform-style:preserve-3d}.orb:before{content:"";position:absolute;inset:-70%;background:conic-gradient(var(--cyan),var(--blue),var(--pink),var(--green),var(--cyan));animation:spin 4s linear infinite;opacity:.42}.orb:after{content:"I";position:relative;font-size:46px;font-weight:1000;text-shadow:0 0 30px rgba(99,231,255,.8);transform:translateZ(25px)}.orb:hover{transform:translateY(-3px) rotateX(8deg) rotateY(-10deg)} .drawer{position:fixed;left:0;top:0;bottom:0;z-index:50;width:var(--panelW);transform:translateX(calc(-100% + 18px));transition:transform .26s ease;transform-style:preserve-3d}.drawer.open{transform:translateX(0)}.tab{position:absolute;left:calc(100% - 18px);top:50%;translate:0 -50%;width:58px;height:178px;border:1px solid var(--line);border-left:0;border-radius:0 22px 22px 0;background:linear-gradient(180deg,rgba(255,255,255,.13),rgba(255,255,255,.035));box-shadow:0 24px 90px rgba(0,0,0,.55);backdrop-filter:blur(18px);cursor:pointer;display:grid;place-items:center}.tab span{writing-mode:vertical-rl;rotate:180deg;font-size:12px;font-weight:950;letter-spacing:.22em;text-transform:uppercase}.panel{height:100%;overflow:auto;padding:18px 18px calc(24px + var(--safeB));background:linear-gradient(180deg,rgba(7,11,28,.82),rgba(5,8,18,.68));border-right:1px solid var(--line);backdrop-filter:blur(24px);box-shadow:30px 0 120px rgba(0,0,0,.55)}.card{border:1px solid rgba(255,255,255,.13);background:linear-gradient(135deg,rgba(255,255,255,.08),rgba(255,255,255,.025));border-radius:24px;padding:16px;margin-bottom:12px;box-shadow:0 22px 70px rgba(0,0,0,.32);transform-style:preserve-3d}.card h2{margin:0 0 10px;font-size:13px;text-transform:uppercase;letter-spacing:.16em}.card p{margin:0;color:var(--muted);line-height:1.45;font-size:14px}.menuList,.games{display:grid;gap:10px;margin-top:12px}.menuA,.game{position:relative;text-decoration:none;color:var(--ink);border:1px solid rgba(255,255,255,.13);background:linear-gradient(135deg,rgba(255,255,255,.075),rgba(255,255,255,.02));border-radius:18px;overflow:hidden;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease;transform-style:preserve-3d}.menuA{display:flex;align-items:center;justify-content:space-between;padding:13px 14px}.menuA:hover,.game:hover{transform:translateY(-3px) rotateX(5deg) rotateY(-5deg);border-color:rgba(99,231,255,.42);box-shadow:0 18px 60px rgba(99,231,255,.12)}.game{display:grid;grid-template-columns:108px 1fr;min-height:82px}.thumb{background:radial-gradient(circle at 30% 20%,rgba(87,255,155,.28),transparent 32%),radial-gradient(circle at 70% 70%,rgba(255,84,221,.20),transparent 40%),linear-gradient(135deg,rgba(99,231,255,.12),rgba(255,255,255,.025))}.thumb img{width:100%;height:100%;object-fit:cover;display:block;filter:saturate(1.15) contrast(1.1)}.gbody{padding:12px}.gtitle{font-weight:950}.gmeta{margin-top:8px;color:var(--muted);font-size:12px;display:flex;justify-content:space-between;gap:10px}.empty{color:var(--muted);font-size:14px;line-height:1.5}.mini{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.pill{border:1px solid rgba(255,255,255,.13);border-radius:999px;padding:7px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:rgba(236,246,255,.82);background:rgba(255,255,255,.05)} body.idle .hud{opacity:.22}body.idle .drawer.open{transform:translateX(calc(-100% + 18px))}@media(max-width:760px){.hud{align-items:flex-start}.status{display:none}.brand h1{font-size:25px}.stage{padding-top:96px}.core{height:62vh;min-height:380px}.diamond{width:86px;height:138px}.orb{width:76px;height:76px;border-radius:24px}.game{grid-template-columns:92px 1fr}.title3d{font-size:48px}.hint{font-size:11px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}} </style> <script>window.SIMON_CONFIG=<?= json_encode($SIMON, JSON_UNESCAPED_SLASHES) ?>;</script> </head> <body class="idle"> <div class="bg" aria-hidden="true"><video id="bgvid" autoplay muted loop playsinline preload="metadata" poster="/arcade/media/arcade.jpg"><source src="/arcade/media/arcade.mp4" type="video/mp4"></video><div id="poster" class="poster"></div></div> <div class="grid3d" aria-hidden="true"></div><canvas id="fx" aria-hidden="true"></canvas><div id="simGlyphs" class="simGlyphs" aria-hidden="true"></div> <header class="hud"><div class="brand"><h1><?= h($ARCADE['name']) ?></h1><p><?= h($ARCADE['tagline']) ?></p></div><div class="status"><span class="chip"><b>●</b> telemetry</span><span class="chip">games <?= (int)count($GAMES) ?></span><span class="chip">3D spatial</span></div></header> <nav class="drawer" id="drawer" aria-label="Arcade menu"><button class="tab" id="tab" type="button" aria-label="Open arcade menu"><span>MENU</span></button><div class="panel"> <section class="card"><h2>SIMON Arcade</h2><p><?= h($ARCADE['desc']) ?></p><div class="mini"><span class="pill">GA4</span><span class="pill">Webhook</span><span class="pill">Game Clicks</span><span class="pill">SIMON Effect</span></div></section> <section class="card"><h2>Core Links</h2><div class="menuList"><?php foreach($ARCADE['links'] as $label=>$href): ?><a class="menuA" href="<?= h($href) ?>" data-menu-link="<?= h($label) ?>"><span><?= h($label) ?></span><b>→</b></a><?php endforeach; ?><a class="menuA" href="/arcade/games/" data-menu-link="All Games Folder"><span>All Games Folder</span><b>→</b></a></div></section> <section class="card"><h2>Games</h2><p>Every game click below is captured by GA4 and the SIMON webhook.</p><?php if(!$GAMES): ?><div class="empty" style="margin-top:12px">No games found. Add files to <b>/arcade/games/</b> and optional thumbnails to <b>/arcade/thumbs/</b>.</div><?php else: ?><div class="games"><?php foreach($GAMES as $g): ?><a class="game" href="<?= h($g['href']) ?>" data-game="<?= h($g['slug']) ?>" data-game-title="<?= h($g['title']) ?>"><div class="thumb"><?php if($g['thumb']): ?><img src="<?= h($g['thumb']) ?>" alt="<?= h($g['title']) ?> thumbnail" loading="lazy"><?php endif; ?></div><div class="gbody"><div class="gtitle"><?= h($g['title']) ?></div><div class="gmeta"><span><?= h($g['ext']) ?></span><span><?= h($g['slug']) ?></span></div></div></a><?php endforeach; ?></div><?php endif; ?></section> </div></nav> <main class="stage"><section class="core" id="core"><div class="portal"></div><div class="center"><div><div class="diamond" aria-hidden="true"></div><div class="title3d">PLAY</div><div class="reel" id="reel">SIMON CAPTURE ONLINE</div><div class="hint">Tap menu. Pick a game. Every click becomes signal.</div></div></div></section></main><button class="orb" id="orb" type="button" aria-label="Open SIMON menu"></button> <script> (()=>{ const CFG=window.SIMON_CONFIG||{};const drawer=document.getElementById('drawer');const tab=document.getElementById('tab');const orb=document.getElementById('orb');const reel=document.getElementById('reel');const glyphs=document.getElementById('simGlyphs');const bgvid=document.getElementById('bgvid');const poster=document.getElementById('poster');const canvas=document.getElementById('fx');const ctx=canvas.getContext('2d',{alpha:true}); const REEL=<?= json_encode($REEL, JSON_UNESCAPED_SLASHES) ?>;let ri=0,idle=null,mx=innerWidth/2,my=innerHeight/2; function key(){return CFG.KEY?('&key='+encodeURIComponent(CFG.KEY)):''} function endpoint(stream){return (CFG.WEBHOOK_BASE||'/connlink/test1/ui/webhook_inbox.php')+'?stream='+encodeURIComponent(stream||CFG.PULSE_STREAM||'default')+key()} function track(event,data){data=data||{};const payload={title:event,summary:data.title||data.label||data.slug||event,event:event,data:data,url:location.href,path:location.pathname,source:CFG.SOURCE||'arcade',screen:innerWidth+'x'+innerHeight,tz:(Intl.DateTimeFormat().resolvedOptions().timeZone||'Local'),at:new Date().toISOString(),ua:navigator.userAgent};try{if(window.gtag){gtag('event',event,{event_category:'SIMON Arcade',event_label:data.title||data.label||data.slug||'',game_slug:data.slug||'',menu_label:data.label||'',transport_type:'beacon'});}const body=JSON.stringify(payload);if(navigator.sendBeacon){navigator.sendBeacon(endpoint(CFG.PULSE_STREAM),new Blob([body],{type:'application/json'}));}else{fetch(endpoint(CFG.PULSE_STREAM),{method:'POST',headers:{'Content-Type':'application/json'},body,keepalive:true}).catch(()=>{});}}catch(e){}} function visit(){track('arcade_page_view',{title:document.title,games:<?= (int)count($GAMES) ?>});try{fetch(endpoint(CFG.VISIT_STREAM||'visits'),{method:'POST',headers:{'Content-Type':'application/json'},keepalive:true,body:JSON.stringify({title:'Visit · '+document.title,summary:document.referrer||navigator.userAgent,url:location.href,at:new Date().toISOString(),source:CFG.SOURCE||'arcade',screen:innerWidth+'x'+innerHeight})}).catch(()=>{});}catch(e){}} function active(){document.body.classList.remove('idle');clearTimeout(idle);idle=setTimeout(()=>{document.body.classList.add('idle');drawer.classList.remove('open')},4200)} ['pointermove','pointerdown','touchstart','keydown','wheel'].forEach(e=>addEventListener(e,active,{passive:true}));active(); function toggle(force){const on=typeof force==='boolean'?force:!drawer.classList.contains('open');drawer.classList.toggle('open',on);track('arcade_menu_toggle',{open:on});burst(5)} tab.addEventListener('click',e=>{e.preventDefault();toggle()});orb.addEventListener('click',e=>{e.preventDefault();toggle(true);track('simon_orb_click',{});burst(12)});addEventListener('pointerdown',e=>{if(drawer.classList.contains('open')&&!drawer.contains(e.target)&&e.target!==orb)drawer.classList.remove('open')},{passive:true}); document.querySelectorAll('[data-menu-link]').forEach(a=>a.addEventListener('click',()=>track('arcade_menu_link_click',{label:a.dataset.menuLink||'',href:a.href,title:a.textContent.trim()}))); document.querySelectorAll('[data-game]').forEach(a=>a.addEventListener('click',()=>track('arcade_game_click',{slug:a.dataset.game||'',title:a.dataset.gameTitle||a.textContent.trim(),href:a.href}))); setInterval(()=>{reel.textContent=REEL[ri++%REEL.length];burst(1)},1600); function burst(n){for(let i=0;i<n;i++)setTimeout(()=>glyph(),i*70)}function glyph(){if(!glyphs)return;const g=document.createElement('i');g.className='glyph';g.style.setProperty('--x',Math.random()*100+'vw');g.style.setProperty('--dx',(Math.random()*44-22)+'vw');glyphs.appendChild(g);setTimeout(()=>g.remove(),8200)}setInterval(()=>glyph(),900); if(bgvid){const p=()=>{if(poster)poster.style.display='block'};['error','stalled','abort'].forEach(e=>bgvid.addEventListener(e,p));} function resize(){const d=Math.min(2,devicePixelRatio||1);canvas.width=innerWidth*d;canvas.height=innerHeight*d;canvas.style.width=innerWidth+'px';canvas.style.height=innerHeight+'px';ctx.setTransform(d,0,0,d,0,0)}addEventListener('resize',resize,{passive:true});resize();addEventListener('pointermove',e=>{mx=e.clientX;my=e.clientY},{passive:true}); const pts=[];function seed(){pts.length=0;for(let i=0;i<Math.min(260,Math.max(140,innerWidth/7));i++)pts.push({x:Math.random()*innerWidth,y:Math.random()*innerHeight,z:Math.random(),r:.6+Math.random()*2.4,v:.15+Math.random()*.65,a:.1+Math.random()*.45,h:Math.random()*360})}seed();addEventListener('resize',seed,{passive:true}); function draw(t){ctx.clearRect(0,0,innerWidth,innerHeight);const cx=innerWidth/2,cy=innerHeight/2;let grd=ctx.createRadialGradient(mx,my,20,cx,cy,Math.max(innerWidth,innerHeight)*.72);grd.addColorStop(0,'rgba(87,255,155,.13)');grd.addColorStop(.35,'rgba(99,231,255,.08)');grd.addColorStop(1,'rgba(255,84,221,0)');ctx.fillStyle=grd;ctx.fillRect(0,0,innerWidth,innerHeight);for(const p of pts){p.y-=p.v*(.3+p.z);p.x+=Math.sin((t*.001)+p.z*10)*.12+(mx-cx)*.00004;if(p.y<-20){p.y=innerHeight+20;p.x=Math.random()*innerWidth}if(p.x<-20)p.x=innerWidth+20;if(p.x>innerWidth+20)p.x=-20;const tw=.55+.45*Math.sin(t*.002+p.z*20);ctx.beginPath();ctx.arc(p.x,p.y,p.r*(.8+p.z*1.2)*tw,0,Math.PI*2);ctx.fillStyle=`hsla(${p.h},100%,72%,${p.a*tw})`;ctx.fill();}requestAnimationFrame(draw)}requestAnimationFrame(draw);visit(); })(); </script> </body> </html>
Save file
Quick jump
open a path
Open