test_js / index.html
broadfield-dev's picture
Update index.html
9ce5d85 verified
raw
history blame
6.25 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rubik's Cube</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
#controls { position: absolute; bottom: 10px; left: 10px; z-index: 10; }
</style>
</head>
<body>
<div id="controls">
<button onclick="rotate('U')">U</button>
<button onclick="rotate('U\'')">U'</button>
<button onclick="rotate('D')">D</button>
<button onclick="rotate('D\'')">D'</button>
<button onclick="rotate('L')">L</button>
<button onclick="rotate('L\'')">L'</button>
<button onclick="rotate('R')">R</button>
<button onclick="rotate('R\'')">R'</button>
<button onclick="rotate('F')">F</button>
<button onclick="rotate('F\'')">F'</button>
<button onclick="rotate('B')">B</button>
<button onclick="rotate('B\'')">B'</button>
<button onclick="scramble()">Scramble</button>
<button onclick="unscramble()">Unscramble</button>
</div>
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/[email protected]';
import { OrbitControls } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
camera.position.z = 5;
const cubeSize = 0.9;
const colors = {
'U': 0xFFFFFF, 'D': 0xFFFF00, 'L': 0xFFA500,
'R': 0x00FF00, 'F': 0x0000FF, 'B': 0xFF00FF
};
// Create cubies
const cubies = [];
for (let x = -1; x <= 1; x++) {
for (let y = -1; y <= 1; y++) {
for (let z = -1; z <= 1; z++) {
const geometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
const materials = [
new THREE.MeshStandardMaterial({color: x === -1 ? colors['L'] : 0x000000}), // Left
new THREE.MeshStandardMaterial({color: x === 1 ? colors['R'] : 0x000000}), // Right
new THREE.MeshStandardMaterial({color: z === 1 ? colors['F'] : 0x000000}), // Front
new THREE.MeshStandardMaterial({color: z === -1 ? colors['B'] : 0x000000}), // Back
new THREE.MeshStandardMaterial({color: y === 1 ? colors['U'] : 0x000000}), // Up
new THREE.MeshStandardMaterial({color: y === -1 ? colors['D'] : 0x000000}) // Down
];
const cubie = new THREE.Mesh(geometry, materials);
cubie.position.set(x * (cubeSize + 0.01), y * (cubeSize + 0.01), z * (cubeSize + 0.01));
cubies.push({ mesh: cubie, originalPosition: cubie.position.clone(), originalRotation: cubie.rotation.clone() });
scene.add(cubie);
}
}
}
// Light setup
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);
// Cube rotation logic
const moveMap = {
'U': { axis: 'y', layer: 1, direction: 1, affectedCubies: cubies.filter(c => c.mesh.position.y === cubeSize) },
'U\'': { axis: 'y', layer: 1, direction: -1, affectedCubies: cubies.filter(c => c.mesh.position.y === cubeSize) },
// ... other moves similarly defined
};
let movesHistory = [];
function rotate(move) {
const { axis, layer, direction, affectedCubies } = moveMap[move];
const pivot = new THREE.Object3D();
scene.add(pivot);
for (let cubie of affectedCubies) {
pivot.attach(cubie.mesh);
}
const targetRotation = Math.PI / 2 * direction;
let currentRotation = 0;
function animate() {
if (currentRotation < Math.abs(targetRotation)) {
currentRotation += 0.1 * Math.sign(targetRotation);
pivot.rotation[axis] = currentRotation;
requestAnimationFrame(animate);
} else {
pivot.rotation[axis] = targetRotation;
for (let cubie of affectedCubies) {
cubie.mesh.applyMatrix4(pivot.matrix);
scene.attach(cubie.mesh);
}
scene.remove(pivot);
movesHistory.push(move);
}
}
animate();
}
function scramble() {
const moves = ['U', 'U\'', 'D', 'D\'', 'L', 'L\'', 'R', 'R\'', 'F', 'F\'', 'B', 'B\''];
for (let i = 0; i < 20; i++) {
rotate(moves[Math.floor(Math.random() * moves.length)]);
}
}
let unscrambling = false;
function unscramble() {
if (!unscrambling && movesHistory.length > 0) {
unscrambling = true;
const interval = setInterval(() => {
if (movesHistory.length > 0) {
let lastMove = movesHistory.pop();
let inverse = lastMove.replace("'", "") + (lastMove.includes('\'') ? '' : '\'');
rotate(inverse);
} else {
clearInterval(interval);
unscrambling = false;
}
}, 500);
}
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>