Explore this code to learn how to display a 3D cube of cubes and rotate it around 4 axis using controls.
Scroll all the way to the bottom of this page to work with this demo in full screen. This demo works best on a large pc screen.
This uses the three.js animation library to render the graphic in the canvas.
Instructions to replicate this on your own server.
Create a folder or subdomain to hold this code. I recommend making a sub domain or using one of your own domain names to dedicate the root folder to this code.
Create an index.html file and put this code in it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Array Visualization</title>
<style>
body { margin: 0; }
canvas { display: block; }
#controls {
position: fixed;
bottom: 10px;
left: 10px;
z-index: 100;
}
.control-icon, .control-label {
cursor: pointer;
padding: 5px;
margin: 5px;
display: inline-block;
}
.control-icon {
background-color: #ddd;
border-radius: 50%;
}
.control-icon:hover {
background-color: #ccc;
}
.control-label {
vertical-align: middle;
color : #555;
}
#gap-slider {
width: 150px;
vertical-align: middle;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="script.js"></script> <!-- Link to your JavaScript file -->
<div id="controls">
<div class="control-label">Adjust Gap</div>
<input type="range" id="gap-slider" min="0" max="1" step="0.01" value="0.2">
<div class="control-label">Rotate Left</div>
<div class="control-icon" id="rotate-left">โฒ</div>
<div class="control-label">Rotate Right</div>
<div class="control-icon" id="rotate-right">โณ</div>
<div class="control-label">Rotate Up</div>
<div class="control-icon" id="rotate-up">🔼</div>
<div class="control-label">Rotate Down</div>
<div class="control-icon" id="rotate-down">🔽</div>
<div class="control-label">Stop Animation</div>
<div class="control-icon" id="stop-animation">⏹️</div>
</div>
</body>
</html>
Create a file called script.js and put this code in it.
// Function to generate a random color
function generateRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
// Function to create an 8x8x8 array with random colors
function createColorArray() {
let array = [];
for (let i = 0; i < 8; i++) {
array[i] = [];
for (let j = 0; j < 8; j++) {
array[i][j] = [];
for (let k = 0; k < 8; k++) {
array[i][j][k] = generateRandomColor();
}
}
}
return array;
}
// Global variables
let rotateDirection = null;
let animationActive = true;
let rotationSpeed = 0.05;
let gap = 0.2; // Initial gap size
let cubes = []; // Store cube meshes for easy access
// Rotation function
function rotateArray(scene) {
if (rotateDirection) {
switch (rotateDirection) {
case 'left':
scene.rotation.y -= rotationSpeed;
break;
case 'right':
scene.rotation.y += rotationSpeed;
break;
case 'up':
scene.rotation.x -= rotationSpeed;
break;
case 'down':
scene.rotation.x += rotationSpeed;
break;
// Add cases for other directions if needed
}
}
}
// Function to initialize controls
function initControls(scene, renderer) {
const rotateLeft = document.getElementById('rotate-left');
const rotateRight = document.getElementById('rotate-right');
const rotateUp = document.getElementById('rotate-up');
const rotateDown = document.getElementById('rotate-down');
const stopAnimation = document.getElementById('stop-animation');
stopAnimation.addEventListener('click', () => {
animationActive = false;
});
// Bind hover events
rotateLeft.addEventListener('mouseenter', () => rotateDirection = 'left');
rotateRight.addEventListener('mouseenter', () => rotateDirection = 'right');
rotateUp.addEventListener('mouseenter', () => rotateDirection = 'up');
rotateDown.addEventListener('mouseenter', () => rotateDirection = 'down');
// Stop rotation on mouse leave
const stopRotation = () => rotateDirection = null;
rotateLeft.addEventListener('mouseleave', stopRotation);
rotateRight.addEventListener('mouseleave', stopRotation);
rotateUp.addEventListener('mouseleave', stopRotation);
rotateDown.addEventListener('mouseleave', stopRotation);
// Gap Slider Event Listener
document.getElementById('gap-slider').addEventListener('input', (event) => {
gap = parseFloat(event.target.value);
updateCubesPosition(scene);
});
}
// Function to update cubes position based on gap
function updateCubesPosition(scene) {
let cubeSize = 1;
cubes.forEach((cube, index) => {
let x = index % 8;
let y = Math.floor(index / 8) % 8;
let z = Math.floor(index / 64);
cube.position.set(x * (cubeSize + gap), y * (cubeSize + gap), z * (cubeSize + gap));
});
}
// Function to initialize the 3D scene using Three.js
function init3DScene(colorArray) {
// Set up the scene, camera, and renderer
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement); // Create cubes and add to the scene
let geometry = new THREE.BoxGeometry(1, 1, 1); // Cube size
colorArray.forEach((row, x) => {
row.forEach((column, y) => {
column.forEach((color, z) => {
let material = new THREE.MeshBasicMaterial({ color: color });
let cube = new THREE.Mesh(geometry, material);
cube.position.set(x * (1 + gap), y * (1 + gap), z * (1 + gap));
scene.add(cube);
cubes.push(cube); // Store for later access
});
});
});
// Camera positioning
camera.position.z = 20;
// Animation loop
function animate() {
if (animationActive) {
requestAnimationFrame(animate);
if (rotateDirection) {
rotateArray(scene);
}
renderer.render(scene, camera);
}
}
animate();
initControls(scene, renderer);
}
// Main execution
document.addEventListener('DOMContentLoaded', () => {
let colorArray = createColorArray();
init3DScene(colorArray);
});
Once you have your code uploaded then just access the location from your browser to see the 3d block displayed and then you can control the block using the controls at the bottom. Just hover over the control to spin the block.
You can also use vscode with a live html server plugin installed to run this code locally to play with it before you upload it to your public server to show it off.
I was developing this to explore creating a mini Minecraft world and this is the beginning of my exploration of generating all the blocks of the world.
Subscribe to this blog to get the updates as I add new code to this idea.
Don’t settle for less when it comes to your hosting and domain name registration needs! Take your online presence to the next level with top-notch services from https://mtbn.net. Visit us today and experience nothing but the best!
Leave a Reply
You must be logged in to post a comment.