Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save shricodev/79eec9915bde0b3847e066b1fad22ceb to your computer and use it in GitHub Desktop.

Select an option

Save shricodev/79eec9915bde0b3847e066b1fad22ceb to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
// Initialize canvas
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Configuration
const RADIUS = 1;
const LETTERS = [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
];
const NUM_POINTS = 400;
const SCALE = 150;
const CENTER_X = canvas.width / 2;
const CENTER_Y = canvas.height / 2;
// Generate points on sphere
const points = Array.from({ length: NUM_POINTS }, (_, i) => {
const theta = Math.acos(2 * Math.random() - 1); // Uniform distribution
const phi = Math.random() * Math.PI * 2;
return {
x: RADIUS * Math.sin(theta) * Math.cos(phi),
y: RADIUS * Math.sin(theta) * Math.sin(phi),
z: RADIUS * Math.cos(theta),
letter: LETTERS[i % LETTERS.length],
};
});
// Rotation state
let angleX = 0;
let angleY = 0;
// Animation loop
function animate() {
// Clear canvas
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Prepare drawing context
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "14px Arial";
// Calculate rotated points
const rotatedPoints = points.map((p) => {
// X-axis rotation
let y = p.y * Math.cos(angleX) - p.z * Math.sin(angleX);
let z = p.y * Math.sin(angleX) + p.z * Math.cos(angleX);
let x = p.x;
// Y-axis rotation
const x2 = x * Math.cos(angleY) + z * Math.sin(angleY);
const z2 = -x * Math.sin(angleY) + z * Math.cos(angleY);
return {
x: x2,
y: y,
z: z2,
letter: p.letter,
};
});
// Sort points by depth (farthest first)
rotatedPoints.sort((a, b) => a.z - b.z);
// Draw points
rotatedPoints.forEach((p) => {
// Calculate color (white to gray based on depth)
const gray = 128 + (p.z + 1) * 63.5;
ctx.fillStyle = `rgb(${gray},${gray},${gray})`;
// Project to 2D
const x = p.x * SCALE + CENTER_X;
const y = p.y * SCALE + CENTER_Y;
ctx.fillText(p.letter, x, y);
});
// Update angles
angleX += 0.02;
angleY += 0.03;
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment