Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created May 14, 2025 02:49
Show Gist options
  • Save EncodeTheCode/4c75767db0d0a2e90bc8816ca265f054 to your computer and use it in GitHub Desktop.
Save EncodeTheCode/4c75767db0d0a2e90bc8816ca265f054 to your computer and use it in GitHub Desktop.
<canvas id="canvas" width="600" height="600"></canvas>
<script>
// ----- 1. 3D Vector System -----
class Vector3 {
constructor(x = 0, y = 0, z = 0) {
this.x = x; this.y = y; this.z = z;
}
add(v) {
return new Vector3(this.x + v.x, this.y + v.y, this.z + v.z);
}
subtract(v) {
return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z);
}
rotateY(angle) {
const cos = Math.cos(angle), sin = Math.sin(angle);
return new Vector3(this.x * cos - this.z * sin, this.y, this.x * sin + this.z * cos);
}
project(width, height, scale = 100, distance = 3) {
const dz = this.z + distance;
const factor = scale / dz;
return {
x: this.x * factor + width / 2,
y: -this.y * factor + height / 2
};
}
}
// ----- 2. Mesh Box -----
function createBox(size = 1) {
const s = size / 2;
const vertices = [
new Vector3(-s, -s, -s), new Vector3(s, -s, -s),
new Vector3(s, s, -s), new Vector3(-s, s, -s),
new Vector3(-s, -s, s), new Vector3(s, -s, s),
new Vector3(s, s, s), new Vector3(-s, s, s),
];
const faces = [
[0,1,2,3], [4,5,6,7], // front/back
[0,1,5,4], [2,3,7,6], // top/bottom
[0,3,7,4], [1,2,6,5], // sides
];
return { vertices, faces };
}
// ----- 3. Renderer -----
class Renderer {
constructor(canvas, mesh) {
this.ctx = canvas.getContext('2d');
this.canvas = canvas;
this.mesh = mesh;
this.angle = 0;
this.lastRotated = 0;
requestAnimationFrame(() => this.draw());
}
draw() {
const now = Date.now();
if (now - this.lastRotated > 60) {
this.angle += Math.PI / 100;
this.lastRotated = now;
}
const { ctx, canvas, mesh } = this;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const rotated = mesh.vertices.map(v => v.rotateY(this.angle));
const projected = rotated.map(v => v.project(canvas.width, canvas.height));
ctx.strokeStyle = '#0ff';
ctx.lineWidth = 2;
for (const face of mesh.faces) {
ctx.beginPath();
const [a, b, c, d] = face;
ctx.moveTo(projected[a].x, projected[a].y);
ctx.lineTo(projected[b].x, projected[b].y);
ctx.lineTo(projected[c].x, projected[c].y);
ctx.lineTo(projected[d].x, projected[d].y);
ctx.closePath();
ctx.stroke();
}
requestAnimationFrame(() => this.draw());
}
}
// ----- 4. Init -----
const canvas = document.getElementById('canvas');
const box = createBox(2);
new Renderer(canvas, box);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment