const canvas = document.getElementById('rt-canvas');
const ctx = canvas.getContext('2d');
function resize() {
const r = canvas.getBoundingClientRect();
canvas.width = Math.round(r.width * devicePixelRatio);
canvas.height = Math.round(r.height * devicePixelRatio);
}
addEventListener('resize', resize); resize();
const cam = { x: 0.08, y: 0.5 };
const screenX = 0.3;
const sphere = { x: 0.64, y: 0.52, r: 0.15 };
const light = { x: 0.92, y: 0.14 };
const N = 6;
function draw(t) {
const w = canvas.width, h = canvas.height;
ctx.clearRect(0, 0, w, h);
const P = (nx, ny) => [nx * w, ny * h];
ctx.strokeStyle = '#5f5f70';
ctx.lineWidth = Math.max(1, w * 0.002);
ctx.beginPath();
const [x0, y0] = P(screenX, 0.16), [x1, y1] = P(screenX, 0.84);
ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke();
const [cx, cy] = P(cam.x, cam.y);
const [lx, ly] = P(light.x, light.y);
const [scx, scy] = P(sphere.x, sphere.y);
const rad = sphere.r * Math.min(w, h);
ctx.fillStyle = '#ffd27a'; ctx.beginPath(); ctx.arc(lx, ly, Math.max(4, w * 0.01), 0, Math.PI * 2); ctx.fill();
ctx.fillStyle = '#3a4a72'; ctx.beginPath(); ctx.arc(scx, scy, rad, 0, Math.PI * 2); ctx.fill();
ctx.fillStyle = '#e7ebff'; ctx.beginPath(); ctx.arc(cx, cy, Math.max(3, w * 0.008), 0, Math.PI * 2); ctx.fill();
const active = Math.floor(t / 700) % N;
for (let i = 0; i < N; i++) {
const py = 0.2 + (i / (N - 1)) * 0.6;
const [px, pyp] = P(screenX, py);
let dx = px - cx, dy = pyp - cy;
const dl = Math.hypot(dx, dy) || 1; dx /= dl; dy /= dl;
const on = i === active;
ctx.globalAlpha = on ? 1 : 0.3;
ctx.lineWidth = on ? Math.max(2, w * 0.003) : Math.max(1, w * 0.0015);
ctx.strokeStyle = '#7c8cff';
const ox = cx - scx, oy = cy - scy;
const b = 2 * (dx * ox + dy * oy);
const c = ox * ox + oy * oy - rad * rad;
const disc = b * b - 4 * c;
let hx = px, hy = pyp, reflected = null;
if (disc >= 0) {
const th = (-b - Math.sqrt(disc)) / 2;
if (th > 0) {
hx = cx + dx * th; hy = cy + dy * th;
const nx = (hx - scx) / rad, ny = (hy - scy) / rad;
const dDot = dx * nx + dy * ny;
reflected = [dx - 2 * dDot * nx, dy - 2 * dDot * ny];
}
}
ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(hx, hy); ctx.stroke();
if (reflected) {
ctx.setLineDash(on ? [] : [4, 4]);
ctx.beginPath(); ctx.moveTo(hx, hy); ctx.lineTo(hx + reflected[0] * w * 0.32, hy + reflected[1] * w * 0.32); ctx.stroke();
ctx.setLineDash([]);
if (on) { ctx.fillStyle = '#ff8fb0'; ctx.beginPath(); ctx.arc(hx, hy, Math.max(2, w * 0.006), 0, Math.PI * 2); ctx.fill(); }
}
}
ctx.globalAlpha = 1;
requestAnimationFrame(draw);
}
requestAnimationFrame(draw);