Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 30 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,7 @@ <h2 class="text-4xl md:text-5xl font-bold mb-4">Photos</h2>
MATRIX RAIN
====================================================================
*/
let matrixInterval;
let matrixAnimationId;
let isMatrixActive = false;

function toggleMatrixMode() {
Expand All @@ -1616,7 +1616,7 @@ <h2 class="text-4xl md:text-5xl font-bold mb-4">Photos</h2>
if (isMatrixActive) {
isMatrixActive = false;
body.classList.remove('matrix-mode-active');
clearInterval(matrixInterval);
cancelAnimationFrame(matrixAnimationId);
console.log('[MATRIX] Deactivated');
} else {
isMatrixActive = true;
Expand All @@ -1630,22 +1630,38 @@ <h2 class="text-4xl md:text-5xl font-bold mb-4">Photos</h2>
const fontSize = 16;
const columns = canvas.width / fontSize;
const drops = Array(Math.floor(columns)).fill(1);
let lastTime = 0;
const fpsInterval = 30; // approx 30ms per frame to match setInterval(30)
Comment on lines +1633 to +1634
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fpsInterval is in milliseconds (frame duration), but the name reads like “frames per second”. Renaming to something like frameIntervalMs (or computing it from a targetFps via 1000 / targetFps) would make the units/intent unambiguous and avoid future timing mistakes.

Copilot uses AI. Check for mistakes.

const draw = () => {
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#0F0';
ctx.font = fontSize + 'px monospace';

for (let i = 0; i < drops.length; i++) {
const text = chars.charAt(Math.floor(Math.random() * chars.length));
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) drops[i] = 0;
drops[i]++;
const draw = (currentTime) => {
if (!isMatrixActive) return;

matrixAnimationId = requestAnimationFrame(draw);

// Handle the case where currentTime is undefined (initial call)
if (currentTime === undefined) currentTime = performance.now();

if (!lastTime) lastTime = currentTime;
Comment on lines +1641 to +1644
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The currentTime === undefined fallback is unnecessary for requestAnimationFrame callbacks (the timestamp argument is always provided) and makes the flow harder to follow. Consider removing this branch and initializing/updating lastTime with explicit comparisons (e.g., lastTime === 0) to avoid relying on falsy checks.

Suggested change
// Handle the case where currentTime is undefined (initial call)
if (currentTime === undefined) currentTime = performance.now();
if (!lastTime) lastTime = currentTime;
if (lastTime === 0) lastTime = currentTime;

Copilot uses AI. Check for mistakes.
const elapsed = currentTime - lastTime;

if (elapsed > fpsInterval) {
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The throttle gate uses elapsed > fpsInterval; if elapsed lands exactly on the interval boundary, the frame will be skipped, which can introduce minor jitter. Using >= is a more robust way to enforce a fixed minimum frame interval.

Suggested change
if (elapsed > fpsInterval) {
if (elapsed >= fpsInterval) {

Copilot uses AI. Check for mistakes.
lastTime = currentTime - (elapsed % fpsInterval);

ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#0F0';
ctx.font = fontSize + 'px monospace';

for (let i = 0; i < drops.length; i++) {
const text = chars.charAt(Math.floor(Math.random() * chars.length));
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) drops[i] = 0;
drops[i]++;
}
}
};

matrixInterval = setInterval(draw, 30);
matrixAnimationId = requestAnimationFrame(draw);
}
}

Expand Down