Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created May 2, 2024 20:06
Show Gist options
  • Save EncodeTheCode/2c99e17a18a73f23bb116c9ebca6732e to your computer and use it in GitHub Desktop.
Save EncodeTheCode/2c99e17a18a73f23bb116c9ebca6732e to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>3D Cube with Dynamic Texture</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #222;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
window.onload = function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Load image
var image = new Image();
image.src = 'https://superspacealiens2.000webhostapp.com/uploads/66179c0c997fa_mario_small.png';
image.onload = function() {
// Define vertices of the cube
var vertices = [
{ x: 100, y: 100, z: 0, u: 0, v: 0 }, // Front top left
{ x: 300, y: 100, z: 0, u: 1, v: 0 }, // Front top right
{ x: 300, y: 300, z: 0, u: 1, v: 1 }, // Front bottom right
{ x: 100, y: 300, z: 0, u: 0, v: 1 }, // Front bottom left
{ x: 100, y: 100, z: -200, u: 0, v: 0 }, // Back top left
{ x: 300, y: 100, z: -200, u: 1, v: 0 }, // Back top right
{ x: 300, y: 300, z: -200, u: 1, v: 1 }, // Back bottom right
{ x: 100, y: 300, z: -200, u: 0, v: 1 } // Back bottom left
];
// Define faces of the cube
var faces = [
[1, 1, 1, 1], // Front face
[1, 3, 6, 1], // Back face
[1, 0, 0, 1], // Top face
[1, 0, 0, 1], // Bottom face
[1, 0, 0, 1], // Right face
[1, 1, 1, 1] // Left face
];
// Define camera parameters
var camera = {
x: canvas.width - 500 / 2,
y: canvas.height + 500 / 2,
z: -500
};
// Render the cube
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
faces.forEach(function(face) {
// Check if the face is visible
var normal = getNormal(face);
var dotProduct = normal.x * (vertices[face[0]].x - camera.x) + normal.y * (vertices[face[0]].y - camera.y) + normal.z * (vertices[face[0]].z - camera.z);
if (dotProduct < 0) {
// Draw the face
ctx.beginPath();
ctx.moveTo(vertices[face[0]].x, vertices[face[0]].y);
face.slice(1).forEach(function(vertexIndex) {
ctx.lineTo(vertices[vertexIndex].x, vertices[vertexIndex].y);
});
ctx.closePath();
ctx.stroke();
// Draw texture
ctx.save();
ctx.clip();
var width = Math.abs(vertices[face[1]].x - vertices[face[0]].x);
var height = Math.abs(vertices[face[2]].y - vertices[face[1]].y);
var xOffset = vertices[face[0]].x;
var yOffset = vertices[face[0]].y;
var angle = Math.atan2(vertices[face[1]].y - vertices[face[0]].y, vertices[face[1]].x - vertices[face[0]].x);
ctx.translate(xOffset, yOffset);
ctx.rotate(angle);
var textureX = vertices[face[0]].u * image.width;
var textureY = vertices[face[0]].v * image.height;
ctx.drawImage(image, textureX, textureY, image.width * width / canvas.width, image.height * height / canvas.height, 0, 0, width, height);
ctx.restore();
}
});
}
// Calculate the normal vector of a face
function getNormal(face) {
var v0 = vertices[face[0]];
var v1 = vertices[face[1]];
var v2 = vertices[face[2]];
var vector1 = { x: v1.x - v0.x, y: v1.y - v0.y, z: v1.z - v0.z };
var vector2 = { x: v2.x - v1.x, y: v2.y - v1.y, z: v2.z - v1.z };
return {
x: vector1.y * vector2.z - vector1.z * vector2.y,
y: vector1.z * vector2.x - vector1.x * vector2.z,
z: vector1.x * vector2.y - vector1.y * vector2.x
};
}
var angleX = 0.005;
var angleY = 0.005;
var angleZ = 0.005;
// Rotate the cube vertices
function rotateVertices(angleX, angleY, angleZ) {
vertices.forEach(function(vertex) {
var x = vertex.x;
var y = vertex.y;
var z = vertex.z;
// Rotation around X-axis
var tempY = y * Math.cos(angleX) - z * Math.sin(angleX);
var tempZ = y * Math.sin(angleX) + z * Math.cos(angleX);
y = tempY;
z = tempZ;
// Rotation around Y-axis
var tempX = x * Math.cos(angleY) + z * Math.sin(angleY);
tempZ = -x * Math.sin(angleY) + z * Math.cos(angleY);
x = tempX;
z = tempZ;
// Rotation around Z-axis
tempX = x * Math.cos(angleZ) - y * Math.sin(angleZ);
tempY = x * Math.sin(angleZ) + y * Math.cos(angleZ);
x = tempX;
y = tempY;
vertex.x = x;
vertex.y = y;
vertex.z = z;
});
}
// Animation loop
function animate() {
rotateVertices(angleX, angleY, angleZ);
render();
requestAnimationFrame(animate);
}
animate();
};
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment