<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Designer Lissajous Glow</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: radial-gradient(circle at center, #000010, #000000);
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;
window.addEventListener("resize", () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
});
function hslColor(hue) {
return `hsl(${hue}, 100%, 60%)`;
}
function drawLissajous(time) {
ctx.clearRect(0, 0, width, height);
const centerX = width / 2;
const centerY = height / 2;
const scale = 200;
const a = 7; // frequency X
const b = 5; // frequency Y
const delta = time * 0.002;
for (let i = 0; i < 3; i++) {
ctx.beginPath();
const hue = (time / 20 + i * 60) % 360;
ctx.strokeStyle = hslColor(hue);
ctx.lineWidth = 2;
ctx.shadowColor = hslColor(hue);
ctx.shadowBlur = 25;
for (let t = 0; t <= Math.PI * 2; t += 0.01) {
const x = centerX + scale * Math.sin(a * t + delta + i);
const y = centerY + scale * Math.sin(b * t + i * 0.2);
if (t === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
requestAnimationFrame(drawLissajous);
}
drawLissajous(0);
</script>
</body>
</html>