A beacon emits repeating expanding rings on a timer; rings brighten nearby dots when they pass, proving timed signaling.


Code for Above

<div style="max-width:1500px;margin:0 auto;">
<iframe
  title="POC — Pulse Beacon"
  scrolling="no"
  style="width:1500px;height:1500px;border:0;display:block;background:#000;border-radius:14px;box-shadow:0 20px 60px rgba(0,0,0,.5);"
  sandbox="allow-scripts allow-same-origin"
  srcdoc='
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>POC — Pulse Beacon</title>
<style>
  html, body { margin:0; width:100%; height:100%; overflow:hidden; background:#000; }
  canvas { display:block; outline:none; cursor:crosshair; }
  .hint { position:absolute; left:12px; bottom:12px; color:#aaa; font:14px system-ui; user-select:none; }
</style>
</head>
<body>
<canvas id="c" width="1500" height="1500"></canvas>
<div class="hint">Click: place beacon • Beacon pulses automatically</div>

<script>
const c = document.getElementById("c");
const x = c.getContext("2d");
const W = 1500, H = 1500;

function pos(e){
  const r = c.getBoundingClientRect();
  return {
    x: (e.clientX - r.left) * (c.width / r.width),
    y: (e.clientY - r.top)  * (c.height / r.height)
  };
}

// Dots that light up when ping passes
const dots = Array.from({length: 110}, () => ({
  x: Math.random()*W,
  y: Math.random()*H,
  r: 3 + Math.random()*8,
  glow: 0
}));

// Beacon + pulses
let beacon = { x: W/2, y: H/2 };
const pulses = [];

const PULSE_EVERY = 70;     // frames between pulses
const SPEED = 16;           // radius growth
const BAND = 22;            // band thickness for detection
const GLOW_DECAY = 0.90;
const MAX_R = 2400;

let t = 0;

c.addEventListener("click", (e) => {
  const p = pos(e);
  beacon = { x: p.x, y: p.y };
  pulses.length = 0;
  t = 0;
});

function emit(){
  pulses.push({ x: beacon.x, y: beacon.y, r: 0, life: 1 });
}

function update(){
  t++;
  if (t % PULSE_EVERY === 0) emit();

  // decay dot glow
  for (const d of dots) d.glow *= GLOW_DECAY;

  // expand pulses
  for (const pg of pulses){
    pg.r += SPEED;
    pg.life *= 0.987;
  }

  // reveal dots when band hits
  for (const pg of pulses){
    for (const d of dots){
      const dist = Math.hypot(d.x - pg.x, d.y - pg.y);
      if (Math.abs(dist - pg.r) <= BAND) d.glow = 1;
    }
  }

  // cull pulses
  for (let i=pulses.length-1;i>=0;i--){
    if (pulses[i].r > MAX_R || pulses[i].life < 0.06) pulses.splice(i,1);
  }
}

function draw(){
  x.clearRect(0,0,W,H);

  // grid
  x.strokeStyle = "rgba(255,255,255,0.05)";
  for (let i=0;i<=W;i+=150){ x.beginPath(); x.moveTo(i,0); x.lineTo(i,H); x.stroke(); }
  for (let j=0;j<=H;j+=150){ x.beginPath(); x.moveTo(0,j); x.lineTo(W,j); x.stroke(); }

  // pulses
  for (const pg of pulses){
    x.strokeStyle = `rgba(255,255,255,${0.12 + pg.life*0.35})`;
    x.lineWidth = 3;
    x.beginPath();
    x.arc(pg.x, pg.y, pg.r, 0, Math.PI*2);
    x.stroke();
  }

  // dots
  for (const d of dots){
    const a = 0.10 + d.glow*0.90;
    x.fillStyle = `rgba(255,255,255,${a})`;
    x.beginPath();
    x.arc(d.x, d.y, d.r, 0, Math.PI*2);
    x.fill();
  }

  // beacon
  x.fillStyle = "#fff";
  x.beginPath(); x.arc(beacon.x, beacon.y, 6, 0, Math.PI*2); x.fill();
  x.strokeStyle = "rgba(255,255,255,0.25)";
  x.lineWidth = 2;
  x.beginPath(); x.arc(beacon.x, beacon.y, 18, 0, Math.PI*2); x.stroke();

  // HUD
  x.fillStyle = "rgba(255,255,255,0.6)";
  x.font = "14px system-ui";
  x.fillText(`pulses=${pulses.length}  interval=${PULSE_EVERY}f`, 12, 24);

  requestAnimationFrame(loop);
}

function loop(){
  update();
  draw();
}
loop();
</script>
</body>
</html>
'></iframe>
</div>