Created
May 2, 2024 20:06
-
-
Save EncodeTheCode/2c99e17a18a73f23bb116c9ebca6732e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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